diff --git a/0008-QMP-bugfix-the-error-in-the-return-result-of-query_c.patch b/0008-QMP-bugfix-the-error-in-the-return-result-of-query_c.patch new file mode 100644 index 0000000000000000000000000000000000000000..3b4dc2bf61ee55923fa7333ae9e981339b0904b7 --- /dev/null +++ b/0008-QMP-bugfix-the-error-in-the-return-result-of-query_c.patch @@ -0,0 +1,171 @@ +From 1cd0eea327faf629b7eef5433be6c42c83a32e09 Mon Sep 17 00:00:00 2001 +From: Mingwang Li +Date: Thu, 22 May 2025 11:02:00 +0800 +Subject: [PATCH 1/2] QMP: bugfix the error in the return result of + query_commands + +There is no need to use conditional judgment for enumeration variable aliases; +otherwise, the names of each variable in the enumeration will be wrongly obtained. + +Signed-off-by: Mingwang Li +Signed-off-by: Kunkun Jiang +--- + machine_manager/src/qmp/qmp_schema.rs | 128 +++++++++++++------------- + 1 file changed, 64 insertions(+), 64 deletions(-) + +diff --git a/machine_manager/src/qmp/qmp_schema.rs b/machine_manager/src/qmp/qmp_schema.rs +index 4281624..4f05689 100644 +--- a/machine_manager/src/qmp/qmp_schema.rs ++++ b/machine_manager/src/qmp/qmp_schema.rs +@@ -54,7 +54,7 @@ impl QmpErrorClass { + } + + macro_rules! define_qmp_command_enum { +- ($($command:ident($name:expr, $args_type:ty, $need_strum:ident $(, $serde_default:ident)?)),*) => { ++ ($($command:ident($name:expr, $args_type:ty $(, $serde_default:ident)?)),*) => { + /// A enum to store all command struct + #[derive(Debug, Clone, Serialize, Deserialize, EnumIter, EnumVariantNames, EnumString)] + #[serde(tag = "execute")] +@@ -62,7 +62,7 @@ macro_rules! define_qmp_command_enum { + pub enum QmpCommand { + $( + #[serde(rename = $name)] +- #[cfg_attr($need_strum, strum(serialize = $name))] ++ #[strum(serialize = $name)] + $command { + $(#[serde($serde_default)])? + arguments: $args_type, +@@ -76,68 +76,68 @@ macro_rules! define_qmp_command_enum { + + // QMP command enum definition example: command("name", arguments, ..) + define_qmp_command_enum!( +- qmp_capabilities("qmp_capabilities", qmp_capabilities, FALSE, default), +- quit("quit", quit, FALSE, default), +- stop("stop", stop, FALSE, default), +- cont("cont", cont, FALSE, default), +- system_powerdown("system_powerdown", system_powerdown, FALSE, default), +- system_reset("system_reset", system_reset, FALSE, default), +- device_add("device_add", Box, FALSE), +- device_del("device_del", device_del, FALSE), +- chardev_add("chardev-add", chardev_add, FALSE), +- chardev_remove("chardev-remove", chardev_remove, FALSE), +- netdev_add("netdev_add", Box, FALSE), +- netdev_del("netdev_del", netdev_del, FALSE), +- cameradev_add("cameradev_add", cameradev_add, FALSE), +- cameradev_del("cameradev_del", cameradev_del, FALSE), +- query_hotpluggable_cpus("query-hotpluggable-cpus", query_hotpluggable_cpus, TRUE, default), +- query_cpus("query-cpus", query_cpus, TRUE, default), +- query_status("query-status", query_status, FALSE, default), +- getfd("getfd", getfd, FALSE), +- blockdev_add("blockdev-add", Box, FALSE), +- blockdev_del("blockdev-del", blockdev_del, FALSE), +- balloon("balloon", balloon, FALSE, default), +- query_mem("query-mem", query_mem, FALSE, default), +- query_mem_gpa("query-mem-gpa", query_mem_gpa, FALSE, default), +- query_balloon("query-balloon", query_balloon, FALSE, default), +- query_vnc("query-vnc", query_vnc, TRUE, default), +- query_display_image("query-display-image", query_display_image, FALSE, default), +- switch_audio_record("switch-audio-record", switch_audio_record, FALSE), +- migrate("migrate", migrate, FALSE), +- query_migrate("query-migrate", query_migrate, FALSE, default), +- cancel_migrate("migrate_cancel", cancel_migrate, FALSE, default), +- query_version("query-version", query_version, FALSE, default), +- query_commands("query-commands", query_commands, FALSE, default), +- query_target("query-target", query_target, FALSE, default), +- query_kvm("query-kvm", query_kvm, FALSE, default), +- query_machines("query-machines", query_machines, FALSE, default), +- query_events("query-events", query_events, TRUE, default), +- list_type("qom-list-types", list_type, FALSE, default), +- device_list_properties("device-list-properties", device_list_properties, FALSE, default), +- block_commit("block-commit", block_commit, TRUE, default), +- query_tpm_models("query-tpm-models", query_tpm_models, FALSE, default), +- query_tpm_types("query-tpm-types", query_tpm_types, FALSE, default), +- query_command_line_options("query-command-line-options", query_command_line_options, FALSE, default), +- query_migrate_capabilities("query-migrate-capabilities", query_migrate_capabilities, FALSE, default), +- query_qmp_schema("query-qmp-schema", query_qmp_schema, FALSE, default), +- query_sev_capabilities("query-sev-capabilities", query_sev_capabilities, FALSE, default), +- query_chardev("query-chardev", query_chardev, TRUE, default), +- qom_list("qom-list", qom_list, TRUE, default), +- qom_get("qom-get", qom_get, TRUE, default), +- query_block("query-block", query_block, TRUE, default), +- query_named_block_nodes("query-named-block-nodes", query_named_block_nodes, TRUE, default), +- query_blockstats("query-blockstats", query_blockstats, TRUE, default), +- query_block_jobs("query-block-jobs", query_block_jobs, TRUE, default), +- query_gic_capabilities("query-gic-capabilities", query_gic_capabilities, TRUE, default), +- query_iothreads("query-iothreads", query_iothreads, TRUE, default), +- update_region("update_region", update_region, TRUE, default), +- input_event("input_event", input_event, FALSE, default), +- human_monitor_command("human-monitor-command", human_monitor_command, FALSE), +- blockdev_snapshot_internal_sync("blockdev-snapshot-internal-sync", blockdev_snapshot_internal, FALSE), +- blockdev_snapshot_delete_internal_sync("blockdev-snapshot-delete-internal-sync", blockdev_snapshot_internal, FALSE), +- query_vcpu_reg("query-vcpu-reg", query_vcpu_reg, FALSE), +- trace_get_state("trace-get-state", trace_get_state, FALSE), +- trace_set_state("trace-set-state", trace_set_state, FALSE) ++ qmp_capabilities("qmp_capabilities", qmp_capabilities, default), ++ quit("quit", quit, default), ++ stop("stop", stop, default), ++ cont("cont", cont, default), ++ system_powerdown("system_powerdown", system_powerdown, default), ++ system_reset("system_reset", system_reset, default), ++ device_add("device_add", Box), ++ device_del("device_del", device_del), ++ chardev_add("chardev-add", chardev_add), ++ chardev_remove("chardev-remove", chardev_remove), ++ netdev_add("netdev_add", Box), ++ netdev_del("netdev_del", netdev_del), ++ cameradev_add("cameradev_add", cameradev_add), ++ cameradev_del("cameradev_del", cameradev_del), ++ query_hotpluggable_cpus("query-hotpluggable-cpus", query_hotpluggable_cpus, default), ++ query_cpus("query-cpus", query_cpus, default), ++ query_status("query-status", query_status, default), ++ getfd("getfd", getfd), ++ blockdev_add("blockdev-add", Box), ++ blockdev_del("blockdev-del", blockdev_del), ++ balloon("balloon", balloon, default), ++ query_mem("query-mem", query_mem, default), ++ query_mem_gpa("query-mem-gpa", query_mem_gpa, default), ++ query_balloon("query-balloon", query_balloon, default), ++ query_vnc("query-vnc", query_vnc, default), ++ query_display_image("query-display-image", query_display_image, default), ++ switch_audio_record("switch-audio-record", switch_audio_record), ++ migrate("migrate", migrate), ++ query_migrate("query-migrate", query_migrate, default), ++ cancel_migrate("migrate_cancel", cancel_migrate, default), ++ query_version("query-version", query_version, default), ++ query_commands("query-commands", query_commands, default), ++ query_target("query-target", query_target, default), ++ query_kvm("query-kvm", query_kvm, default), ++ query_machines("query-machines", query_machines, default), ++ query_events("query-events", query_events, default), ++ list_type("qom-list-types", list_type, default), ++ device_list_properties("device-list-properties", device_list_properties, default), ++ block_commit("block-commit", block_commit, default), ++ query_tpm_models("query-tpm-models", query_tpm_models, default), ++ query_tpm_types("query-tpm-types", query_tpm_types, default), ++ query_command_line_options("query-command-line-options", query_command_line_options, default), ++ query_migrate_capabilities("query-migrate-capabilities", query_migrate_capabilities, default), ++ query_qmp_schema("query-qmp-schema", query_qmp_schema, default), ++ query_sev_capabilities("query-sev-capabilities", query_sev_capabilities, default), ++ query_chardev("query-chardev", query_chardev, default), ++ qom_list("qom-list", qom_list, default), ++ qom_get("qom-get", qom_get, default), ++ query_block("query-block", query_block, default), ++ query_named_block_nodes("query-named-block-nodes", query_named_block_nodes, default), ++ query_blockstats("query-blockstats", query_blockstats, default), ++ query_block_jobs("query-block-jobs", query_block_jobs, default), ++ query_gic_capabilities("query-gic-capabilities", query_gic_capabilities, default), ++ query_iothreads("query-iothreads", query_iothreads, default), ++ update_region("update_region", update_region, default), ++ input_event("input_event", input_event, default), ++ human_monitor_command("human-monitor-command", human_monitor_command), ++ blockdev_snapshot_internal_sync("blockdev-snapshot-internal-sync", blockdev_snapshot_internal), ++ blockdev_snapshot_delete_internal_sync("blockdev-snapshot-delete-internal-sync", blockdev_snapshot_internal), ++ query_vcpu_reg("query-vcpu-reg", query_vcpu_reg), ++ trace_get_state("trace-get-state", trace_get_state), ++ trace_set_state("trace-set-state", trace_set_state) + ); + + /// Command trait for Deserialize and find back Response. +-- +2.43.0 + diff --git a/0009-QMP-add-query-cpus-fast.patch b/0009-QMP-add-query-cpus-fast.patch new file mode 100644 index 0000000000000000000000000000000000000000..3be4cc0442adb8599642aa5d55822f16966447be --- /dev/null +++ b/0009-QMP-add-query-cpus-fast.patch @@ -0,0 +1,231 @@ +From 121df9ccb7a5dffa26ec4fc8412799a385abf05d Mon Sep 17 00:00:00 2001 +From: Kunkun Jiang +Date: Thu, 22 May 2025 12:30:04 +0800 +Subject: [PATCH 2/2] QMP: add query-cpus-fast + +This commit introduces a replacement for query-cpus called +query-cpus-fast. query-cpus has been discarded in libvirt. + +Signed-off-by: Kunkun Jiang +--- + machine/src/micro_common/mod.rs | 27 +++++++++ + machine/src/standard_common/mod.rs | 27 +++++++++ + machine_manager/src/machine.rs | 2 + + machine_manager/src/qmp/qmp_schema.rs | 85 +++++++++++++++++++++++++++ + machine_manager/src/qmp/qmp_socket.rs | 1 + + 5 files changed, 142 insertions(+) + +diff --git a/machine/src/micro_common/mod.rs b/machine/src/micro_common/mod.rs +index b97f046..8b40b16 100644 +--- a/machine/src/micro_common/mod.rs ++++ b/machine/src/micro_common/mod.rs +@@ -577,6 +577,33 @@ impl DeviceInterface for LightMachine { + Response::create_response(cpu_vec.into(), None) + } + ++ fn query_cpus_fast(&self) -> Response { ++ let mut cpu_vec: Vec = Vec::new(); ++ let cpu_topo = self.get_cpu_topo(); ++ let cpus = self.get_cpus(); ++ for cpu_index in 0..cpu_topo.max_cpus { ++ if cpu_topo.get_mask(cpu_index as usize) == 1 { ++ let thread_id = cpus[cpu_index as usize].tid(); ++ let cpu_instance = cpu_topo.get_topo_instance_for_qmp(cpu_index as usize); ++ #[cfg(target_arch = "x86_64")] ++ let target = String::from("x86_64"); ++ #[cfg(target_arch = "aarch64")] ++ let target = String::from("aarch64"); ++ let cpu_info = qmp_schema::CpuInfoFast { ++ qom_path: String::from("/machine/unattached/device[") ++ + &cpu_index.to_string() ++ + "]", ++ props: Some(cpu_instance), ++ cpu_index: cpu_index as isize, ++ thread_id: thread_id as isize, ++ target: target, ++ }; ++ cpu_vec.push(serde_json::to_value(cpu_info).unwrap()); ++ } ++ } ++ Response::create_response(cpu_vec.into(), None) ++ } ++ + fn query_hotpluggable_cpus(&self) -> Response { + let mut hotplug_vec: Vec = Vec::new(); + #[cfg(target_arch = "x86_64")] +diff --git a/machine/src/standard_common/mod.rs b/machine/src/standard_common/mod.rs +index 1ab0be0..fc10707 100644 +--- a/machine/src/standard_common/mod.rs ++++ b/machine/src/standard_common/mod.rs +@@ -1008,6 +1008,33 @@ impl DeviceInterface for StdMachine { + Response::create_response(cpu_vec.into(), None) + } + ++ fn query_cpus_fast(&self) -> Response { ++ let mut cpu_vec: Vec = Vec::new(); ++ let cpu_topo = self.get_cpu_topo(); ++ let cpus = self.get_cpus(); ++ for cpu_index in 0..cpu_topo.max_cpus { ++ if cpu_topo.get_mask(cpu_index as usize) == 1 { ++ let thread_id = cpus[cpu_index as usize].tid(); ++ let cpu_instance = cpu_topo.get_topo_instance_for_qmp(cpu_index as usize); ++ #[cfg(target_arch = "x86_64")] ++ let target = String::from("x86_64"); ++ #[cfg(target_arch = "aarch64")] ++ let target = String::from("aarch64"); ++ let cpu_info = qmp_schema::CpuInfoFast { ++ qom_path: String::from("/machine/unattached/device[") ++ + &cpu_index.to_string() ++ + "]", ++ props: Some(cpu_instance), ++ cpu_index: cpu_index as isize, ++ thread_id: thread_id as isize, ++ target: target, ++ }; ++ cpu_vec.push(serde_json::to_value(cpu_info).unwrap()); ++ } ++ } ++ Response::create_response(cpu_vec.into(), None) ++ } ++ + fn query_hotpluggable_cpus(&self) -> Response { + Response::create_empty_response() + } +diff --git a/machine_manager/src/machine.rs b/machine_manager/src/machine.rs +index f0f00aa..4d36e80 100644 +--- a/machine_manager/src/machine.rs ++++ b/machine_manager/src/machine.rs +@@ -155,6 +155,8 @@ pub trait DeviceInterface { + /// Query each cpu's the topology info. + fn query_cpus(&self) -> Response; + ++ fn query_cpus_fast(&self) -> Response; ++ + /// Query each `hotpluggable_cpus`'s topology info and hotplug message. + fn query_hotpluggable_cpus(&self) -> Response; + +diff --git a/machine_manager/src/qmp/qmp_schema.rs b/machine_manager/src/qmp/qmp_schema.rs +index 4f05689..110e1f9 100644 +--- a/machine_manager/src/qmp/qmp_schema.rs ++++ b/machine_manager/src/qmp/qmp_schema.rs +@@ -92,6 +92,7 @@ define_qmp_command_enum!( + cameradev_del("cameradev_del", cameradev_del), + query_hotpluggable_cpus("query-hotpluggable-cpus", query_hotpluggable_cpus, default), + query_cpus("query-cpus", query_cpus, default), ++ query_cpus_fast("query-cpus-fast", query_cpus_fast, default), + query_status("query-status", query_status, default), + getfd("getfd", getfd), + blockdev_add("blockdev-add", Box), +@@ -851,6 +852,63 @@ pub struct CpuInfoX86 {} + #[derive(Default, Debug, Clone, Serialize, Deserialize)] + pub struct CpuInfoArm {} + ++/// @query-cpus-fast: ++/// ++/// Returns information about all virtual CPUs. ++/// ++/// Returns: list of @CpuInfoFast ++/// ++/// Since: 2.12 ++/// ++/// Example: ++/// ++/// -> { "execute": "query-cpus-fast" } ++/// <- { "return": [ ++/// { ++/// "thread-id": 25627, ++/// "props": { ++/// "core-id": 0, ++/// "thread-id": 0, ++/// "socket-id": 0 ++/// }, ++/// "qom-path": "/machine/unattached/device[0]", ++/// "target":"x86_64", ++/// "cpu-index": 0 ++/// }, ++/// { ++/// "thread-id": 25628, ++/// "props": { ++/// "core-id": 0, ++/// "thread-id": 0, ++/// "socket-id": 1 ++/// }, ++/// "qom-path": "/machine/unattached/device[2]", ++/// "target":"x86_64", ++/// "cpu-index": 1 ++/// } ++/// ] ++/// } ++/// ++/// ``` ++#[derive(Default, Debug, Clone, Serialize, Deserialize)] ++#[serde(deny_unknown_fields)] ++pub struct query_cpus_fast {} ++generate_command_impl!(query_cpus_fast, Vec); ++ ++#[derive(Debug, Clone, Serialize, Deserialize)] ++pub struct CpuInfoFast { ++ #[serde(rename = "qom_path")] ++ pub qom_path: String, ++ #[serde(rename = "props", default, skip_serializing_if = "Option::is_none")] ++ pub props: Option, ++ #[serde(rename = "cpu-index")] ++ pub cpu_index: isize, ++ #[serde(rename = "thread-id")] ++ pub thread_id: isize, ++ #[serde(rename = "target")] ++ pub target: String, ++} ++ + /// query-status + /// + /// Query the run status of all VCPUs. +@@ -2170,6 +2228,33 @@ mod tests { + let ret_msg = r#"invalid type: string "isdf", expected struct query_cpus"#; + assert!(err_msg == ret_msg); + ++ // qmp: query-cpus-fast. ++ let json_msg = r#" ++ { ++ "execute": "query-cpus-fast" ++ } ++ "#; ++ let err_msg = match serde_json::from_str::(json_msg) { ++ Ok(_) => "ok".to_string(), ++ Err(e) => e.to_string(), ++ }; ++ let ret_msg = r#"ok"#; ++ assert!(err_msg == ret_msg); ++ ++ // unexpected arguments for query-cpus-fast. ++ let json_msg = r#" ++ { ++ "execute": "query-cpus-fast" , ++ "arguments": "isdf" ++ } ++ "#; ++ let err_msg = match serde_json::from_str::(json_msg) { ++ Ok(_) => "ok".to_string(), ++ Err(e) => e.to_string(), ++ }; ++ let ret_msg = r#"invalid type: string "isdf", expected struct query_cpus_fast"#; ++ assert!(err_msg == ret_msg); ++ + // qmp: query-ststus. + let json_msg = r#" + { +diff --git a/machine_manager/src/qmp/qmp_socket.rs b/machine_manager/src/qmp/qmp_socket.rs +index 35ad238..3ae155c 100644 +--- a/machine_manager/src/qmp/qmp_socket.rs ++++ b/machine_manager/src/qmp/qmp_socket.rs +@@ -460,6 +460,7 @@ fn qmp_command_exec( + (query_migrate, query_migrate), + (cancel_migrate, cancel_migrate), + (query_cpus, query_cpus), ++ (query_cpus_fast, query_cpus_fast), + (query_balloon, query_balloon), + (query_mem, query_mem), + (query_vnc, query_vnc), +-- +2.43.0 + diff --git a/stratovirt.spec b/stratovirt.spec index c715b3c5fc3ecea9526c0ac76cd951a7f784b52e..d7b8bf67713b392ddf836671627cd780c2c66875 100644 --- a/stratovirt.spec +++ b/stratovirt.spec @@ -6,7 +6,7 @@ Name: stratovirt Version: 2.4.0 -Release: 7 +Release: 8 Summary: StratoVirt is an opensource VMM(Virtual Machine Manager) which aims to perform next generation virtualization. License: MulanPSL-2.0 @@ -24,6 +24,8 @@ Patch006:0006-introduce-riscv64-architecture-support.patch %endif Patch007:0007-vfio-pci-fix-a-deadlock-problem.patch +Patch008:0008-QMP-bugfix-the-error-in-the-return-result-of-query_c.patch +Patch009:0009-QMP-add-query-cpus-fast.patch ExclusiveArch: x86_64 aarch64 riscv64 @@ -129,6 +131,10 @@ install -D -m555 ./target/%{rust_musl_target}/release/stratovirt %{buildroot}%{_ %endif %changelog +* Thu May 22 2025 jiangkunkun 2.4.0-8 +- bugfix the error in the return result of query_commands +- add QMP query-cpus-fast + * Wed May 21 2025 shenyage 2.4.0-7 - vfio-pci: fix a deadlock problem