Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,8 @@ public static class HostFactResponse extends AgentResponse {
private String osRelease;
@GrayVersion(value = "5.0.0")
private String qemuImgVersion;
@GrayVersion(value = "5.5.28")
private String qemuKvmPackageVersion;
@GrayVersion(value = "5.0.0")
private String libvirtVersion;
@GrayVersion(value = "5.0.0")
Expand Down Expand Up @@ -580,6 +582,14 @@ public void setQemuImgVersion(String qemuImgVersion) {
this.qemuImgVersion = qemuImgVersion;
}

public String getQemuKvmPackageVersion() {
return qemuKvmPackageVersion;
}

public void setQemuKvmPackageVersion(String qemuKvmPackageVersion) {
this.qemuKvmPackageVersion = qemuKvmPackageVersion;
}

public List<String> getIpAddresses() {
return ipAddresses;
}
Expand Down
10 changes: 10 additions & 0 deletions plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -6336,6 +6336,8 @@ private void saveKvmHostRelatedFacts(HostFactResponse ret) {
createTagWithoutNonValue(KVMSystemTags.EPT_CPU_FLAG, KVMSystemTags.EPT_CPU_FLAG_TOKEN, ret.getEptFlag(), false);
createTagWithoutNonValue(KVMSystemTags.CPU_MODEL_NAME, KVMSystemTags.CPU_MODEL_NAME_TOKEN, ret.getCpuModelName(), false);

refreshIothreadVqMappingCapability(ret);

if (ret.getLibvirtVersion().compareTo(KVMConstant.MIN_LIBVIRT_VIRTIO_SCSI_VERSION) >= 0) {
recreateNonInherentTag(KVMSystemTags.VIRTIO_SCSI);
}
Expand All @@ -6348,6 +6350,14 @@ private void saveKvmHostRelatedFacts(HostFactResponse ret) {
deleteCpuHistoryVOIfCpuModeNameChange(ret.getCpuModelName());
deleteCpuHistoryVOIfCpuFeatureMd5Change(ret.getCpuFeatureMd5());
}

private void refreshIothreadVqMappingCapability(HostFactResponse ret) {
if (KvmHostIothreadVqMappingCapability.supported(ret.getQemuKvmPackageVersion(), ret.getLibvirtPackageVersion())) {
recreateNonInherentTag(KVMSystemTags.IOTHREAD_VQ_MAPPING);
} else {
KVMSystemTags.IOTHREAD_VQ_MAPPING.delete(self.getUuid());
}
}
};
}

Expand Down
2 changes: 2 additions & 0 deletions plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public class KVMSystemTags {

public static SystemTag VIRTIO_SCSI = new SystemTag("capability:virtio-scsi", HostVO.class);

public static SystemTag IOTHREAD_VQ_MAPPING = new SystemTag("capability::iothread-vq-mapping", HostVO.class);

public static final String L2_BRIDGE_NAME_TOKEN = "name";
public static PatternedSystemTag L2_BRIDGE_NAME = new PatternedSystemTag(String.format("kvm::bridge::{%s}", L2_BRIDGE_NAME_TOKEN), L2NetworkVO.class);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.zstack.kvm;

import org.apache.commons.lang.StringUtils;
import org.apache.maven.artifact.versioning.ComparableVersion;

import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class KvmHostIothreadVqMappingCapability {
static final String MIN_QEMU_KVM_PACKAGE_VERSION = "6.2.0-451";
static final String MIN_LIBVIRT_PACKAGE_VERSION = "8.0.0-163";
private static final Pattern NUMERIC_VERSION_TOKEN = Pattern.compile("\\d+(?:\\.\\d+)*");

public static boolean supported(String qemuKvmPackageVersion, String libvirtPackageVersion) {
return versionAtLeast(qemuKvmPackageVersion, MIN_QEMU_KVM_PACKAGE_VERSION)
&& versionAtLeast(libvirtPackageVersion, MIN_LIBVIRT_PACKAGE_VERSION);
}

private static boolean versionAtLeast(String current, String required) {
String normalized = normalizeVersion(current);
if (normalized == null) {
return false;
}

return new ComparableVersion(normalized).compareTo(new ComparableVersion(required)) >= 0;
}

private static String normalizeVersion(String version) {
if (StringUtils.isBlank(version)) {
return null;
}

String normalized = Arrays.stream(version.trim().split("\\s+")[0].split("-"))
.map(KvmHostIothreadVqMappingCapability::numericPrefix)
.filter(StringUtils::isNotBlank)
.collect(Collectors.joining("-"));
return StringUtils.isBlank(normalized) ? null : normalized;
}

private static String numericPrefix(String versionSegment) {
Matcher matcher = NUMERIC_VERSION_TOKEN.matcher(versionSegment);
return matcher.lookingAt() ? matcher.group() : null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.zstack.kvm;

import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class KvmHostIothreadVqMappingCapabilityTest {
@Test
public void supportsBaselineVersions() {
assertTrue(KvmHostIothreadVqMappingCapability.supported("6.2.0-451.g623f2a5caf.el8", "8.0.0-163.gd30ff15b84"));
assertTrue(KvmHostIothreadVqMappingCapability.supported("6.2.0-546.g7638079ce5.el8", "8.0.0-164.gd30ff15b84"));
assertTrue(KvmHostIothreadVqMappingCapability.supported("6.2.0-451.module+el8.10.0+12345", "8.0.0-163.fc39"));
}

@Test
public void rejectsUnsupportedQemuKvmPackageVersion() {
assertFalse(KvmHostIothreadVqMappingCapability.supported("6.2.0-450.g623f2a5caf.el8", "8.0.0-163.gd30ff15b84"));
}

@Test
public void rejectsUnsupportedLibvirtPackageVersion() {
assertFalse(KvmHostIothreadVqMappingCapability.supported("6.2.0-451.g623f2a5caf.el8", "8.0.0-162.gd30ff15b84"));
}

@Test
public void rejectsMissingQemuKvmPackageVersion() {
assertFalse(KvmHostIothreadVqMappingCapability.supported(null, "8.0.0-163.gd30ff15b84"));
assertFalse(KvmHostIothreadVqMappingCapability.supported("", "8.0.0-163.gd30ff15b84"));
}

@Test
public void rejectsMissingLibvirtPackageVersion() {
assertFalse(KvmHostIothreadVqMappingCapability.supported("6.2.0-451.g623f2a5caf.el8", null));
assertFalse(KvmHostIothreadVqMappingCapability.supported("6.2.0-451.g623f2a5caf.el8", ""));
}
}