diff --git a/README.md b/README.md index ae1c78543..2301050fd 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ $ pushd $CLOUDH $ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor $ ./cloud-hypervisor/target/release/cloud-hypervisor \ --kernel ./hypervisor-fw \ - --disk ./clear-29160-kvm.img \ + --disk path=clear-29160-kvm.img \ --cpus 4 \ --memory size=1024M \ --net "tap=,mac=,ip=,mask=" \ @@ -167,7 +167,7 @@ $ pushd $CLOUDH $ sudo setcap cap_net_admin+ep ./cloud-hypervisor/target/release/cloud-hypervisor $ ./cloud-hypervisor/target/release/cloud-hypervisor \ --kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \ - --disk ./clear-29160-kvm.img \ + --disk path=clear-29160-kvm.img \ --cmdline "console=hvc0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \ --cpus 4 \ --memory size=1024M \ @@ -187,7 +187,7 @@ $ ./cloud-hypervisor/target/release/cloud-hypervisor \ --kernel ./linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \ --console off \ --serial tty \ - --disk ./clear-29160-kvm.img \ + --disk path=clear-29160-kvm.img \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \ --cpus 4 \ --memory size=1024M \ diff --git a/docs/custom-image.md b/docs/custom-image.md index fe23d138b..d6cdb27b0 100644 --- a/docs/custom-image.md +++ b/docs/custom-image.md @@ -15,7 +15,7 @@ IMG_VERSION=$(curl https://download.clearlinux.org/latest) # Get latest clear-kvm image: wget -P $HOME/workloads/ https://download.clearlinux.org/current/clear-${IMG_VERSION}-kvm.img.xz # Boot cloud-hypervisor VM with the downloaded image -./cloud-hypervisor -v --kernel $HOME/workloads/vmlinux --disk clear-30970-kvm.img --cmdline "console=ttyS0 console=hvc0 reboot=k panic=1 nomodules root=/dev/vda3" --cpus 1 --memory size=1G --net tap=,mac= +./cloud-hypervisor -v --kernel $HOME/workloads/vmlinux --disk path=clear-30970-kvm.img --cmdline "console=ttyS0 console=hvc0 reboot=k panic=1 nomodules root=/dev/vda3" --cpus 1 --memory size=1G --net tap=,mac= # Setup connectivity IFACE=$(ip route | grep default | awk -F 'dev' '{print $2}' | awk -F ' ' '{print $1}') GW=$(ip route | grep vmtap0 | awk -F ' ' '{print $1}') diff --git a/docs/debug-port.md b/docs/debug-port.md index a8588ac73..e880db06b 100644 --- a/docs/debug-port.md +++ b/docs/debug-port.md @@ -43,7 +43,7 @@ to easily grep for the tracing logs (e.g. ``` ./target/debug/cloud-hypervisor \ --kernel ~/rust-hypervisor-firmware/target/target/release/hypervisor-fw \ - --disk ~/hypervisor/images/clear-30080-kvm.img \ + --disk path=~/hypervisor/images/clear-30080-kvm.img \ --cpus 4 \ --memory size=1024M \ --rng \ diff --git a/docs/fs.md b/docs/fs.md index e4cc87d02..6ca4f181d 100644 --- a/docs/fs.md +++ b/docs/fs.md @@ -53,7 +53,7 @@ Assuming you have `clear-kvm.img` and `custom-vmlinux.bin` on your system, here ./cloud-hypervisor \ --cpus 4 \ --memory "size=512,file=/dev/shm" \ - --disk clear-kvm.img \ + --disk path=clear-kvm.img \ --kernel custom-vmlinux.bin \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules root=/dev/vda3" \ --fs tag=virtiofs,sock=/tmp/virtiofs,num_queues=1,queue_size=512 diff --git a/docs/networking.md b/docs/networking.md index 293440992..e2fcab531 100644 --- a/docs/networking.md +++ b/docs/networking.md @@ -10,7 +10,7 @@ Use one `--net` command-line argument from cloud-hypervisor to specify the emula ./cloud-hypervisor \ --cpus 4 \ --memory "size=512M" \ - --disk my-root-disk.img \ + --disk path=my-root-disk.img \ --kernel my-vmlinux.bin \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules root=/dev/vda3" \ --net tap=ich0,mac=a4:a1:c2:00:00:01,ip=192.168.4.2,mask=255.255.255.0 \ diff --git a/docs/vfio.md b/docs/vfio.md index 9ddea9691..f33f44752 100644 --- a/docs/vfio.md +++ b/docs/vfio.md @@ -66,7 +66,7 @@ takes the device's sysfs path as an argument. In our example it is ``` ./target/debug/cloud-hypervisor \ --kernel ~/vmlinux \ - --disk ~/clear-29160-kvm.img \ + --disk path=~/clear-29160-kvm.img \ --console off \ --serial tty \ --cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda3" \ diff --git a/src/main.rs b/src/main.rs index 14dac552a..f81d98aa6 100755 --- a/src/main.rs +++ b/src/main.rs @@ -122,7 +122,10 @@ fn main() { .arg( Arg::with_name("disk") .long("disk") - .help("Path to VM disk image") + .help( + "Disk parameters \"path=,\ + iommu=on|off\"", + ) .takes_value(true) .min_values(1) .group("vm-config"), @@ -1015,16 +1018,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--serial", "tty", "--console", "off"]) @@ -1065,16 +1068,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .spawn() @@ -1103,16 +1106,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .spawn() @@ -1141,16 +1144,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .spawn() @@ -1182,16 +1185,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .spawn() @@ -1235,16 +1238,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--cmdline", "root=PARTUUID=19866ecd-ecc4-4ef8-b313-09a92260ef9b console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"]) @@ -1294,16 +1297,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--cmdline", "root=PARTUUID=19866ecd-ecc4-4ef8-b313-09a92260ef9b console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"]) @@ -1361,16 +1364,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&[ "--vhost-user-net", @@ -1423,16 +1426,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -1513,11 +1516,11 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -1563,16 +1566,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .spawn() @@ -1634,16 +1637,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -1759,16 +1762,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -1820,7 +1823,12 @@ mod tests { .args(&["--cpus", "1"]) .args(&["--memory", "size=512M"]) .args(&["--kernel", kernel_path.to_str().unwrap()]) - .args(&["--disk", guest.disk_config.disk(DiskType::CloudInit).unwrap().as_str()]) + .args(&["--disk", + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str()]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ "--pmem", @@ -1861,16 +1869,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&[ "--net", @@ -1914,16 +1922,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--serial", "off"]) @@ -1975,16 +1983,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--serial", "null"]) @@ -2036,16 +2044,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--serial", "tty"]) @@ -2099,16 +2107,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -2162,16 +2170,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--console", "tty"]) @@ -2222,16 +2230,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&[ @@ -2416,16 +2424,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--cmdline", "root=PARTUUID=19866ecd-ecc4-4ef8-b313-09a92260ef9b console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw acpi=off"]) @@ -2478,16 +2486,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--serial", "tty", "--console", "off"]) @@ -2549,16 +2557,16 @@ mod tests { .args(&["--kernel", kernel_path.to_str().unwrap()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--cmdline", "root=PARTUUID=19866ecd-ecc4-4ef8-b313-09a92260ef9b console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"]) @@ -2615,16 +2623,16 @@ mod tests { .args(&["--kernel", guest.fw_path.as_str()]) .args(&[ "--disk", - guest - .disk_config - .disk(DiskType::OperatingSystem) - .unwrap() - .as_str(), - guest - .disk_config - .disk(DiskType::CloudInit) - .unwrap() - .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::OperatingSystem).unwrap() + ) + .as_str(), + format!( + "path={}", + guest.disk_config.disk(DiskType::CloudInit).unwrap() + ) + .as_str(), ]) .args(&["--net", guest.default_net_string().as_str()]) .args(&["--vsock", format!("cid=3,sock={}", sock).as_str()]) diff --git a/test_data/cloud-init/clear/openstack/latest/user_data b/test_data/cloud-init/clear/openstack/latest/user_data index ea38d5c4d..6ce86b455 100644 --- a/test_data/cloud-init/clear/openstack/latest/user_data +++ b/test_data/cloud-init/clear/openstack/latest/user_data @@ -53,4 +53,4 @@ write_files: bash -c "echo 0000:00:03.0 > /sys/bus/pci/devices/0000\:00\:03.0/driver/unbind" bash -c "echo 1af4 1041 > /sys/bus/pci/drivers/vfio-pci/new_id" - /mnt/cloud-hypervisor --console off --serial tty --kernel /mnt/vmlinux --cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda2 VFIOTAG" --disk /mnt/clear-cloudguest.img /mnt/cloudinit.img --cpus 1 --memory size=512M --rng --device /sys/bus/pci/devices/0000:00:03.0/ + /mnt/cloud-hypervisor --console off --serial tty --kernel /mnt/vmlinux --cmdline "console=ttyS0 reboot=k panic=1 nomodules i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd root=/dev/vda2 VFIOTAG" --disk path=/mnt/clear-cloudguest.img path=/mnt/cloudinit.img --cpus 1 --memory size=512M --rng --device /sys/bus/pci/devices/0000:00:03.0/ diff --git a/vmm/src/api/openapi/cloud-hypervisor.yaml b/vmm/src/api/openapi/cloud-hypervisor.yaml index b4af1018d..ffb3239c7 100644 --- a/vmm/src/api/openapi/cloud-hypervisor.yaml +++ b/vmm/src/api/openapi/cloud-hypervisor.yaml @@ -225,6 +225,9 @@ components: properties: path: type: string + iommu: + type: boolean + default: false NetConfig: required: diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 119b7cd72..dbb610437 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -75,6 +75,8 @@ pub enum Error<'a> { ParseVsockSockParam, /// Missing kernel configuration ValidateMissingKernelConfig, + /// Failed parsing iommu parameter for the device. + ParseDeviceIommu, } pub type Result<'a, T> = result::Result>; @@ -114,6 +116,20 @@ fn parse_size(size: &str) -> Result { Ok(res << shift) } +fn parse_iommu(iommu: &str) -> Result { + if !iommu.is_empty() { + let res = match iommu { + "on" => true, + "off" => false, + _ => return Err(Error::ParseDeviceIommu), + }; + + Ok(res) + } else { + Ok(false) + } +} + #[derive(Clone, Debug, Deserialize, Serialize)] pub struct CpusConfig(pub u8); @@ -210,12 +226,29 @@ impl CmdlineConfig { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct DiskConfig { pub path: PathBuf, + #[serde(default)] + pub iommu: bool, } impl DiskConfig { pub fn parse(disk: &str) -> Result { + // Split the parameters based on the comma delimiter + let params_list: Vec<&str> = disk.split(',').collect(); + + let mut path_str: &str = ""; + let mut iommu_str: &str = ""; + + for param in params_list.iter() { + if param.starts_with("path=") { + path_str = ¶m[5..]; + } else if param.starts_with("iommu=") { + iommu_str = ¶m[6..]; + } + } + Ok(DiskConfig { - path: PathBuf::from(disk), + path: PathBuf::from(path_str), + iommu: parse_iommu(iommu_str)?, }) } } @@ -679,13 +712,17 @@ impl VmConfig { } pub fn parse(vm_params: VmParams) -> Result { - let iommu = false; + let mut iommu = false; let mut disks: Option> = None; if let Some(disk_list) = &vm_params.disks { let mut disk_config_list = Vec::new(); for item in disk_list.iter() { - disk_config_list.push(DiskConfig::parse(item)?); + let disk_config = DiskConfig::parse(item)?; + if disk_config.iommu { + iommu = true; + } + disk_config_list.push(disk_config); } disks = Some(disk_config_list); }