diff options
-rw-r--r-- | devices/src/virtio/block.rs | 23 | ||||
-rw-r--r-- | src/linux.rs | 12 | ||||
-rw-r--r-- | src/main.rs | 8 | ||||
-rw-r--r-- | vm_control/src/lib.rs | 45 |
4 files changed, 59 insertions, 29 deletions
diff --git a/devices/src/virtio/block.rs b/devices/src/virtio/block.rs index bcf0cf1..e5b6c33 100644 --- a/devices/src/virtio/block.rs +++ b/devices/src/virtio/block.rs @@ -24,7 +24,7 @@ use sys_util::{ use data_model::{DataInit, Le16, Le32, Le64}; use msg_socket::{MsgReceiver, MsgSender}; -use vm_control::{VmControlResponseSocket, VmRequest, VmResponse}; +use vm_control::{DiskControlCommand, DiskControlResponseSocket, DiskControlResult}; use super::{ DescriptorChain, Queue, VirtioDevice, INTERRUPT_STATUS_CONFIG_CHANGED, @@ -663,24 +663,24 @@ impl<T: DiskFile> Worker<T> { used_count > 0 } - fn resize(&mut self, new_size: u64) -> VmResponse { + fn resize(&mut self, new_size: u64) -> DiskControlResult { if self.read_only { error!("Attempted to resize read-only block device"); - return VmResponse::Err(SysError::new(libc::EROFS)); + return DiskControlResult::Err(SysError::new(libc::EROFS)); } info!("Resizing block device to {} bytes", new_size); if let Err(e) = self.disk_image.set_len(new_size) { error!("Resizing disk failed! {}", e); - return VmResponse::Err(SysError::new(libc::EIO)); + return DiskControlResult::Err(SysError::new(libc::EIO)); } if let Ok(new_disk_size) = self.disk_image.seek(SeekFrom::End(0)) { let mut disk_size = self.disk_size.lock(); *disk_size = new_disk_size; } - VmResponse::Ok + DiskControlResult::Ok } fn signal_used_queue(&self) { @@ -699,7 +699,7 @@ impl<T: DiskFile> Worker<T> { &mut self, queue_evt: EventFd, kill_evt: EventFd, - control_socket: VmControlResponseSocket, + control_socket: DiskControlResponseSocket, ) { #[derive(PollToken)] enum Token { @@ -777,15 +777,10 @@ impl<T: DiskFile> Worker<T> { }; let resp = match req { - VmRequest::DiskResize { new_size, .. } => { + DiskControlCommand::Resize { new_size } => { needs_config_interrupt = true; self.resize(new_size) } - // Only DiskResize makes sense - fail any other requests - _ => { - error!("block device received unexpected VmRequest"); - VmResponse::Err(SysError::new(libc::EINVAL)) - } }; if let Err(e) = control_socket.send(&resp) { @@ -819,7 +814,7 @@ pub struct Block<T: DiskFile> { disk_size: Arc<Mutex<u64>>, avail_features: u64, read_only: bool, - control_socket: Option<VmControlResponseSocket>, + control_socket: Option<DiskControlResponseSocket>, } fn build_config_space(disk_size: u64) -> virtio_blk_config { @@ -845,7 +840,7 @@ impl<T: DiskFile> Block<T> { pub fn new( mut disk_image: T, read_only: bool, - control_socket: Option<VmControlResponseSocket>, + control_socket: Option<DiskControlResponseSocket>, ) -> SysResult<Block<T>> { let disk_size = disk_image.seek(SeekFrom::End(0))? as u64; if disk_size % SECTOR_SIZE != 0 { diff --git a/src/linux.rs b/src/linux.rs index 977f7bf..19cdf09 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -46,6 +46,7 @@ use sys_util::{ use sys_util::{GuestAddress, MemoryMapping, Protection}; use vhost; use vm_control::{ + DiskControlCommand, DiskControlRequestSocket, DiskControlResponseSocket, DiskControlResult, UsbControlSocket, VmControlRequestSocket, VmControlResponseSocket, VmRequest, VmResponse, VmRunMode, }; @@ -280,7 +281,7 @@ type DeviceResult<T = VirtioDeviceStub> = std::result::Result<T, Error>; fn create_block_device( cfg: &Config, disk: &DiskOption, - disk_device_socket: VmControlResponseSocket, + disk_device_socket: DiskControlResponseSocket, ) -> DeviceResult { // Special case '/proc/self/fd/*' paths. The FD is already open, just use it. let raw_image: File = if disk.path.parent() == Some(Path::new("/proc/self/fd")) { @@ -671,7 +672,7 @@ fn create_virtio_devices( _exit_evt: &EventFd, wayland_device_socket: VmControlRequestSocket, balloon_device_socket: UnixSeqpacket, - disk_device_sockets: &mut Vec<VmControlResponseSocket>, + disk_device_sockets: &mut Vec<DiskControlResponseSocket>, ) -> DeviceResult<Vec<VirtioDeviceStub>> { let mut devs = Vec::new(); @@ -771,7 +772,7 @@ fn create_devices( exit_evt: &EventFd, wayland_device_socket: VmControlRequestSocket, balloon_device_socket: UnixSeqpacket, - disk_device_sockets: &mut Vec<VmControlResponseSocket>, + disk_device_sockets: &mut Vec<DiskControlResponseSocket>, usb_provider: HostBackendDeviceProvider, ) -> DeviceResult<Vec<(Box<dyn PciDevice>, Option<Minijail>)>> { let stubs = create_virtio_devices( @@ -1136,7 +1137,8 @@ pub fn run_config(cfg: Config) -> Result<()> { let disk_count = cfg.disks.len(); for _ in 0..disk_count { let (disk_host_socket, disk_device_socket) = - msg_socket::pair::<VmRequest, VmResponse>().map_err(Error::CreateSocket)?; + msg_socket::pair::<DiskControlCommand, DiskControlResult>() + .map_err(Error::CreateSocket)?; disk_host_sockets.push(disk_host_socket); disk_device_sockets.push(disk_device_socket); } @@ -1207,7 +1209,7 @@ fn run_control( control_server_socket: Option<UnlinkUnixSeqpacketListener>, mut control_sockets: Vec<VmControlResponseSocket>, balloon_host_socket: UnixSeqpacket, - disk_host_sockets: &[VmControlRequestSocket], + disk_host_sockets: &[DiskControlRequestSocket], usb_control_socket: UsbControlSocket, sigchld_fd: SignalFd, _render_node_host: RenderNodeHost, diff --git a/src/main.rs b/src/main.rs index 9906e47..01c096b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,8 +27,8 @@ use sys_util::{ validate_raw_fd, warn, }; use vm_control::{ - MaybeOwnedFd, UsbControlCommand, UsbControlResult, VmControlRequestSocket, VmRequest, - VmResponse, + DiskControlCommand, MaybeOwnedFd, UsbControlCommand, UsbControlResult, VmControlRequestSocket, + VmRequest, VmResponse, }; use crate::argument::{print_help, set_arguments, Argument}; @@ -953,9 +953,9 @@ fn disk_cmd(mut args: std::env::Args) -> std::result::Result<(), ()> { } }; - VmRequest::DiskResize { + VmRequest::DiskCommand { disk_index, - new_size, + command: DiskControlCommand::Resize { new_size }, } } _ => { diff --git a/vm_control/src/lib.rs b/vm_control/src/lib.rs index 9e6cc85..b197e9b 100644 --- a/vm_control/src/lib.rs +++ b/vm_control/src/lib.rs @@ -92,6 +92,28 @@ impl Default for VmRunMode { } #[derive(MsgOnSocket, Debug)] +pub enum DiskControlCommand { + /// Resize a disk to `new_size` in bytes. + Resize { new_size: u64 }, +} + +impl Display for DiskControlCommand { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use self::DiskControlCommand::*; + + match self { + Resize { new_size } => write!(f, "disk_resize {}", new_size), + } + } +} + +#[derive(MsgOnSocket, Debug)] +pub enum DiskControlResult { + Ok, + Err(SysError), +} + +#[derive(MsgOnSocket, Debug)] pub enum UsbControlCommand { AttachDevice { bus: u8, @@ -133,7 +155,11 @@ impl Display for UsbControlResult { } } +pub type DiskControlRequestSocket = MsgSocket<DiskControlCommand, DiskControlResult>; +pub type DiskControlResponseSocket = MsgSocket<DiskControlResult, DiskControlCommand>; + pub type UsbControlSocket = MsgSocket<UsbControlCommand, UsbControlResult>; + pub type VmControlRequestSocket = MsgSocket<VmRequest, VmResponse>; pub type VmControlResponseSocket = MsgSocket<VmResponse, VmRequest>; @@ -162,9 +188,12 @@ pub enum VmRequest { height: u32, format: u32, }, - /// Resize a disk chosen by `disk_index` to `new_size` in bytes. + /// Send a command to a disk chosen by `disk_index`. /// `disk_index` is a 0-based count of `--disk`, `--rwdisk`, and `-r` command-line options. - DiskResize { disk_index: usize, new_size: u64 }, + DiskCommand { + disk_index: usize, + command: DiskControlCommand, + }, /// Command to use controller. UsbCommand(UsbControlCommand), } @@ -209,7 +238,7 @@ impl VmRequest { sys_allocator: &mut SystemAllocator, run_mode: &mut Option<VmRunMode>, balloon_host_socket: &UnixSeqpacket, - disk_host_sockets: &[MsgSocket<VmRequest, VmResponse>], + disk_host_sockets: &[DiskControlRequestSocket], usb_control_socket: &UsbControlSocket, ) -> VmResponse { match *self { @@ -274,15 +303,19 @@ impl VmRequest { Err(e) => VmResponse::Err(e), } } - VmRequest::DiskResize { disk_index, .. } => { + VmRequest::DiskCommand { + disk_index, + ref command, + } => { // Forward the request to the block device process via its control socket. if let Some(sock) = disk_host_sockets.get(disk_index) { - if let Err(e) = sock.send(self) { + if let Err(e) = sock.send(command) { error!("disk socket send failed: {}", e); VmResponse::Err(SysError::new(EINVAL)) } else { match sock.recv() { - Ok(result) => result, + Ok(DiskControlResult::Ok) => VmResponse::Ok, + Ok(DiskControlResult::Err(e)) => VmResponse::Err(e), Err(e) => { error!("disk socket recv failed: {}", e); VmResponse::Err(SysError::new(EINVAL)) |