main, vmm: Add support for multiple --disk options

Store the list of disks in a Vec<PathBuf> and then iterate over that
when creating the block devices.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2019-05-22 14:56:22 +01:00
parent 52790424f2
commit a09f918adc
2 changed files with 47 additions and 45 deletions

View File

@ -35,7 +35,8 @@ fn main() {
Arg::with_name("disk")
.long("disk")
.help("Path to VM disk image")
.takes_value(true),
.takes_value(true)
.min_values(1),
)
.arg(
Arg::with_name("net")
@ -69,11 +70,11 @@ fn main() {
.expect("Missing argument: kernel");
let kernel_path = kernel_arg.as_path();
let disk_arg = cmd_arguments
.value_of("disk")
let disk_paths: Vec<PathBuf> = cmd_arguments
.values_of("disk")
.expect("Missing arguments on disk")
.map(PathBuf::from)
.expect("Missing argument: disk");
let disk_path = disk_arg.as_path();
.collect();
let cmdline = cmd_arguments
.value_of("cmdline")
@ -100,13 +101,13 @@ fn main() {
.unwrap_or(DEFAULT_MEMORY);
println!(
"Cloud Hypervisor Guest\n\tvCPUs: {}\n\tMemory: {} MB\n\tKernel: {:?}\n\tKernel cmdline: {}\n\tDisk: {:?}",
vcpus, memory, kernel_path, cmdline, disk_path
"Cloud Hypervisor Guest\n\tvCPUs: {}\n\tMemory: {} MB\n\tKernel: {:?}\n\tKernel cmdline: {}\n\tDisk(s): {:?}",
vcpus, memory, kernel_path, cmdline, disk_paths,
);
let vm_config = VmConfig::new(
kernel_path,
disk_path,
disk_paths,
rng_path,
cmdline,
net_params,

View File

@ -34,7 +34,7 @@ use std::fs::{File, OpenOptions};
use std::io::{self, stdout};
use std::net::Ipv4Addr;
use std::os::unix::io::{AsRawFd, RawFd};
use std::path::Path;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Barrier, Mutex};
use std::{result, str, thread};
use vm_allocator::SystemAllocator;
@ -290,7 +290,7 @@ impl Vcpu {
pub struct VmConfig<'a> {
kernel_path: &'a Path,
disk_path: &'a Path,
disk_paths: Vec<PathBuf>,
rng_path: Option<String>,
cmdline: cmdline::Cmdline,
cmdline_addr: GuestAddress,
@ -302,7 +302,7 @@ pub struct VmConfig<'a> {
impl<'a> VmConfig<'a> {
pub fn new(
kernel_path: &'a Path,
disk_path: &'a Path,
disk_paths: Vec<PathBuf>,
rng_path: Option<String>,
cmdline_str: String,
net_params: Option<String>,
@ -314,7 +314,7 @@ impl<'a> VmConfig<'a> {
Ok(VmConfig {
kernel_path,
disk_path,
disk_paths,
rng_path,
cmdline,
cmdline_addr: CMDLINE_OFFSET,
@ -420,41 +420,42 @@ impl DeviceManager {
let mut pci_root = PciRoot::new(None);
// Open block device path
let raw_img: File = OpenOptions::new()
.read(true)
.write(true)
.open(&vm_cfg.disk_path)
.map_err(DeviceManagerError::Disk)?;
for disk_path in &vm_cfg.disk_paths {
// Open block device path
let raw_img: File = OpenOptions::new()
.read(true)
.write(true)
.open(disk_path.as_path())
.map_err(DeviceManagerError::Disk)?;
// Add virtio-blk
let image_type =
qcow::detect_image_type(&raw_img).map_err(DeviceManagerError::DetectImageType)?;
let disk_path = vm_cfg.disk_path.to_path_buf();
let block = match image_type {
ImageType::Raw => {
let raw_img = vm_virtio::RawFile::new(raw_img);
let dev = vm_virtio::Block::new(raw_img, disk_path, false)
.map_err(DeviceManagerError::CreateVirtioBlock)?;
Box::new(dev) as Box<vm_virtio::VirtioDevice>
}
ImageType::Qcow2 => {
let qcow_img =
QcowFile::from(raw_img).map_err(DeviceManagerError::QcowDeviceCreate)?;
let dev = vm_virtio::Block::new(qcow_img, disk_path, false)
.map_err(DeviceManagerError::CreateVirtioBlock)?;
Box::new(dev) as Box<vm_virtio::VirtioDevice>
}
};
// Add virtio-blk
let image_type =
qcow::detect_image_type(&raw_img).map_err(DeviceManagerError::DetectImageType)?;
let block = match image_type {
ImageType::Raw => {
let raw_img = vm_virtio::RawFile::new(raw_img);
let dev = vm_virtio::Block::new(raw_img, disk_path.to_path_buf(), false)
.map_err(DeviceManagerError::CreateVirtioBlock)?;
Box::new(dev) as Box<vm_virtio::VirtioDevice>
}
ImageType::Qcow2 => {
let qcow_img =
QcowFile::from(raw_img).map_err(DeviceManagerError::QcowDeviceCreate)?;
let dev = vm_virtio::Block::new(qcow_img, disk_path.to_path_buf(), false)
.map_err(DeviceManagerError::CreateVirtioBlock)?;
Box::new(dev) as Box<vm_virtio::VirtioDevice>
}
};
DeviceManager::add_virtio_pci_device(
block,
memory.clone(),
allocator,
vm_fd,
&mut pci_root,
&mut mmio_bus,
)?;
DeviceManager::add_virtio_pci_device(
block,
memory.clone(),
allocator,
vm_fd,
&mut pci_root,
&mut mmio_bus,
)?;
}
// Add virtio-net if required
if let Some(net_params) = &vm_cfg.net_params {