diff --git a/devices/Cargo.toml b/devices/Cargo.toml index f4d53d4bcc..0b602aec28 100644 --- a/devices/Cargo.toml +++ b/devices/Cargo.toml @@ -66,7 +66,8 @@ sync = { path = "../common/sync" } system_api = { version = "*", optional = true } thiserror = "1.0.20" tpm2 = { path = "../tpm2", optional = true } -uuid = { version = "0.8.2" } +tracing = { path = "../tracing" } +uuid = { version = "0.8.2", features = [ "serde" ] } vhost = { path = "../vhost" } vmm_vhost = { path = "../third_party/vmm_vhost", features = ["vmm", "device", "vfio-device"] } virtio_sys = { path = "../virtio_sys" } @@ -87,8 +88,9 @@ vfio_sys = { path = "../vfio_sys" } [target.'cfg(windows)'.dependencies] broker_ipc = { path = "../broker_ipc" } chrono = "*" -tracing = { path = "../tracing" } +metrics = { path = "../metrics" } tube_transporter = { path = "../tube_transporter" } +win_util = { path = "../win_util"} winapi = "*" [dependencies.futures] diff --git a/devices/src/irqchip/x86_64.rs b/devices/src/irqchip/x86_64.rs index 430304cf05..be4ad6b0f3 100644 --- a/devices/src/irqchip/x86_64.rs +++ b/devices/src/irqchip/x86_64.rs @@ -192,6 +192,7 @@ impl DelayedIoApicIrqEvents { } } +#[cfg_attr(windows, allow(dead_code))] #[cfg(test)] /// This module contains tests that apply to any implementations of IrqChipX86_64 pub(super) mod tests { diff --git a/devices/src/pci/mod.rs b/devices/src/pci/mod.rs index 0054bdbb0e..e4c6f4d151 100644 --- a/devices/src/pci/mod.rs +++ b/devices/src/pci/mod.rs @@ -75,7 +75,7 @@ pub const PCI_VENDOR_ID_INTEL: u16 = 0x8086; pub const PCI_VENDOR_ID_REDHAT: u16 = 0x1b36; #[repr(u16)] -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq)] pub enum CrosvmDeviceId { Pit = 1, Pic = 2, @@ -118,7 +118,8 @@ impl TryFrom for CrosvmDeviceId { 14 => Ok(CrosvmDeviceId::DirectMmio), 15 => Ok(CrosvmDeviceId::DirectIo), 16 => Ok(CrosvmDeviceId::UserspaceIrqChip), - 17 => Ok(CrosvmDeviceId::Pflash), + 17 => Ok(CrosvmDeviceId::VmWatchdog), + 18 => Ok(CrosvmDeviceId::Pflash), _ => Err(base::Error::new(EINVAL)), } } diff --git a/devices/src/pci/msi.rs b/devices/src/pci/msi.rs index 22d1367387..ca980e9157 100644 --- a/devices/src/pci/msi.rs +++ b/devices/src/pci/msi.rs @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#![cfg_attr(windows, allow(dead_code))] + use base::{error, AsRawDescriptor, Event, RawDescriptor, Tube}; use bit_field::*; use data_model::DataInit; diff --git a/devices/src/serial.rs b/devices/src/serial.rs index 237830195f..0fd146d22f 100644 --- a/devices/src/serial.rs +++ b/devices/src/serial.rs @@ -12,8 +12,6 @@ use std::sync::Arc; use std::thread::{self}; use base::{error, Event, Result}; -#[cfg(windows)] -use base::{named_pipes, FileSync}; use crate::bus::BusAccessInfo; use crate::pci::CrosvmDeviceId; diff --git a/devices/src/serial/sys/windows.rs b/devices/src/serial/sys/windows.rs index d97b25d80f..1752ecdc60 100644 --- a/devices/src/serial/sys/windows.rs +++ b/devices/src/serial/sys/windows.rs @@ -8,9 +8,8 @@ use std::thread::{self, JoinHandle}; use std::time::Duration; use base::{ - error, - named_pipes::{self, PipeConnection}, - Event, EventToken, FileSync, RawDescriptor, Result, WaitContext, + error, named_pipes::PipeConnection, Event, EventToken, FileSync, RawDescriptor, Result, + WaitContext, }; use hypervisor::ProtectionType; @@ -117,7 +116,7 @@ impl SerialDevice for Serial { out: Option>, sync: Option>, out_timestamp: bool, - keep_rds: Vec, + _keep_rds: Vec, ) -> Serial { let system_params = SystemSerialParams { out_timestamp, @@ -137,9 +136,9 @@ impl SerialDevice for Serial { fn new_with_pipe( _protected_vm: ProtectionType, interrupt_evt: Event, - pipe_in: named_pipes::PipeConnection, - pipe_out: named_pipes::PipeConnection, - keep_rds: Vec, + pipe_in: PipeConnection, + pipe_out: PipeConnection, + _keep_rds: Vec, ) -> Serial { let system_params = SystemSerialParams { out_timestamp: false, @@ -238,8 +237,6 @@ mod tests { use super::*; use regex::Regex; - use std::sync::Arc; - use sync::Mutex; use crate::serial::tests::*; use crate::serial::*; diff --git a/devices/src/utils/event_loop.rs b/devices/src/utils/event_loop.rs index 740041ec06..2d596096dc 100644 --- a/devices/src/utils/event_loop.rs +++ b/devices/src/utils/event_loop.rs @@ -3,9 +3,7 @@ // found in the LICENSE file. use super::error::{Error, Result}; -use base::{ - error, warn, AsRawDescriptor, Descriptor, Event, EventType, RawDescriptor, WaitContext, -}; +use base::{error, warn, AsRawDescriptor, Descriptor, Event, EventType, WaitContext}; use std::collections::BTreeMap; use std::mem::drop; use std::sync::{Arc, Weak}; @@ -41,7 +39,7 @@ impl FailHandle for Option> { pub struct EventLoop { fail_handle: Option>, poll_ctx: Arc>, - handlers: Arc>>>, + handlers: Arc>>>, stop_evt: Event, } @@ -60,7 +58,7 @@ impl EventLoop { .and_then(|e| Ok((e.try_clone()?, e))) .map_err(Error::CreateEvent)?; - let fd_callbacks: Arc>>> = + let fd_callbacks: Arc>>> = Arc::new(Mutex::new(BTreeMap::new())); let poll_ctx: WaitContext = WaitContext::new() .and_then(|pc| { @@ -100,7 +98,7 @@ impl EventLoop { } let mut locked = fd_callbacks.lock(); - let weak_handler = match locked.get(&fd) { + let weak_handler = match locked.get(&Descriptor(fd)) { Some(cb) => cb.clone(), None => { warn!("callback for fd {} already removed", fd); @@ -127,7 +125,7 @@ impl EventLoop { if remove { let _ = poll_ctx.delete(&event.token); - let _ = locked.remove(&fd); + let _ = locked.remove(&Descriptor(fd)); } } } @@ -154,7 +152,7 @@ impl EventLoop { } self.handlers .lock() - .insert(descriptor.as_raw_descriptor(), handler); + .insert(Descriptor(descriptor.as_raw_descriptor()), handler); // This might fail due to epoll syscall. Check epoll_ctl(2). self.poll_ctx .add_for_event( @@ -176,7 +174,9 @@ impl EventLoop { self.poll_ctx .delete(descriptor) .map_err(Error::WaitContextDeleteDescriptor)?; - self.handlers.lock().remove(&descriptor.as_raw_descriptor()); + self.handlers + .lock() + .remove(&Descriptor(descriptor.as_raw_descriptor())); Ok(()) } diff --git a/devices/src/virtio/async_device.rs b/devices/src/virtio/async_device.rs index cd881ddf68..2c630aa9f7 100644 --- a/devices/src/virtio/async_device.rs +++ b/devices/src/virtio/async_device.rs @@ -4,6 +4,8 @@ //! Provides helpers that make it easier to process virtio queues on an async executor. +#![cfg_attr(windows, allow(dead_code))] + use anyhow::{bail, Context}; use async_task::Task; use base::warn; diff --git a/devices/src/virtio/balloon.rs b/devices/src/virtio/balloon.rs index 23d7d9f5d8..511cdba564 100644 --- a/devices/src/virtio/balloon.rs +++ b/devices/src/virtio/balloon.rs @@ -491,7 +491,7 @@ fn run_worker( &guest_address, len, #[cfg(windows)] - dynamic_mapping_tube, + &dynamic_mapping_tube, #[cfg(unix)] &mem, ) @@ -511,7 +511,7 @@ fn run_worker( &guest_address, len, #[cfg(windows)] - dynamic_mapping_tube, + &dynamic_mapping_tube, ) }, ); @@ -571,7 +571,7 @@ fn run_worker( /// Virtio device for memory balloon inflation/deflation. pub struct Balloon { - command_tube: Tube, + command_tube: Option, #[cfg(windows)] dynamic_mapping_tube: Option, inflate_tube: Option, @@ -616,7 +616,7 @@ impl Balloon { }; Ok(Balloon { - command_tube, + command_tube: Some(command_tube), #[cfg(windows)] dynamic_mapping_tube: Some(dynamic_mapping_tube), inflate_tube, @@ -662,7 +662,10 @@ impl Drop for Balloon { impl VirtioDevice for Balloon { fn keep_rds(&self) -> Vec { - let mut rds = vec![self.command_tube.as_raw_descriptor()]; + let mut rds = Vec::new(); + if let Some(command_tube) = &self.command_tube { + rds.push(command_tube.as_raw_descriptor()); + } if let Some(inflate_tube) = &self.inflate_tube { rds.push(inflate_tube.as_raw_descriptor()); } @@ -723,8 +726,10 @@ impl VirtioDevice for Balloon { let state = self.state.clone(); + // TODO(b/222588331): this relies on Tube::try_clone working + #[cfg(unix)] #[allow(deprecated)] - let command_tube = match self.command_tube.try_clone() { + let command_tube = match self.command_tube.as_ref().unwrap().try_clone() { Ok(tube) => tube, Err(e) => { error!("failed to clone command tube {:?}", e); @@ -732,6 +737,8 @@ impl VirtioDevice for Balloon { } }; #[cfg(windows)] + let command_tube = self.command_tube.take().unwrap(); + #[cfg(windows)] let mapping_tube = self.dynamic_mapping_tube.take().unwrap(); let inflate_tube = self.inflate_tube.take(); let worker_result = thread::Builder::new() diff --git a/devices/src/virtio/balloon/sys/unix.rs b/devices/src/virtio/balloon/sys/unix.rs index 060b28414b..d58314a0b9 100644 --- a/devices/src/virtio/balloon/sys/unix.rs +++ b/devices/src/virtio/balloon/sys/unix.rs @@ -34,15 +34,19 @@ pub(in crate::virtio::balloon) async fn send_adjusted_response_async( pub(in crate::virtio::balloon) fn send_adjusted_response_if_needed( state: &Arc>, - command_tube: &Tube, + command_tube: &Option, config: virtio_balloon_config, ) { let mut state = block_on(state.lock()); state.actual_pages = config.actual.to_native(); if state.failable_update && state.actual_pages == state.num_pages { state.failable_update = false; - if let Err(e) = send_adjusted_response(command_tube, state.num_pages) { - error!("Failed to send response {:?}", e); + if let Some(ref command_tube) = command_tube { + if let Err(e) = send_adjusted_response(command_tube, state.num_pages) { + error!("Failed to send response {:?}", e); + } + } else { + panic!("Command tube missing!"); } } } diff --git a/devices/src/virtio/balloon/sys/windows.rs b/devices/src/virtio/balloon/sys/windows.rs index 38ce278d33..82791eac94 100644 --- a/devices/src/virtio/balloon/sys/windows.rs +++ b/devices/src/virtio/balloon/sys/windows.rs @@ -6,9 +6,9 @@ use std::sync::Arc; use balloon_control::BalloonTubeResult; use base::{warn, Tube}; -use cros_async::{AsyncMutex, AsyncTube}; +use cros_async::{block_on, sync::Mutex as AsyncMutex, AsyncTube}; use vm_control::{VmMemoryRequest, VmMemoryResponse}; -use vm_memory::{GuestAddress, GuestMemory}; +use vm_memory::GuestAddress; use crate::virtio::balloon::virtio_balloon_config; use crate::virtio::balloon::{BalloonState, VIRTIO_BALLOON_PFN_SHIFT}; @@ -22,12 +22,12 @@ pub(in crate::virtio::balloon) fn send_adjusted_response( Ok(()) } -pub(in crate::virtio::balloon) async fn send_adjusted_response_if_needed( +pub(in crate::virtio::balloon) fn send_adjusted_response_if_needed( state: &Arc>, - _command_tube: &Tube, + _command_tube: &Option, config: virtio_balloon_config, ) { - let mut state = block_on(self.state.lock()); + let mut state = block_on(state.lock()); state.actual_pages = config.actual.to_native(); } @@ -45,7 +45,10 @@ pub(in crate::virtio::balloon) fn free_memory( len: u64, dynamic_mapping_tube: &Tube, ) { - let request = VmMemoryRequest::DynamicallyFreeMemoryRange { guest_address, len }; + let request = VmMemoryRequest::DynamicallyFreeMemoryRange { + guest_address: *guest_address, + size: len, + }; if let Err(e) = dynamic_mapping_tube.send(&request) { warn!( "Failed to send free memory request. Marking pages unused failed: {}, addr={}", @@ -61,8 +64,15 @@ pub(in crate::virtio::balloon) fn free_memory( } } -pub(in crate::virtio::balloon) fn reclaim_memory(guest_address: &GuestAddress, len: u64) { - let request = VmMemoryRequest::DynamicallyReclaimMemoryRange { guest_address, len }; +pub(in crate::virtio::balloon) fn reclaim_memory( + guest_address: &GuestAddress, + len: u64, + dynamic_mapping_tube: &Tube, +) { + let request = VmMemoryRequest::DynamicallyReclaimMemoryRange { + guest_address: *guest_address, + size: len, + }; if let Err(e) = dynamic_mapping_tube.send(&request) { warn!( "Failed to send reclaim memory request. Marking pages used failed: {}, addr={}", diff --git a/devices/src/virtio/block/block.rs b/devices/src/virtio/block/block.rs index f9b556fc5f..7c80bd151b 100644 --- a/devices/src/virtio/block/block.rs +++ b/devices/src/virtio/block/block.rs @@ -13,11 +13,11 @@ use std::thread; use std::time::Duration; use std::u32; +#[cfg(unix)] +use base::AsRawDescriptor; use base::Error as SysError; use base::Result as SysResult; -use base::{ - error, info, warn, AsRawDescriptor, Event, EventToken, RawDescriptor, Timer, Tube, WaitContext, -}; +use base::{error, info, warn, Event, EventToken, RawDescriptor, Timer, Tube, WaitContext}; use data_model::DataInit; use disk::DiskFile; @@ -140,7 +140,7 @@ fn deserialize_disk_id<'de, D: Deserializer<'de>>( Ok(Some(ret)) } -#[derive(Debug, Serialize, Deserialize, PartialEq, serde_keyvalue::FromKeyValues)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, serde_keyvalue::FromKeyValues)] #[serde(deny_unknown_fields)] pub struct DiskOption { pub path: PathBuf, @@ -657,6 +657,8 @@ impl VirtioDevice for Block { keep_rds.extend(disk_image.as_raw_descriptors()); } + // TODO: b/143318939 uncomment this when msgOnSocket is ported + #[cfg(unix)] if let Some(control_tube) = &self.control_tube { keep_rds.push(control_tube.as_raw_descriptor()); } @@ -1142,6 +1144,24 @@ mod tests { } ); + // io_concurrency + #[cfg(windows)] + { + let params = from_block_arg("/some/path.img,io_concurrency=4").unwrap(); + assert_eq!( + params, + DiskOption { + path: "/some/path.img".into(), + read_only: false, + sparse: true, + o_direct: false, + block_size: 512, + id: None, + io_concurrency: NonZeroU32::new(4).unwrap(), + } + ); + } + // id let params = from_block_arg("/some/path.img,id=DISK").unwrap(); assert_eq!( diff --git a/devices/src/virtio/iommu.rs b/devices/src/virtio/iommu.rs index da79f64e69..381ed04840 100644 --- a/devices/src/virtio/iommu.rs +++ b/devices/src/virtio/iommu.rs @@ -146,6 +146,7 @@ struct State { page_mask: u64, // Hot-pluggable PCI endpoints ranges // RangeInclusive: (start endpoint PCI address .. =end endpoint PCI address) + #[cfg_attr(windows, allow(dead_code))] hp_endpoints_ranges: Vec>, // All PCI endpoints that attach to certain IOMMU domain // key: endpoint PCI address diff --git a/devices/src/virtio/iommu/protocol.rs b/devices/src/virtio/iommu/protocol.rs index 93356f07d9..0a9f1bafc0 100644 --- a/devices/src/virtio/iommu/protocol.rs +++ b/devices/src/virtio/iommu/protocol.rs @@ -24,6 +24,7 @@ //! doc, "Arrays of sizes from 0 to 32 (inclusive) implement the Default trait //! if the element type allows it." +#![cfg_attr(windows, allow(dead_code))] #![allow(non_camel_case_types)] use data_model::{DataInit, Le16, Le32, Le64}; diff --git a/devices/src/virtio/iommu/sys/windows.rs b/devices/src/virtio/iommu/sys/windows.rs index eff13ae66d..1cb4c4ccb2 100644 --- a/devices/src/virtio/iommu/sys/windows.rs +++ b/devices/src/virtio/iommu/sys/windows.rs @@ -11,16 +11,16 @@ use cros_async::AsyncTube; use crate::virtio::iommu::{Result, State}; pub(in crate::virtio::iommu) async fn handle_command_tube( - state: &Rc>, - command_tube: AsyncTube, + _state: &Rc>, + _command_tube: AsyncTube, ) -> Result<()> { panic!("IOMMU is not supported on Windows"); } pub(in crate::virtio::iommu) async fn handle_translate_request( - state: &Rc>, - request_tube: Option, - response_tubes: Option>, + _state: &Rc>, + _request_tube: Option, + _response_tubes: Option>, ) -> Result<()> { // TODO nkgold (b/222588331): the below implementation assures AsyncTube::send is sync, where it // should be async (as it is on Windows). Once that's fixed there's no reason this function diff --git a/devices/src/virtio/mod.rs b/devices/src/virtio/mod.rs index 737381ccf1..3b197f23df 100644 --- a/devices/src/virtio/mod.rs +++ b/devices/src/virtio/mod.rs @@ -6,6 +6,7 @@ mod async_device; mod async_utils; +mod balloon; mod descriptor_utils; mod input; mod interrupt; @@ -27,6 +28,7 @@ pub mod resource_bridge; pub mod snd; pub mod vhost; +pub use self::balloon::*; pub use self::block::*; pub use self::console::*; pub use self::descriptor_utils::Error as DescriptorError; @@ -44,7 +46,6 @@ pub use self::virtio_device::*; pub use self::virtio_pci_device::*; cfg_if::cfg_if! { if #[cfg(unix)] { - mod balloon; mod p9; mod pmem; pub mod wl; @@ -54,7 +55,6 @@ cfg_if::cfg_if! { pub mod gpu; pub mod net; - pub use self::balloon::*; #[cfg(feature = "gpu")] pub use self::gpu::*; pub use self::iommu::sys::unix::vfio_wrapper; diff --git a/devices/src/virtio/queue.rs b/devices/src/virtio/queue.rs index dccfc98b1d..84b4af4c91 100644 --- a/devices/src/virtio/queue.rs +++ b/devices/src/virtio/queue.rs @@ -254,6 +254,11 @@ impl<'a, 'b> Iterator for AvailIter<'a, 'b> { #[derive(Clone)] /// A virtio queue's parameters. +/// +/// WARNING: it is NOT safe to clone and then use n>1 Queue(s) to interact with the same virtqueue. +/// That will prevent descriptor index tracking from being accurate, which can cause incorrect +/// interrupt masking. +/// TODO(b/201119859) drop Clone from this struct. pub struct Queue { /// The maximal size in elements offered by the device pub max_size: u16, @@ -773,6 +778,7 @@ mod tests { use super::super::Interrupt; use super::*; use crate::IrqLevelEvent; + use memoffset::offset_of; use std::convert::TryInto; use std::sync::atomic::AtomicUsize; use std::sync::Arc; @@ -879,10 +885,8 @@ mod tests { 10, ); - // Calculating the offset of used_event within Avail structure - #[allow(deref_nullptr)] - let used_event_offset: u64 = - unsafe { &(*(::std::ptr::null::())).used_event as *const _ as u64 }; + // Offset of used_event within Avail structure + let used_event_offset = offset_of!(Avail, used_event) as u64; let used_event_address = GuestAddress(AVAIL_OFFSET + used_event_offset); // Assume driver submit 0x100 req to device, @@ -955,10 +959,8 @@ mod tests { 10, ); - // Calculating the offset of used_event within Avail structure - #[allow(deref_nullptr)] - let used_event_offset: u64 = - unsafe { &(*(::std::ptr::null::())).used_event as *const _ as u64 }; + // Offset of used_event within Avail structure + let used_event_offset = offset_of!(Avail, used_event) as u64; let used_event_address = GuestAddress(AVAIL_OFFSET + used_event_offset); // Assume driver submit 0x100 req to device, diff --git a/devices/src/virtio/snd/vios_backend/mod.rs b/devices/src/virtio/snd/vios_backend/mod.rs index 3ce6ba8766..47e3beea55 100644 --- a/devices/src/virtio/snd/vios_backend/mod.rs +++ b/devices/src/virtio/snd/vios_backend/mod.rs @@ -81,7 +81,7 @@ pub struct Sound { impl VirtioDevice for Sound { fn keep_rds(&self) -> Vec { - self.vios_client.keep_fds() + self.vios_client.keep_rds() } fn device_type(&self) -> DeviceType { diff --git a/devices/src/virtio/snd/vios_backend/shm_streams.rs b/devices/src/virtio/snd/vios_backend/shm_streams.rs index 1044a938ae..8c551b2a3c 100644 --- a/devices/src/virtio/snd/vios_backend/shm_streams.rs +++ b/devices/src/virtio/snd/vios_backend/shm_streams.rs @@ -173,7 +173,7 @@ impl ShmStreamSource for VioSShmStreamSource { /// This list helps users of the ShmStreamSource enter Linux jails without /// closing needed file descriptors. fn keep_fds(&self) -> Vec { - self.vios_client.keep_fds() + self.vios_client.keep_rds() } } diff --git a/devices/src/virtio/snd/vios_backend/shm_vios.rs b/devices/src/virtio/snd/vios_backend/shm_vios.rs index 6345617e84..c7909c51a0 100644 --- a/devices/src/virtio/snd/vios_backend/shm_vios.rs +++ b/devices/src/virtio/snd/vios_backend/shm_vios.rs @@ -15,7 +15,7 @@ use data_model::{DataInit, VolatileMemory, VolatileMemoryError, VolatileSlice}; use std::collections::{HashMap, VecDeque}; use std::fs::File; use std::io::{Error as IOError, ErrorKind as IOErrorKind, IoSliceMut, Seek, SeekFrom}; -use std::os::unix::io::{AsRawFd, RawFd}; +use std::os::unix::io::RawFd; use std::path::Path; use std::sync::mpsc::{channel, Receiver, RecvError, Sender}; use std::sync::Arc; @@ -447,14 +447,14 @@ impl VioSClient { } /// Get a list of file descriptors used by the implementation. - pub fn keep_fds(&self) -> Vec { - let control_fd = self.control_socket.lock().as_raw_fd(); - let event_fd = self.event_socket.as_raw_fd(); + pub fn keep_rds(&self) -> Vec { + let control_desc = self.control_socket.lock().as_raw_descriptor(); + let event_desc = self.event_socket.as_raw_descriptor(); let recv_event = self.recv_event.as_raw_descriptor(); let event_notifier = self.event_notifier.as_raw_descriptor(); - let mut ret = vec![control_fd, event_fd, recv_event, event_notifier]; - ret.append(&mut self.tx.keep_fds()); - ret.append(&mut self.rx.keep_fds()); + let mut ret = vec![control_desc, event_desc, recv_event, event_notifier]; + ret.append(&mut self.tx.keep_rds()); + ret.append(&mut self.rx.keep_rds()); ret } @@ -747,7 +747,7 @@ impl IoBufferQueue { seq_socket_send(&self.socket, msg) } - fn keep_fds(&self) -> Vec { + fn keep_rds(&self) -> Vec { vec![ self.file.as_raw_descriptor(), self.socket.as_raw_descriptor(), diff --git a/devices/src/virtio/vhost/user/device/block/sys/windows.rs b/devices/src/virtio/vhost/user/device/block/sys/windows.rs index 3f0be7747d..646874b810 100644 --- a/devices/src/virtio/vhost/user/device/block/sys/windows.rs +++ b/devices/src/virtio/vhost/user/device/block/sys/windows.rs @@ -53,8 +53,8 @@ fn open_disk_file(disk_option: &DiskOption, take_write_lock: bool) -> anyhow::Re .context("Failed to open disk file") } -#[derive(FromArgs)] -#[argh(description = "")] +#[derive(FromArgs, Debug)] +#[argh(subcommand, name = "block", description = "")] pub struct Options { #[argh( option, @@ -64,19 +64,7 @@ pub struct Options { bootstrap: usize, } -pub fn start_device(program_name: &str, args: &[&str]) -> anyhow::Result<()> { - let opts = match Options::from_args(&[program_name], args) { - Ok(opts) => opts, - Err(e) => { - if e.status.is_err() { - bail!(e.output); - } else { - println!("{}", e.output); - } - return Ok(()); - } - }; - +pub fn start_device(opts: Options) -> anyhow::Result<()> { tracing::init(); let raw_transport_tube = opts.bootstrap as RawDescriptor; diff --git a/devices/src/virtio/vhost/user/device/handler.rs b/devices/src/virtio/vhost/user/device/handler.rs index c421cd0489..2087292fcb 100644 --- a/devices/src/virtio/vhost/user/device/handler.rs +++ b/devices/src/virtio/vhost/user/device/handler.rs @@ -90,6 +90,7 @@ use {base::clear_fd_flags, std::os::unix::io::AsRawFd}; pub struct CallEvent(Event); impl CallEvent { + #[cfg_attr(windows, allow(dead_code))] pub fn into_inner(self) -> Event { self.0 } @@ -226,6 +227,7 @@ impl Vring { } /// Performs the run loop for an already-constructed request handler. +#[cfg_attr(windows, allow(dead_code))] pub async fn run_handler(mut req_handler: SlaveReqHandler, ex: &Executor) -> Result<()> where S: VhostUserSlaveReqHandler, @@ -791,11 +793,14 @@ impl SharedMemoryMapper for VhostShmemMapper { mod tests { use super::*; + #[cfg(unix)] use std::sync::mpsc::channel; + #[cfg(unix)] use std::sync::Barrier; use anyhow::{anyhow, bail}; use data_model::DataInit; + #[cfg(unix)] use tempfile::{Builder, TempDir}; use crate::virtio::vhost::user::vmm::VhostUserHandler; diff --git a/devices/src/virtio/vhost/user/device/handler/sys/windows.rs b/devices/src/virtio/vhost/user/device/handler/sys/windows.rs index f1e3a85899..e4ab389f20 100644 --- a/devices/src/virtio/vhost/user/device/handler/sys/windows.rs +++ b/devices/src/virtio/vhost/user/device/handler/sys/windows.rs @@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -use std::fs::File; use std::mem::ManuallyDrop; -use std::sync::Arc; use anyhow::{Context, Result}; use base::named_pipes::{BlockingMode, FramingMode, PipeConnection}; @@ -13,15 +11,10 @@ use cros_async::{EventAsync, Executor}; use futures::FutureExt; use futures::{pin_mut, select}; use tube_transporter::{TubeTransferDataList, TubeTransporterReader}; -use vm_memory::GuestMemory; -use vmm_vhost::{Protocol, SlaveReqHandler}; +use vmm_vhost::SlaveReqHandler; -use crate::virtio::vhost::user::device::{ - handler::{ - CallEvent, DeviceRequestHandler, MappingInfo, VhostResult, VhostUserBackend, - VhostUserMemoryRegion, VhostUserRegularOps, - }, - listener::{VhostUserListener, VhostUserListenerTrait}, +use crate::virtio::vhost::user::device::handler::{ + CallEvent, DeviceRequestHandler, VhostUserRegularOps, }; pub type Doorbell = CallEvent; diff --git a/devices/src/virtio/vhost/user/device/listener/sys/windows.rs b/devices/src/virtio/vhost/user/device/listener/sys/windows.rs index e22f93da08..626750fd90 100644 --- a/devices/src/virtio/vhost/user/device/listener/sys/windows.rs +++ b/devices/src/virtio/vhost/user/device/listener/sys/windows.rs @@ -19,17 +19,17 @@ pub struct VhostUserListener; impl VhostUserListenerTrait for VhostUserListener { fn new( - path: &str, - max_num_queues: usize, - keep_rds: Option<&mut Vec>, + _path: &str, + _max_num_queues: usize, + _keep_rds: Option<&mut Vec>, ) -> anyhow::Result { todo!() } fn run_backend( self, - backend: Box, - ex: &Executor, + _backend: Box, + _ex: &Executor, ) -> Pin>>> { todo!() } diff --git a/devices/src/virtio/vhost/user/device/mod.rs b/devices/src/virtio/vhost/user/device/mod.rs index 0463fd9d8d..d5ebd66d91 100644 --- a/devices/src/virtio/vhost/user/device/mod.rs +++ b/devices/src/virtio/vhost/user/device/mod.rs @@ -38,7 +38,7 @@ cfg_if::cfg_if! { #[cfg(feature = "slirp")] mod net; #[cfg(feature = "slirp")] - pub use net::run_net_device; + pub use net::{run_net_device, Options as NetOptions}; #[cfg(feature = "slirp")] pub use net::sys::windows::NetBackendConfig; diff --git a/devices/src/virtio/vhost/user/device/net/sys/windows.rs b/devices/src/virtio/vhost/user/device/net/sys/windows.rs index f8b430c13e..ac7e14f959 100644 --- a/devices/src/virtio/vhost/user/device/net/sys/windows.rs +++ b/devices/src/virtio/vhost/user/device/net/sys/windows.rs @@ -7,7 +7,7 @@ use crate::virtio; use crate::virtio::net::MAX_BUFFER_SIZE; use crate::virtio::net::{process_rx, NetError}; use crate::virtio::vhost::user::device::handler::sys::windows::read_from_tube_transporter; -use crate::virtio::vhost::user::device::handler::{DeviceRequestHandler, Doorbell}; +use crate::virtio::vhost::user::device::handler::{sys::Doorbell, DeviceRequestHandler}; use crate::virtio::vhost::user::device::net::{ run_ctrl_queue, run_tx_queue, NetBackend, NET_EXECUTOR, }; @@ -93,7 +93,7 @@ async fn run_rx_queue( &mut overlapped_wrapper, ); if needs_interrupt { - call_evt.lock().signal_used_queue(queue.vector); + call_evt.lock().signal_used_queue(queue.vector()); } // There aren't any RX descriptors available for us to write packets to. Wait for the guest @@ -127,7 +127,7 @@ pub(in crate::virtio::vhost::user::device::net) fn start_queue anyhow::Result<()> { - let opts = match Options::from_args(&[program_name], args) { - Ok(opts) => opts, - Err(e) => { - if e.status.is_err() { - bail!(e.output); - } else { - println!("{}", e.output); - } - return Ok(()); - } - }; - +pub fn start_device(opts: Options) -> anyhow::Result<()> { // Get the Tubes from the TubeTransporter. Then get the "Config" from the bootstrap_tube // which will contain slirp settings. let raw_transport_tube = opts.bootstrap as RawDescriptor; @@ -253,7 +243,7 @@ pub fn run_device(program_name: &str, args: &[&str]) -> anyhow::Result<()> { let startup_args: CommonChildStartupArgs = bootstrap_tube.recv::().unwrap(); - common_child_setup(startup_args).unwrap(); + let _child_cleanup = common_child_setup(startup_args).unwrap(); let net_backend_config = bootstrap_tube.recv::().unwrap(); diff --git a/devices/src/virtio/vsock/vsock.rs b/devices/src/virtio/vsock/vsock.rs index 0f103223ae..98db1287eb 100644 --- a/devices/src/virtio/vsock/vsock.rs +++ b/devices/src/virtio/vsock/vsock.rs @@ -198,7 +198,7 @@ impl VirtioDevice for Vsock { }; self.kill_evt = Some(self_kill_evt); let host_guid = self.host_guid.clone(); - let guest_cid = self.guest_cid.clone(); + let guest_cid = self.guest_cid; let worker_result = thread::Builder::new() .name("userspace_virtio_vsock".to_string()) .spawn(move || { @@ -351,7 +351,7 @@ impl Worker { VsockError::CloneDescriptor(e) }) .map(base::Event)?; - let evt_async = EventAsync::new(h_evt, &ex).map_err(|e| { + let evt_async = EventAsync::new(h_evt, ex).map_err(|e| { error!("Could not create EventAsync."); VsockError::CreateEventAsync(e) })?; @@ -362,7 +362,7 @@ impl Worker { error!("Could not clone connection_event."); VsockError::CloneDescriptor(e) })?; - let connection_evt_async = EventAsync::new(connection_evt_clone, &ex).map_err(|e| { + let connection_evt_async = EventAsync::new(connection_evt_clone, ex).map_err(|e| { error!("Could not create EventAsync."); VsockError::CreateEventAsync(e) })?; @@ -428,7 +428,7 @@ impl Worker { let pipe_connection = &mut connection.pipe; let overlapped = &mut connection.overlapped; - let guest_port = connection.guest_port.clone(); + let guest_port = connection.guest_port; let buffer = &mut connection.buffer; match overlapped.get_h_event_ref() { @@ -533,19 +533,18 @@ impl Worker { break; } - let mut data = vec![0 as u8; len]; + let mut data = vec![0_u8; len]; if len > 0 { if let Err(e) = reader.read_exact(&mut data) { error!("vosck: failed to read data from tx packet: {:?}", e); } } - match process_packets_queue.send((header, data)).await { - Err(e) => error!( + if let Err(e) = process_packets_queue.send((header, data)).await { + error!( "Error while sending packet to queue, dropping packet: {:?}", e - ), - _ => {} + ) }; queue.add_used(&self.mem, index, 0); queue.trigger_interrupt(&self.mem, &*self.interrupt.borrow()); @@ -649,16 +648,15 @@ impl Worker { buffer, // The connection has just been made, so we haven't received // anything yet. - recv_cnt: 0 as usize, - prev_recv_cnt: 0 as usize, - tx_cnt: 0 as usize, + recv_cnt: 0_usize, + prev_recv_cnt: 0_usize, + tx_cnt: 0_usize, is_buffer_full: false, }; self.connections.write().unwrap().insert(port, connection); self.connection_event .write(0) // 0 is arbitrary - .expect(&format!( - "Failed to signal new connection event for vsock port {}.", port)); + .unwrap_or_else(|_| panic!("Failed to signal new connection event for vsock port {}.", port)); true } Err(e) => { @@ -801,7 +799,7 @@ impl Worker { let (send, recv) = mpsc::channel(CHANNEL_SIZE); let event_async = EventAsync::new( rx_queue_evt.try_clone().expect("Failed to clone event"), - &ex, + ex, ) .expect("Failed to set up the rx queue event"); futures.push( @@ -817,11 +815,8 @@ impl Worker { send }); // Try to send the packet. Do not block other ports if the queue is full. - match queue.try_send(packet) { - Err(e) => { - error!("Error sending packet to queue, dropping packet: {:?}", e) - } - _ => {} + if let Err(e) = queue.try_send(packet) { + error!("Error sending packet to queue, dropping packet: {:?}", e) } } SelectResult::Finished(_) => { @@ -846,7 +841,7 @@ impl Worker { ) -> PortPair { while let Some((header, mut data)) = packet_recv_queue.next().await { if !self - .handle_tx_packet(header, &mut data, send_queue, &mut rx_queue_evt, ex) + .handle_tx_packet(header, &data, send_queue, &mut rx_queue_evt, ex) .await { packet_recv_queue.close(); @@ -1284,7 +1279,7 @@ impl Worker { } } -fn get_pipe_name(guid: &String, pipe: u32) -> String { +fn get_pipe_name(guid: &str, pipe: u32) -> String { format!("\\\\.\\pipe\\{}\\vsock-{}", guid, pipe) }