Skip to content

Commit 61671d5

Browse files
committed
<fix>[kvm]:Check KVM agent port availability
This commit adds a check for the availability of KVM agent port after configuring iptables. The iptables rules are updated to allow incoming traffic on the KVM agent port, and then a simple port check is performed to ensure that the port is open and accessible. This check is important to ensure that the KVM virtualization environment is properly configured and ready for use. If the kvmagent port is blocked and the echo fails, the kvmagent will be restarted and the command will be reissued. However, due to the kvmagent port being blocked, the command will fail to be issued. The HA fencer is unable to update the heartbeat, and during the HA checker check, the heartbeat will not be refreshed, potentially resulting in split-brain VMs. Resolves: ZSTAC-56336 Change-Id: I6c6578706c6d716f7774776b65776a6f666a6263
1 parent 6d48624 commit 61671d5

File tree

4 files changed

+65
-1
lines changed

4 files changed

+65
-1
lines changed

conf/globalConfig/kvm.xml

+8
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@
154154
<defaultValue>2</defaultValue>
155155
</config>
156156

157+
<config>
158+
<category>kvm</category>
159+
<name>testKvmagentPortOnConnectTimeout</name>
160+
<description>use with testKvmagentPortOnConnectTimeout, the connect timeout launching a socket connection to hosts' kvmagent port, in seconds</description>
161+
<type>java.lang.Integer</type>
162+
<defaultValue>2</defaultValue>
163+
</config>
164+
157165
<config>
158166
<category>kvm</category>
159167
<name>restartagentwhenfakedead</name>

plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalConfig.java

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ public class KVMGlobalConfig {
6666
public static GlobalConfig TEST_SSH_PORT_ON_OPEN_TIMEOUT = new GlobalConfig(CATEGORY, "testSshPortOpenTimeout");
6767
@GlobalConfigValidation(numberGreaterThan = 0, numberLessThan = 300)
6868
public static GlobalConfig TEST_SSH_PORT_ON_CONNECT_TIMEOUT = new GlobalConfig(CATEGORY, "testSshPortOnConnectTimeout");
69+
@GlobalConfigValidation(numberGreaterThan = 0, numberLessThan = 300)
70+
public static GlobalConfig TEST_KVMAGENT_PORT_ON_CONNECT_TIMEOUT = new GlobalConfig(CATEGORY, "testKvmagentPortOnConnectTimeout");
6971
@GlobalConfigValidation
7072
public static GlobalConfig RESTART_AGENT_IF_FAKE_DEAD = new GlobalConfig(CATEGORY, "restartagentwhenfakedead");
7173

plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java

+47-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
import java.io.File;
9292
import java.io.IOException;
9393
import java.io.UnsupportedEncodingException;
94-
import java.net.URLEncoder;
94+
import java.net.*;
9595
import java.nio.charset.StandardCharsets;
9696
import java.util.*;
9797
import java.util.concurrent.TimeUnit;
@@ -4240,6 +4240,32 @@ private void recreateTag(SystemTag tag, String token, String value, boolean inhe
42404240
creator.create();
42414241
}
42424242

4243+
public ErrorCode isRemotePortOpen(String ip, int port, int timeout) {
4244+
Socket socket = new Socket();
4245+
4246+
try {
4247+
socket.setReuseAddress(true);
4248+
SocketAddress sa = new InetSocketAddress(ip, port);
4249+
socket.connect(sa, timeout);
4250+
if (socket.isConnected()) {
4251+
return null;
4252+
}
4253+
return operr("connect remote port[ip:%s, port:%s] is failed", ip, port);
4254+
} catch (SocketException e) {
4255+
logger.debug(String.format("unable to connect remote port[ip:%s, port:%s], %s", ip, port, e.getMessage()));
4256+
return operr("unable to connect remote port[ip:%s, port:%s], %s", ip, port, e.getMessage());
4257+
} catch (IOException e) {
4258+
logger.debug(String.format("unable to connect remote port[ip:%s, port:%s], %s", ip, port, e.getMessage()));
4259+
return operr("unable to connect remote port[ip:%s, port:%s], %s", ip, port, e.getMessage());
4260+
} finally {
4261+
try {
4262+
socket.close();
4263+
} catch (IOException e) {
4264+
logger.warn(e.getMessage(), e);
4265+
}
4266+
}
4267+
}
4268+
42434269
@Override
42444270
public void connectHook(final ConnectHostInfo info, final Completion complete) {
42454271
if (!info.isNewAdded()) {
@@ -4677,6 +4703,26 @@ public void run(FlowTrigger trigger, Map data) {
46774703
}
46784704
});
46794705

4706+
flow(new NoRollbackFlow() {
4707+
String __name__ = "test-kvmagent-port-open";
4708+
4709+
@Override
4710+
public boolean skip(Map data) {
4711+
return CoreGlobalProperty.UNIT_TEST_ON;
4712+
}
4713+
4714+
@Override
4715+
public void run(FlowTrigger trigger, Map data) {
4716+
long ctimeout = TimeUnit.SECONDS.toMillis(KVMGlobalConfig.TEST_KVMAGENT_PORT_ON_CONNECT_TIMEOUT.value(Integer.class).longValue());
4717+
ErrorCode errorCode = isRemotePortOpen(getSelf().getManagementIp(), KVMGlobalProperty.AGENT_PORT, (int) ctimeout);
4718+
if (errorCode != null) {
4719+
trigger.fail(errorCode);
4720+
return;
4721+
}
4722+
trigger.next();
4723+
}
4724+
});
4725+
46804726
flow(new NoRollbackFlow() {
46814727
String __name__ = "echo-host";
46824728

test/src/test/resources/globalConfig/kvm.xml

+8
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@
154154
<defaultValue>2</defaultValue>
155155
</config>
156156

157+
<config>
158+
<category>kvm</category>
159+
<name>testKvmagentPortOnConnectTimeout</name>
160+
<description>use with testKvmagentPortOnConnectTimeout, the connect timeout launching a socket connection to hosts' kvmagent port, in seconds</description>
161+
<type>java.lang.Integer</type>
162+
<defaultValue>2</defaultValue>
163+
</config>
164+
157165
<config>
158166
<category>kvm</category>
159167
<name>restartagentwhenfakedead</name>

0 commit comments

Comments
 (0)