diff --git a/0010-add-support-to-interconnecting-with-libvirt.patch b/0010-add-support-to-interconnecting-with-libvirt.patch new file mode 100644 index 0000000000000000000000000000000000000000..c3217ba9f453a9abf7ca255bdfa970e21d2f9a71 --- /dev/null +++ b/0010-add-support-to-interconnecting-with-libvirt.patch @@ -0,0 +1,233 @@ +From 763110fef62e39eb2f2a3db75f7583f799e4ad9c Mon Sep 17 00:00:00 2001 +From: Ming Yang +Date: Fri, 23 May 2025 11:47:40 +0800 +Subject: [PATCH] add support to interconnecting with libvirt + +--- + machine_manager/src/cmdline.rs | 19 ++++++++-------- + machine_manager/src/config/chardev.rs | 20 +++++++++++----- + machine_manager/src/config/machine_config.rs | 2 +- + machine_manager/src/machine.rs | 19 +++++++++++++++- + machine_manager/src/qmp/qmp_schema.rs | 24 ++++++++++++++++++++ + machine_manager/src/qmp/qmp_socket.rs | 1 + + 6 files changed, 68 insertions(+), 17 deletions(-) + +diff --git a/machine_manager/src/cmdline.rs b/machine_manager/src/cmdline.rs +index 5b0d275..d440cbc 100644 +--- a/machine_manager/src/cmdline.rs ++++ b/machine_manager/src/cmdline.rs +@@ -183,8 +183,8 @@ pub fn create_args_parser<'a>() -> ArgParser<'a> { + Arg::with_name("qmp") + .long("qmp") + .value_name("") +- .help("\n\t\tset unix socket path: unix:,server,nowait; \ +- \n\t\tset tcp socket path: tcp:ip:port,server,nowait") ++ .help("\n\t\tset unix socket path: unix:,server,nowait/wait=off; \ ++ \n\t\tset tcp socket path: tcp:ip:port,server,nowait/wait=off") + .takes_value(true) + ) + .arg( +@@ -222,8 +222,8 @@ pub fn create_args_parser<'a>() -> ArgParser<'a> { + .help("\n\t\tadd standard i/o device: -chardev stdio,id=; \ + \n\t\tadd pseudo-terminal: -chardev pty,id=; \ + \n\t\tadd file: -chardev file,id=,path=; \ +- \n\t\tadd unix-socket: -chardev socket,id=,path=[,server][,nowait]; \ +- \n\t\tadd tcp-socket: -chardev socket,id=,port=[,host=host][,server][,nowait];") ++ \n\t\tadd unix-socket: -chardev socket,id=,path=[,server][,nowait/wait=off]; \ ++ \n\t\tadd tcp-socket: -chardev socket,id=,port=[,host=host][,server][,nowait/wait=off];") + .takes_values(true), + ) + .arg( +@@ -266,8 +266,8 @@ pub fn create_args_parser<'a>() -> ArgParser<'a> { + \n\t\tuse standard i/o device: -serial stdio; \ + \n\t\tuse pseudo-terminal: -serial pty; \ + \n\t\tuse file: -serial file,path=; \ +- \n\t\tuse unix-socket: -serial socket,path=[,server][,nowait]; \ +- \n\t\tuse tcp-socket: -serial socket,port=[,host=][,server][,nowait]; \ ++ \n\t\tuse unix-socket: -serial socket,path=[,server][,nowait/wait=off]; \ ++ \n\t\tuse tcp-socket: -serial socket,port=[,host=][,server][,nowait/wait=off]; \ + ") + .takes_value(true), + ) +@@ -615,7 +615,7 @@ pub fn check_api_channel( + let mut sock_paths = Vec::new(); + if let Some(qmp_config) = args.value_of("qmp") { + let mut cmd_parser = CmdParser::new("qmp"); +- cmd_parser.push("").push("server").push("nowait"); ++ cmd_parser.push("").push("server").push("nowait").push("wait"); + + cmd_parser.parse(&qmp_config)?; + if let Some(uri) = cmd_parser.get_value::("")? { +@@ -628,8 +628,9 @@ pub fn check_api_channel( + if cmd_parser.get_value::("server")?.is_none() { + bail!("Argument \'server\' is needed for qmp"); + } +- if cmd_parser.get_value::("nowait")?.is_none() { +- bail!("Argument \'nowait\' is needed for qmp"); ++ if cmd_parser.get_value::("nowait")?.is_none() && cmd_parser ++ .get_value::("wait")?.is_none() { ++ bail!("Argument \'nowait\' or \'wait=off\'is needed for qmp"); + } + } + if let Some(mon_config) = args.value_of("mon") { +diff --git a/machine_manager/src/config/chardev.rs b/machine_manager/src/config/chardev.rs +index 943de72..7fa040c 100644 +--- a/machine_manager/src/config/chardev.rs ++++ b/machine_manager/src/config/chardev.rs +@@ -171,10 +171,7 @@ fn parse_file_chardev(chardev_id: String, cmd_parser: CmdParser) -> Result Result { + let mut server_enabled = false; + let server = cmd_parser.get_value::("server")?; +- if let Some(server) = server { +- if server.ne("") { +- bail!("No parameter needed for server"); +- } ++ if let Some(_server) = server { + server_enabled = true; + } + +@@ -187,9 +184,20 @@ fn parse_socket_chardev(chardev_id: String, cmd_parser: CmdParser) -> Result("wait")?; ++ if let Some(wait) = wait { ++ if wait.eq("off") { ++ nowait_enabled = true; ++ } else if wait.eq("on") { ++ nowait_enabled = false; ++ } else { ++ bail!("Unsupported parameters for wait"); ++ } ++ } ++ + let path = cmd_parser.get_value::("path")?; + if let Some(path) = path { +- let supported_fields = ["", "id", "path", "server", "nowait"]; ++ let supported_fields = ["", "id", "path", "server", "nowait", "wait"]; + check_chardev_fields("unix-socket", &cmd_parser, &supported_fields)?; + + let default_value = path.clone(); +@@ -232,7 +240,7 @@ fn parse_socket_chardev(chardev_id: String, cmd_parser: CmdParser) -> Result Result { + let mut cmd_parser = CmdParser::new("chardev"); +- for field in ["", "id", "path", "host", "port", "server", "nowait"] { ++ for field in ["", "id", "path", "host", "port", "server", "nowait", "wait"] { + cmd_parser.push(field); + } + +diff --git a/machine_manager/src/config/machine_config.rs b/machine_manager/src/config/machine_config.rs +index c1a6fb7..c83e12e 100644 +--- a/machine_manager/src/config/machine_config.rs ++++ b/machine_manager/src/config/machine_config.rs +@@ -474,7 +474,7 @@ impl VmConfig { + + fn get_mem_zone_size(&self, cmd_parser: &CmdParser) -> Result { + if let Some(mem) = cmd_parser.get_value::("size")? { +- let size = memory_unit_conversion(&mem, M)?; ++ let size = memory_unit_conversion(&mem, 1)?; + Ok(size) + } else { + Err(anyhow!(ConfigError::FieldIsMissing( +diff --git a/machine_manager/src/machine.rs b/machine_manager/src/machine.rs +index 4d36e80..92df5e2 100644 +--- a/machine_manager/src/machine.rs ++++ b/machine_manager/src/machine.rs +@@ -342,6 +342,7 @@ pub trait DeviceInterface { + ("usb-kbd", "usb-hid"), + ("usb-storage", "usb-storage-dev"), + ("virtio-gpu-pci", "virtio-gpu"), ++ ("pl011", "sys-bus-device"), + ]; + + for list in list_types { +@@ -351,6 +352,11 @@ pub trait DeviceInterface { + Response::create_response(serde_json::to_value(&vec_types).unwrap(), None) + } + ++ fn qom_list_properties(&self, _typename: String) -> Response { ++ let types = Vec::::new(); ++ Response::create_response(serde_json::to_value(types).unwrap(), None) ++ } ++ + fn device_list_properties(&self, typename: String) -> Response { + let mut vec_props = Vec::::new(); + let prop = DeviceProps { +@@ -411,7 +417,18 @@ pub trait DeviceInterface { + } + + fn query_qmp_schema(&self) -> Response { +- Response::create_empty_response() ++ let mut vec_types = Vec::new(); ++ let list_types: Vec<(&str, &str)> = vec![ ++ ("name", "query-status"), ++ ("ret-type", "1"), ++ ("meta-type", "command"), ++ ("arg-type", "0"), ++ ]; ++ for list in list_types { ++ let re = TypeLists::new(String::from(list.0), String::from(list.1)); ++ vec_types.push(re); ++ } ++ Response::create_response(serde_json::to_value(&vec_types).unwrap(), None) + } + + fn query_sev_capabilities(&self) -> Response { +diff --git a/machine_manager/src/qmp/qmp_schema.rs b/machine_manager/src/qmp/qmp_schema.rs +index 72314e8..8c38864 100644 +--- a/machine_manager/src/qmp/qmp_schema.rs ++++ b/machine_manager/src/qmp/qmp_schema.rs +@@ -114,6 +114,7 @@ define_qmp_command_enum!( + query_machines("query-machines", query_machines, default), + query_events("query-events", query_events, default), + list_type("qom-list-types", list_type, default), ++ qom_list_properties("qom-list-properties", qom_list_properties, 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), +@@ -1366,6 +1367,29 @@ impl TypeLists { + } + } + ++/// qom-list-properties ++/// ++/// List properties associated with a qom. ++/// ++/// # Examples ++/// ++/// ```text ++/// -> { "execute": "qom-list-properties", "arguments": { "typename": "memory-backend-file" } } ++/// <- { "return": [] } ++/// ``` ++#[derive(Default, Debug, Clone, Serialize, Deserialize)] ++pub struct qom_list_properties { ++ pub typename: String, ++} ++generate_command_impl!(qom_list_properties, Vec); ++ ++#[derive(Default, Debug, Clone, Serialize, Deserialize)] ++pub struct QomListProps { ++ pub name: String, ++ #[serde(rename = "typename")] ++ pub prop_type: String, ++} ++ + /// device-list-properties + /// + /// List properties associated with a device. +diff --git a/machine_manager/src/qmp/qmp_socket.rs b/machine_manager/src/qmp/qmp_socket.rs +index 3ae155c..2372c96 100644 +--- a/machine_manager/src/qmp/qmp_socket.rs ++++ b/machine_manager/src/qmp/qmp_socket.rs +@@ -468,6 +468,7 @@ fn qmp_command_exec( + (list_type, list_type), + (query_hotpluggable_cpus, query_hotpluggable_cpus); + (input_event, input_event, key, value), ++ (qom_list_properties, qom_list_properties, typename), + (device_list_properties, device_list_properties, typename), + (device_del, device_del, id), + (switch_audio_record, switch_audio_record, authorized), +-- +2.43.0 + diff --git a/stratovirt.spec b/stratovirt.spec index d7b8bf67713b392ddf836671627cd780c2c66875..9465ff18613ca91db0482b80e158c013603db8c7 100644 --- a/stratovirt.spec +++ b/stratovirt.spec @@ -6,7 +6,7 @@ Name: stratovirt Version: 2.4.0 -Release: 8 +Release: 9 Summary: StratoVirt is an opensource VMM(Virtual Machine Manager) which aims to perform next generation virtualization. License: MulanPSL-2.0 @@ -26,6 +26,7 @@ Patch006:0006-introduce-riscv64-architecture-support.patch 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 +Patch010:0010-add-support-to-interconnecting-with-libvirt.patch ExclusiveArch: x86_64 aarch64 riscv64 @@ -131,6 +132,9 @@ install -D -m555 ./target/%{rust_musl_target}/release/stratovirt %{buildroot}%{_ %endif %changelog +* Fri May 23 2025 Ming Yang 2.4.0-9 +- add support to interconnect with libvirt + * Thu May 22 2025 jiangkunkun 2.4.0-8 - bugfix the error in the return result of query_commands - add QMP query-cpus-fast