summary refs log tree commit diff
path: root/src/linux.rs
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2018-12-04 13:17:46 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-01-16 01:46:54 -0800
commit92f73d73d04bdc973fe89e2c1682a1c3cc03fe49 (patch)
tree8b9b52835951bb982ad3e5cc240b91f0dcacea3f /src/linux.rs
parent53429509833a8f1a227d977778069df93a4edd44 (diff)
downloadcrosvm-92f73d73d04bdc973fe89e2c1682a1c3cc03fe49.tar
crosvm-92f73d73d04bdc973fe89e2c1682a1c3cc03fe49.tar.gz
crosvm-92f73d73d04bdc973fe89e2c1682a1c3cc03fe49.tar.bz2
crosvm-92f73d73d04bdc973fe89e2c1682a1c3cc03fe49.tar.lz
crosvm-92f73d73d04bdc973fe89e2c1682a1c3cc03fe49.tar.xz
crosvm-92f73d73d04bdc973fe89e2c1682a1c3cc03fe49.tar.zst
crosvm-92f73d73d04bdc973fe89e2c1682a1c3cc03fe49.zip
devices: block: add resize VmControl request
This allows manual resizing of block devices at runtime via the command
line ('crosvm disk resize <index> <size>').  The virtio config interrupt
is asserted when the disk size changes so that the guest driver can
update the block device to the updated size.

Currently, there is no automatic policy for resizing disks - that will
be implemented in another change.  Additionally, this resize operation
just changes the size of the block device; the filesystem will need to
be resized by the guest (e.g. via the 'btrfs filesystem resize' command)
as a separate step either before (shrinking) or after (expanding) the
disk resize operation.

BUG=chromium:858815
TEST=Start crosvm with a control socket (-s) and resize the disk with
'crosvm disk resize' from another shell.

Change-Id: I01633a7af04bfbaffbd27b9227274406d2a2b9cb
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1394152
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'src/linux.rs')
-rw-r--r--src/linux.rs52
1 files changed, 45 insertions, 7 deletions
diff --git a/src/linux.rs b/src/linux.rs
index 35bb98f..1bca0bf 100644
--- a/src/linux.rs
+++ b/src/linux.rs
@@ -28,7 +28,7 @@ use byteorder::{ByteOrder, LittleEndian};
 use devices::{self, PciDevice, VirtioPciDevice};
 use io_jail::{self, Minijail};
 use kvm::*;
-use msg_socket::{MsgReceiver, MsgSender, UnlinkMsgSocket};
+use msg_socket::{MsgReceiver, MsgSender, MsgSocket, UnlinkMsgSocket};
 use net_util::{Error as NetError, Tap};
 use qcow::{self, ImageType, QcowFile};
 use sys_util;
@@ -211,6 +211,7 @@ fn create_virtio_devs(
     _exit_evt: &EventFd,
     wayland_device_socket: UnixDatagram,
     balloon_device_socket: UnixDatagram,
+    disk_device_sockets: &mut Vec<UnixDatagram>,
 ) -> std::result::Result<Vec<(Box<PciDevice + 'static>, Option<Minijail>)>, Box<error::Error>> {
     static DEFAULT_PIVOT_ROOT: &str = "/var/empty";
 
@@ -223,6 +224,8 @@ fn create_virtio_devs(
     }
 
     for disk in &cfg.disks {
+        let disk_device_socket = disk_device_sockets.remove(0);
+
         // Special case '/proc/self/fd/*' paths. The FD is already open, just use it.
         let mut raw_image: File = if disk.path.parent() == Some(Path::new("/proc/self/fd")) {
             if !disk.path.is_file() {
@@ -256,16 +259,24 @@ fn create_virtio_devs(
             ImageType::Raw => {
                 // Access as a raw block device.
                 Box::new(
-                    devices::virtio::Block::new(raw_image, disk.read_only)
-                        .map_err(Error::BlockDeviceNew)?,
+                    devices::virtio::Block::new(
+                        raw_image,
+                        disk.read_only,
+                        Some(disk_device_socket),
+                    )
+                    .map_err(Error::BlockDeviceNew)?,
                 )
             }
             ImageType::Qcow2 => {
                 // Valid qcow header present
                 let qcow_image = QcowFile::from(raw_image).map_err(Error::QcowDeviceCreate)?;
                 Box::new(
-                    devices::virtio::Block::new(qcow_image, disk.read_only)
-                        .map_err(Error::BlockDeviceNew)?,
+                    devices::virtio::Block::new(
+                        qcow_image,
+                        disk.read_only,
+                        Some(disk_device_socket),
+                    )
+                    .map_err(Error::BlockDeviceNew)?,
                 )
             }
         };
@@ -780,17 +791,43 @@ pub fn run_config(cfg: Config) -> Result<()> {
     let (balloon_host_socket, balloon_device_socket) =
         UnixDatagram::pair().map_err(Error::CreateSocket)?;
 
+    // Create one control socket per disk.
+    let mut disk_device_sockets = Vec::new();
+    let mut disk_host_sockets = Vec::new();
+    let disk_count = cfg.disks.len();
+    for _ in 0..disk_count {
+        let (disk_host_socket, disk_device_socket) =
+            UnixDatagram::pair().map_err(Error::CreateSocket)?;
+        disk_device_sockets.push(disk_device_socket);
+        let disk_host_socket = MsgSocket::<VmRequest, VmResponse>::new(disk_host_socket);
+        disk_host_sockets.push(disk_host_socket);
+    }
+
     let linux = Arch::build_vm(components, |m, e| {
-        create_virtio_devs(cfg, m, e, wayland_device_socket, balloon_device_socket)
+        create_virtio_devs(
+            cfg,
+            m,
+            e,
+            wayland_device_socket,
+            balloon_device_socket,
+            &mut disk_device_sockets,
+        )
     })
     .map_err(Error::BuildingVm)?;
-    run_control(linux, control_sockets, balloon_host_socket, sigchld_fd)
+    run_control(
+        linux,
+        control_sockets,
+        balloon_host_socket,
+        &disk_host_sockets,
+        sigchld_fd,
+    )
 }
 
 fn run_control(
     mut linux: RunnableLinuxVm,
     control_sockets: Vec<UnlinkMsgSocket<VmResponse, VmRequest>>,
     balloon_host_socket: UnixDatagram,
+    disk_host_sockets: &[MsgSocket<VmRequest, VmResponse>],
     sigchld_fd: SignalFd,
 ) -> Result<()> {
     // Paths to get the currently available memory and the low memory threshold.
@@ -1033,6 +1070,7 @@ fn run_control(
                                     &mut linux.resources,
                                     &mut running,
                                     &balloon_host_socket,
+                                    disk_host_sockets,
                                 );
                                 if let Err(e) = socket.send(&response) {
                                     error!("failed to send VmResponse: {:?}", e);