crosvm: main - Allow read/write block devices

Add an option for allowing a writable disk.
Allow specifying multiple disks.
Don't assume the path to the root device, force the user to specify a
correct command line option.

Change-Id: I87dea1152e1f81c0cde45ad47e2c4cf0f187918e
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/569450
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
This commit is contained in:
Dylan Reid 2017-07-12 19:24:57 -07:00 committed by chrome-bot
parent 5ad8bc5e08
commit f463bc139d

View file

@ -20,6 +20,7 @@ extern crate virtio_sys;
use std::ffi::{CString, CStr};
use std::fmt;
use std::fs::File;
use std::fs::OpenOptions;
use std::io::{stdin, stdout};
use std::net;
use std::path::{Path, PathBuf};
@ -125,8 +126,13 @@ impl fmt::Display for Error {
type Result<T> = std::result::Result<T, Error>;
struct Config {
disk_path: Option<String>,
struct DiskOption<'a> {
path: &'a str,
writable: bool,
}
struct Config<'a> {
disks: Vec<DiskOption<'a>>,
vcpu_count: Option<u32>,
memory: Option<usize>,
kernel_image: File,
@ -234,8 +240,12 @@ fn run_config(cfg: Config) -> Result<()> {
let block_root = TempDir::new(&PathBuf::from("/tmp/block_root"))
.map_err(Error::BlockDeviceRootSetup)?;
if let Some(ref disk_path) = cfg.disk_path {
let disk_image = File::open(disk_path).map_err(|e| Error::Disk(e))?;
for disk in cfg.disks {
let disk_image = OpenOptions::new()
.read(true)
.write(disk.writable)
.open(disk.path)
.map_err(|e| Error::Disk(e))?;
let block_box = Box::new(hw::virtio::Block::new(disk_image)
.map_err(|e| Error::BlockDeviceNew(e))?);
@ -247,10 +257,6 @@ fn run_config(cfg: Config) -> Result<()> {
None
};
cmdline
.insert("root", "/dev/vda")
.map_err(Error::Cmdline)?;
device_manager.register_mmio(block_box, jail, &mut cmdline)
.map_err(Error::RegisterBlock)?;
}
@ -611,7 +617,17 @@ fn main() {
.short("d")
.long("disk")
.value_name("FILE")
.help("rootfs disk image")
.help("disk image")
.multiple(true)
.number_of_values(1)
.takes_value(true))
.arg(Arg::with_name("writable")
.short("w")
.long("writable")
.value_name("FILE")
.help("make disk image writable")
.multiple(true)
.number_of_values(1)
.takes_value(true))
.arg(Arg::with_name("cpus")
.short("c")
@ -677,8 +693,24 @@ fn main() {
}
}
("run", Some(matches)) => {
let mut disks = Vec::new();
matches.values_of("disk").map(|paths| {
disks.extend(paths.map(|ref p| {
DiskOption {
path: p,
writable: false,
}
}))
});
if let Some(write_paths) = matches.values_of("writable") {
for path in write_paths {
disks.iter_mut().find(|ref mut d| d.path == path).map(
|ref mut d| d.writable = true,
);
}
}
let config = Config {
disk_path: matches.value_of("disk").map(|s| s.to_string()),
disks: disks,
vcpu_count: matches.value_of("cpus").and_then(|v| v.parse().ok()),
memory: matches.value_of("memory").and_then(|v| v.parse().ok()),
kernel_image: File::open(matches.value_of("KERNEL").unwrap())