From cff7e711303c563ab943306a38fc6c59f00ef5e7 Mon Sep 17 00:00:00 2001 From: Haidong Pang Date: Sun, 24 May 2026 16:57:47 +0800 Subject: [PATCH] [kvm]: add iothread vq mapping data path Resolves: ZSTAC-82672 Change-Id: Ib43a7a02a0528cc40cd8aa370b93b7fba7dfc051 --- .../zstack/storage/ceph/CephGlobalConfig.java | 4 ++ .../java/org/zstack/kvm/KVMAgentCommands.java | 10 +++++ .../main/java/org/zstack/kvm/KVMConstant.java | 2 + .../src/main/java/org/zstack/kvm/KVMHost.java | 10 ++++- .../java/org/zstack/kvm/KVMSystemTags.java | 3 ++ .../main/java/org/zstack/kvm/VolumeTO.java | 11 ++++++ .../main/java/org/zstack/sdk/VolumeTO.java | 8 ++++ .../integration/kvm/host/AddHostCase.groovy | 39 +++++++++++++++++++ 8 files changed, 86 insertions(+), 1 deletion(-) diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalConfig.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalConfig.java index c3a42f79013..1ec774cfdc4 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalConfig.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalConfig.java @@ -34,6 +34,10 @@ public class CephGlobalConfig { public static GlobalConfig CEPH_BS_ALLOW_PORTS = new GlobalConfig(CATEGORY, "cephbs.allow.ports"); @GlobalConfigValidation public static GlobalConfig CEPH_PS_ALLOW_PORTS = new GlobalConfig(CATEGORY, "cephps.allow.ports"); + @GlobalConfigDef(type = Integer.class, defaultValue = "1", description = "max automatic IOThread count for ZStone primary storage volumes") + @GlobalConfigValidation(inNumberRange = {1, 8}) + public static GlobalConfig ZSTONE_IOTHREAD_MAX = + new GlobalConfig(CATEGORY, "zstone.iothread.max"); @GlobalConfigDef(type = Boolean.class, defaultValue = "true") @GlobalConfigValidation diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java index ff737c20e83..c07cfec1041 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java @@ -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") @@ -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 getIpAddresses() { return ipAddresses; } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java index 5f08e6fdb98..f86208f8f86 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java @@ -110,6 +110,8 @@ public interface KVMConstant { String MIN_QEMU_LIVESNAPSHOT_VERSION = "1.3.0"; String MIN_LIBVIRT_LIVE_BLOCK_COMMIT_VERSION = "1.2.7"; String MIN_LIBVIRT_VIRTIO_SCSI_VERSION = "1.0.4"; + String MIN_QEMU_KVM_IOTHREAD_VQ_MAPPING_PACKAGE_VERSION = "6.2.0-451"; + String MIN_LIBVIRT_IOTHREAD_VQ_MAPPING_PACKAGE_VERSION = "8.0.0-163"; String KVM_REPORT_VM_STATE = "/kvm/reportvmstate"; String KVM_RECONNECT_ME = "/kvm/reconnectme"; diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java index 48370a2a144..477b55d3743 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java @@ -6326,8 +6326,16 @@ private boolean checkVirtualizationEnabled(HostFactResponse response) { private void saveKvmHostRelatedFacts(HostFactResponse ret) { updateHostOsInformation(ret.getOsDistribution(), ret.getOsRelease(), ret.getOsVersion()); - if (ret.getLibvirtPackageVersion() != null) { + if (StringUtils.isNotBlank(ret.getLibvirtPackageVersion())) { createTagWithoutNonValue(KVMSystemTags.LIBVIRT_PACKAGE_VERSION, KVMSystemTags.LIBVIRT_PACKAGE_VERSION_TOKEN, ret.getLibvirtPackageVersion().trim(), false); + } else { + KVMSystemTags.LIBVIRT_PACKAGE_VERSION.delete(self.getUuid()); + } + + if (StringUtils.isNotBlank(ret.getQemuKvmPackageVersion())) { + createTagWithoutNonValue(KVMSystemTags.QEMU_KVM_PACKAGE_VERSION, KVMSystemTags.QEMU_KVM_PACKAGE_VERSION_TOKEN, ret.getQemuKvmPackageVersion().trim(), false); + } else { + KVMSystemTags.QEMU_KVM_PACKAGE_VERSION.delete(self.getUuid()); } createTagWithoutNonValue(KVMSystemTags.QEMU_IMG_VERSION, KVMSystemTags.QEMU_IMG_VERSION_TOKEN, ret.getQemuImgVersion(), false); diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java index e5c14fb9d57..7cd2fbdb2be 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java @@ -18,6 +18,9 @@ public class KVMSystemTags { public static final String QEMU_IMG_VERSION_TOKEN = "version"; public static PatternedSystemTag QEMU_IMG_VERSION = new PatternedSystemTag(String.format("qemu-img::version::{%s}", QEMU_IMG_VERSION_TOKEN), HostVO.class); + public static final String QEMU_KVM_PACKAGE_VERSION_TOKEN = "version"; + public static PatternedSystemTag QEMU_KVM_PACKAGE_VERSION = new PatternedSystemTag(String.format("qemu-kvm::package::version::{%s}", QEMU_KVM_PACKAGE_VERSION_TOKEN), HostVO.class); + public static final String LIBVIRT_VERSION_TOKEN = "version"; public static PatternedSystemTag LIBVIRT_VERSION = new PatternedSystemTag(String.format("libvirt::version::{%s}", LIBVIRT_VERSION_TOKEN), HostVO.class); diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/VolumeTO.java b/plugin/kvm/src/main/java/org/zstack/kvm/VolumeTO.java index 2ea9238f167..0c5a490ee56 100644 --- a/plugin/kvm/src/main/java/org/zstack/kvm/VolumeTO.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/VolumeTO.java @@ -51,6 +51,8 @@ public class VolumeTO extends BaseVirtualDeviceTO { private String multiQueues; private int ioThreadId; private String ioThreadPin; + // 0 means automatic IOThread VQ Mapping is disabled. + private int ioThreads; private int controllerIndex; static { @@ -80,6 +82,7 @@ public VolumeTO(VolumeTO other) { this.multiQueues = other.multiQueues; this.ioThreadId = other.ioThreadId; this.ioThreadPin = other.ioThreadPin; + this.ioThreads = other.ioThreads; this.controllerIndex = other.controllerIndex; } @@ -290,6 +293,14 @@ public String getIoThreadPin() { return ioThreadPin; } + public int getIoThreads() { + return ioThreads; + } + + public void setIoThreads(int ioThreads) { + this.ioThreads = ioThreads; + } + public int getControllerIndex() { return controllerIndex; } diff --git a/sdk/src/main/java/org/zstack/sdk/VolumeTO.java b/sdk/src/main/java/org/zstack/sdk/VolumeTO.java index 84eb1d8518f..ce2c6b372a1 100644 --- a/sdk/src/main/java/org/zstack/sdk/VolumeTO.java +++ b/sdk/src/main/java/org/zstack/sdk/VolumeTO.java @@ -148,6 +148,14 @@ public java.lang.String getIoThreadPin() { return this.ioThreadPin; } + public int ioThreads; + public void setIoThreads(int ioThreads) { + this.ioThreads = ioThreads; + } + public int getIoThreads() { + return this.ioThreads; + } + public int controllerIndex; public void setControllerIndex(int controllerIndex) { this.controllerIndex = controllerIndex; diff --git a/test/src/test/groovy/org/zstack/test/integration/kvm/host/AddHostCase.groovy b/test/src/test/groovy/org/zstack/test/integration/kvm/host/AddHostCase.groovy index 1a26995ba59..12ab7899dbd 100644 --- a/test/src/test/groovy/org/zstack/test/integration/kvm/host/AddHostCase.groovy +++ b/test/src/test/groovy/org/zstack/test/integration/kvm/host/AddHostCase.groovy @@ -12,6 +12,7 @@ import org.zstack.header.host.HostVO import org.zstack.kvm.APIAddKVMHostMsg import org.zstack.kvm.AddKVMHostMsg import org.zstack.kvm.KVMHostInventory +import org.zstack.kvm.KVMSystemTags import org.zstack.sdk.AddKVMHostAction import org.zstack.sdk.ClusterInventory import org.zstack.sdk.GetHypervisorTypesResult @@ -56,6 +57,7 @@ class AddHostCase extends SubCase { testCheckHostManagementFailure() testInnerAddHostMsg() testGetHypervisorTypes() + testPackageVersionTagsClearedWhenFactMissing() testAddHostFailureRollback() testAddHostViaLongJob() testLongJobAddHostFailure() @@ -256,6 +258,43 @@ class AddHostCase extends SubCase { assert (reply.inventory as KVMHostInventory).osDistribution == distribution } + void testPackageVersionTagsClearedWhenFactMissing() { + String qemuKvmPackageVersion = "6.2.0-451.g623f2a5caf.el8" + String libvirtPackageVersion = "8.0.0-163.gd30ff15b84.el8" + + env.afterSimulator(KVM_HOST_FACT_PATH) { HostFactResponse rsp -> + rsp.qemuKvmPackageVersion = qemuKvmPackageVersion + rsp.libvirtPackageVersion = libvirtPackageVersion + return rsp + } + + org.zstack.sdk.KVMHostInventory host = addKVMHost { + resourceUuid = Platform.uuid + sessionId = adminSession() + clusterUuid = cluster.uuid + name = "kvm-package-version" + managementIp = "127.0.0.6" + username = "root" + password = "password" + } as org.zstack.sdk.KVMHostInventory + + assert KVMSystemTags.QEMU_KVM_PACKAGE_VERSION.getTokenByResourceUuid(host.uuid, KVMSystemTags.QEMU_KVM_PACKAGE_VERSION_TOKEN) == qemuKvmPackageVersion + assert KVMSystemTags.LIBVIRT_PACKAGE_VERSION.getTokenByResourceUuid(host.uuid, KVMSystemTags.LIBVIRT_PACKAGE_VERSION_TOKEN) == libvirtPackageVersion + + env.afterSimulator(KVM_HOST_FACT_PATH) { HostFactResponse rsp -> + rsp.qemuKvmPackageVersion = null + rsp.libvirtPackageVersion = " " + return rsp + } + + reconnectHost { + uuid = host.uuid + } + + assert KVMSystemTags.QEMU_KVM_PACKAGE_VERSION.getTokenByResourceUuid(host.uuid, KVMSystemTags.QEMU_KVM_PACKAGE_VERSION_TOKEN) == null + assert KVMSystemTags.LIBVIRT_PACKAGE_VERSION.getTokenByResourceUuid(host.uuid, KVMSystemTags.LIBVIRT_PACKAGE_VERSION_TOKEN) == null + } + void testGetHypervisorTypes() { GetHypervisorTypesResult result = getHypervisorTypes { sessionId = adminSession()