diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2018-12-04 13:17:46 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-01-16 01:46:54 -0800 |
commit | 92f73d73d04bdc973fe89e2c1682a1c3cc03fe49 (patch) | |
tree | 8b9b52835951bb982ad3e5cc240b91f0dcacea3f /src/linux.rs | |
parent | 53429509833a8f1a227d977778069df93a4edd44 (diff) | |
download | crosvm-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.rs | 52 |
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); |