summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2018-01-11 09:20:16 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-01-19 23:29:52 -0800
commit88624f890e7e2a09c122c89f397a4d796c7680fb (patch)
treee34d9467f5a290e4d3546ab62487ce3ad63fdeea
parent76968703ad9f5c4edb4c533026ee35b6bd54a3d2 (diff)
downloadcrosvm-88624f890e7e2a09c122c89f397a4d796c7680fb.tar
crosvm-88624f890e7e2a09c122c89f397a4d796c7680fb.tar.gz
crosvm-88624f890e7e2a09c122c89f397a4d796c7680fb.tar.bz2
crosvm-88624f890e7e2a09c122c89f397a4d796c7680fb.tar.lz
crosvm-88624f890e7e2a09c122c89f397a4d796c7680fb.tar.xz
crosvm-88624f890e7e2a09c122c89f397a4d796c7680fb.tar.zst
crosvm-88624f890e7e2a09c122c89f397a4d796c7680fb.zip
main: Allow qcow files to be used as disks
Using qcow to allow for growable disk. These will be used for user data.

Change-Id: Iefb54eb4255db2ea7693db0020c5f1429acd73fd
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/862629
Reviewed-by: Stephen Barber <smbarber@chromium.org>
-rw-r--r--Cargo.lock7
-rw-r--r--seccomp/x86_64/block_device.policy2
-rw-r--r--src/linux.rs23
-rw-r--r--src/main.rs16
4 files changed, 36 insertions, 12 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 954c1ed..2288301 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -46,11 +46,6 @@ version = "0.3.54"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
-name = "getopts"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
 name = "io_jail"
 version = "0.1.0"
 dependencies = [
@@ -108,7 +103,6 @@ name = "qcow"
 version = "0.1.0"
 dependencies = [
  "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
  "sys_util 0.1.0",
 ]
@@ -170,5 +164,4 @@ dependencies = [
 [metadata]
 "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
 "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
-"checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9"
 "checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0"
diff --git a/seccomp/x86_64/block_device.policy b/seccomp/x86_64/block_device.policy
index a72c622..55e50a3 100644
--- a/seccomp/x86_64/block_device.policy
+++ b/seccomp/x86_64/block_device.policy
@@ -6,6 +6,8 @@ close: 1
 dup: 1
 dup2: 1
 exit_group: 1
+fstat: 1
+ftruncate: 1
 futex: 1
 lseek: 1
 # Disallow mmap with PROT_EXEC set.  The syntax here doesn't allow bit
diff --git a/src/linux.rs b/src/linux.rs
index 4ac793f..6446972 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -22,11 +22,13 @@ use io_jail::{self, Minijail};
 use kernel_cmdline;
 use kernel_loader;
 use kvm::*;
+use qcow::{self, QcowFile};
 use sys_util::*;
 use sys_util;
 use vm_control::VmRequest;
 
 use Config;
+use DiskType;
 
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 use x86_64;
@@ -55,6 +57,7 @@ pub enum Error {
     NetDeviceNew(devices::virtio::NetError),
     NoVarEmpty,
     OpenKernel(PathBuf, io::Error),
+    QcowDeviceCreate(qcow::Error),
     RegisterBalloon(device_manager::Error),
     RegisterBlock(device_manager::Error),
     RegisterIrqfd(sys_util::Error),
@@ -112,6 +115,9 @@ impl fmt::Display for Error {
             &Error::OpenKernel(ref p, ref e) => {
                 write!(f, "failed to open kernel image {:?}: {}", p, e)
             }
+            &Error::QcowDeviceCreate(ref e) => {
+                write!(f, "failed to read qcow formatted file {:?}", e)
+            }
             &Error::RegisterBalloon(ref e) => {
                 write!(f, "error registering balloon device: {:?}", e)
             },
@@ -290,14 +296,23 @@ fn setup_mmio_bus(cfg: &Config,
     }
 
     for disk in &cfg.disks {
-        let disk_image = OpenOptions::new()
+        let mut raw_image = OpenOptions::new()
                             .read(true)
                             .write(disk.writable)
                             .open(&disk.path)
                             .map_err(|e| Error::Disk(e))?;
-
-        let block_box = Box::new(devices::virtio::Block::new(disk_image)
-                    .map_err(|e| Error::BlockDeviceNew(e))?);
+        let block_box: Box<devices::virtio::VirtioDevice> = match disk.disk_type {
+            DiskType::FlatFile => { // Access as a raw block device.
+                Box::new(devices::virtio::Block::new(raw_image)
+                    .map_err(|e| Error::BlockDeviceNew(e))?)
+            }
+            DiskType::Qcow => { // Valid qcow header present
+                let qcow_image = QcowFile::from(raw_image)
+                    .map_err(|e| Error::QcowDeviceCreate(e))?;
+                Box::new(devices::virtio::Block::new(qcow_image)
+                    .map_err(|e| Error::BlockDeviceNew(e))?)
+            }
+        };
         let jail = if cfg.multiprocess {
             let policy_path: PathBuf = cfg.seccomp_policy_dir.join("block_device.policy");
             Some(create_base_minijail(empty_root_path, &policy_path)?)
diff --git a/src/main.rs b/src/main.rs
index 68bdb67..4339336 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,6 +12,7 @@ extern crate kvm;
 extern crate x86_64;
 extern crate kernel_loader;
 extern crate byteorder;
+extern crate qcow;
 #[macro_use]
 extern crate sys_util;
 extern crate vm_control;
@@ -36,9 +37,15 @@ use vm_control::VmRequest;
 
 static SECCOMP_POLICY_DIR: &'static str = "/usr/share/policy/crosvm";
 
+enum DiskType {
+    FlatFile,
+    Qcow,
+}
+
 struct DiskOption {
     path: PathBuf,
     writable: bool,
+    disk_type: DiskType,
 }
 
 pub struct Config {
@@ -162,7 +169,7 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
                                       }
                                   })?)
         }
-        "root" | "disk" | "rwdisk" => {
+        "root" | "disk" | "rwdisk" | "qcow" | "rwqcow" => {
             let disk_path = PathBuf::from(value.unwrap());
             if !disk_path.exists() {
                 return Err(argument::Error::InvalidValue {
@@ -188,6 +195,11 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
                 .push(DiskOption {
                           path: disk_path,
                           writable: name.starts_with("rw"),
+                          disk_type: if name.ends_with("qcow") {
+                                  DiskType::Qcow
+                              } else {
+                                  DiskType::FlatFile
+                              },
                       });
         }
         "host_ip" => {
@@ -308,7 +320,9 @@ fn run_vm(args: std::env::Args) {
                                 "PATH",
                                 "Path to a root disk image. Like `--disk` but adds appropriate kernel command line option."),
           Argument::short_value('d', "disk", "PATH", "Path to a disk image."),
+          Argument::value("qcow", "PATH", "Path to a qcow2 disk image."),
           Argument::value("rwdisk", "PATH", "Path to a writable disk image."),
+          Argument::value("rwqcow", "PATH", "Path to a writable qcow2 disk image."),
           Argument::value("host_ip",
                           "IP",
                           "IP address to assign to host tap interface."),