mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: config: Fix generic vhost-user parsing
The generic vhost-user device took its virtio device type on the command line via the `virtio_id` parameter, but the same value is called `device_type` in the API and the resulting config struct. This irregularity was due to churn during the review process, `device_type` was the intended name. Accept `device_type` on the command line and keep `virtio_id` as a deprecated alias that logs a warning. The alias will then be removed in a later release. Fixes: #8545 Assisted-by: Claude:Opus-4.8 Signed-off-by: Rob Bradford <rbradford@meta.com>
This commit is contained in:
@@ -957,7 +957,7 @@ pub(crate) fn _test_virtio_fs(
|
|||||||
"socket={},id=myfs0,{}{}",
|
"socket={},id=myfs0,{}{}",
|
||||||
virtiofsd_socket_path,
|
virtiofsd_socket_path,
|
||||||
if use_generic_vhost_user {
|
if use_generic_vhost_user {
|
||||||
"queue_sizes=[1024,1024],virtio_id=26"
|
"queue_sizes=[1024,1024],device_type=26"
|
||||||
} else {
|
} else {
|
||||||
"tag=myfs,num_queues=1,queue_size=1024"
|
"tag=myfs,num_queues=1,queue_size=1024"
|
||||||
},
|
},
|
||||||
@@ -1090,7 +1090,7 @@ pub(crate) fn _test_virtio_fs(
|
|||||||
"id=myfs0,socket={},{}{}",
|
"id=myfs0,socket={},{}{}",
|
||||||
virtiofsd_socket_path,
|
virtiofsd_socket_path,
|
||||||
if use_generic_vhost_user {
|
if use_generic_vhost_user {
|
||||||
"queue_sizes=[1024,1024],virtio_id=26"
|
"queue_sizes=[1024,1024],device_type=26"
|
||||||
} else {
|
} else {
|
||||||
"tag=myfs,num_queues=1,queue_size=1024"
|
"tag=myfs,num_queues=1,queue_size=1024"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -43,14 +43,14 @@ similar to this:
|
|||||||
--disk path=your-linux-image.iso \
|
--disk path=your-linux-image.iso \
|
||||||
--kernel vmlinux \
|
--kernel vmlinux \
|
||||||
--cmdline "console=hvc0 root=/dev/vda1 rw" \
|
--cmdline "console=hvc0 root=/dev/vda1 rw" \
|
||||||
--generic-vhost-user "socket=\"${path_to_virtiofsd_socket//\"/\"\"}\",virtio_id=26,queue_sizes=[512,512]" \
|
--generic-vhost-user "socket=\"${path_to_virtiofsd_socket//\"/\"\"}\",device_type=26,queue_sizes=[512,512]" \
|
||||||
"${other_cloud_hypervisor_options[@]}"
|
"${other_cloud_hypervisor_options[@]}"
|
||||||
```
|
```
|
||||||
|
|
||||||
26 is the ID for a virtio-fs device. The IDs for other devices are defined
|
26 is the ID for a virtio-fs device. The IDs for other devices are defined
|
||||||
by the VIRTIO specification. The odd-looking variable expansion escapes
|
by the VIRTIO specification. The odd-looking variable expansion escapes
|
||||||
any double quotes in the socket path. It is also possible to provide
|
any double quotes in the socket path. It is also possible to provide
|
||||||
the name that is defined by the virtio specification, so `virtio_id=fs`
|
the name that is defined by the virtio specification, so `device_type=fs`
|
||||||
will also work.
|
will also work.
|
||||||
|
|
||||||
Inside the guest, you can mount the virtio-fs device with
|
Inside the guest, you can mount the virtio-fs device with
|
||||||
|
|||||||
@@ -53,14 +53,14 @@ pub enum Error {
|
|||||||
/// Filesystem socket is missing
|
/// Filesystem socket is missing
|
||||||
#[error("Error parsing --fs: socket missing")]
|
#[error("Error parsing --fs: socket missing")]
|
||||||
ParseFsSockMissing,
|
ParseFsSockMissing,
|
||||||
/// Generic vhost-user virtio ID is invalid
|
/// Generic vhost-user device type is invalid
|
||||||
#[error(
|
#[error(
|
||||||
"Error parsing --generic-vhost-user: virtio ID {0:?} invalid (leading zeros or unknown string)"
|
"Error parsing --generic-vhost-user: device_type {0:?} invalid (leading zeros or unknown string)"
|
||||||
)]
|
)]
|
||||||
ParseGenericVhostUserVirtioIdInvalid(String),
|
ParseGenericVhostUserVirtioIdInvalid(String),
|
||||||
/// Generic vhost-user virtio ID is unsupported
|
/// Generic vhost-user device type is unsupported
|
||||||
#[error(
|
#[error(
|
||||||
"Error parsing --generic-vhost-user: device with virtio ID {0:?} cannot be implemented via vhost-user"
|
"Error parsing --generic-vhost-user: device with device_type {0:?} cannot be implemented via vhost-user"
|
||||||
)]
|
)]
|
||||||
ParseGenericVhostUserVirtioIdUnsupported(String),
|
ParseGenericVhostUserVirtioIdUnsupported(String),
|
||||||
/// Generic vhost-user socket is missing
|
/// Generic vhost-user socket is missing
|
||||||
@@ -69,8 +69,8 @@ pub enum Error {
|
|||||||
/// Generic vhost-user number of queues is missing
|
/// Generic vhost-user number of queues is missing
|
||||||
#[error("Error parsing --generic-vhost-user: number of queues missing")]
|
#[error("Error parsing --generic-vhost-user: number of queues missing")]
|
||||||
ParseGenericVhostUserNumResponseQueuesMissing,
|
ParseGenericVhostUserNumResponseQueuesMissing,
|
||||||
/// Generic vhost-user virtio ID is missing
|
/// Generic vhost-user device type is missing
|
||||||
#[error("Error parsing --generic-vhost-user: virtio ID missing")]
|
#[error("Error parsing --generic-vhost-user: device_type missing")]
|
||||||
ParseGenericVhostUserVirtioIdMissing,
|
ParseGenericVhostUserVirtioIdMissing,
|
||||||
/// Generic vhost-user available features is missing
|
/// Generic vhost-user available features is missing
|
||||||
#[error("Error parsing --generic-vhost-user: available features missing")]
|
#[error("Error parsing --generic-vhost-user: available features missing")]
|
||||||
@@ -1998,7 +1998,7 @@ impl BalloonConfig {
|
|||||||
|
|
||||||
impl GenericVhostUserConfig {
|
impl GenericVhostUserConfig {
|
||||||
pub const SYNTAX: &'static str = "generic vhost-user parameters \
|
pub const SYNTAX: &'static str = "generic vhost-user parameters \
|
||||||
\"virtio_id=<ID number for virtio device type (FS, block, net, etc) or symbolic name>,\
|
\"device_type=<ID number for virtio device type (FS, block, net, etc) or symbolic name>,\
|
||||||
socket=<socket_path>,\
|
socket=<socket_path>,\
|
||||||
queue_sizes=<list of queue sizes>,\
|
queue_sizes=<list of queue sizes>,\
|
||||||
id=<device_id>,pci_segment=<segment_id>,pci_device_id=<pci_slot>\"";
|
id=<device_id>,pci_segment=<segment_id>,pci_device_id=<pci_slot>\"";
|
||||||
@@ -2006,6 +2006,8 @@ impl GenericVhostUserConfig {
|
|||||||
pub fn parse(vhost_user: &str) -> Result<Self> {
|
pub fn parse(vhost_user: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser
|
parser
|
||||||
|
.add("device_type")
|
||||||
|
// TODO: Remove 'virtio_id' as a deprecated alias for 'device_type'
|
||||||
.add("virtio_id")
|
.add("virtio_id")
|
||||||
.add("queue_sizes")
|
.add("queue_sizes")
|
||||||
.add("socket")
|
.add("socket")
|
||||||
@@ -2022,9 +2024,16 @@ impl GenericVhostUserConfig {
|
|||||||
.convert::<IntegerList<u16>>("queue_sizes")
|
.convert::<IntegerList<u16>>("queue_sizes")
|
||||||
.map_err(Error::ParseGenericVhostUser)?
|
.map_err(Error::ParseGenericVhostUser)?
|
||||||
.ok_or(Error::ParseGenericVhostUserQueueSizeMissing)?;
|
.ok_or(Error::ParseGenericVhostUserQueueSizeMissing)?;
|
||||||
let device_type_str = parser
|
let legacy_virtio_id = parser
|
||||||
.convert::<String>("virtio_id")
|
.convert::<String>("virtio_id")
|
||||||
|
.map_err(Error::ParseGenericVhostUser)?;
|
||||||
|
if legacy_virtio_id.is_some() {
|
||||||
|
warn!("'virtio_id' in --generic-vhost-user is deprecated; use 'device_type'.");
|
||||||
|
}
|
||||||
|
let device_type_str = parser
|
||||||
|
.convert::<String>("device_type")
|
||||||
.map_err(Error::ParseGenericVhostUser)?
|
.map_err(Error::ParseGenericVhostUser)?
|
||||||
|
.or(legacy_virtio_id)
|
||||||
.ok_or(Error::ParseGenericVhostUserVirtioIdMissing)?;
|
.ok_or(Error::ParseGenericVhostUserVirtioIdMissing)?;
|
||||||
let device_type = match device_type_str.as_bytes() {
|
let device_type = match device_type_str.as_bytes() {
|
||||||
b"net" => VIRTIO_ID_NET,
|
b"net" => VIRTIO_ID_NET,
|
||||||
@@ -4583,7 +4592,7 @@ mod unit_tests {
|
|||||||
assert!(!socket.contains(",[]\n\r\0\""));
|
assert!(!socket.contains(",[]\n\r\0\""));
|
||||||
assert!(!id.contains(",[]\n\r\0\""));
|
assert!(!id.contains(",[]\n\r\0\""));
|
||||||
let config = GenericVhostUserConfig::parse(&format!(
|
let config = GenericVhostUserConfig::parse(&format!(
|
||||||
"virtio_id={virtio_id},socket=\"{socket}\",\
|
"device_type={virtio_id},socket=\"{socket}\",\
|
||||||
id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||||
));
|
));
|
||||||
if pci_segment <= u16::MAX.into()
|
if pci_segment <= u16::MAX.into()
|
||||||
@@ -4658,6 +4667,15 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
|||||||
10,
|
10,
|
||||||
&IntegerList(vec![20u64]),
|
&IntegerList(vec![20u64]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// The deprecated 'virtio_id' key is an alias for 'device_type' and must
|
||||||
|
// parse to an identical configuration.
|
||||||
|
assert_eq!(
|
||||||
|
GenericVhostUserConfig::parse("virtio_id=26,socket=/tmp/sock,queue_sizes=[1024]")
|
||||||
|
.unwrap(),
|
||||||
|
GenericVhostUserConfig::parse("device_type=26,socket=/tmp/sock,queue_sizes=[1024]")
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3590,7 +3590,7 @@ mod unit_tests {
|
|||||||
fn test_vmm_vm_cold_add_generic_vhost_user() {
|
fn test_vmm_vm_cold_add_generic_vhost_user() {
|
||||||
let mut vmm = create_dummy_vmm();
|
let mut vmm = create_dummy_vmm();
|
||||||
let generic_vhost_user_config =
|
let generic_vhost_user_config =
|
||||||
GenericVhostUserConfig::parse("virtio_id=26,socket=/tmp/sock,queue_sizes=[1024]")
|
GenericVhostUserConfig::parse("device_type=26,socket=/tmp/sock,queue_sizes=[1024]")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
|
|||||||
Reference in New Issue
Block a user