diff options
author | Alyssa Ross <hi@alyssa.is> | 2020-05-22 00:34:09 +0000 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2020-06-15 09:37:34 +0000 |
commit | 54ab55f99cd593f71a9b572d23199101a48206ec (patch) | |
tree | 633e6f29a69e27db3947fa2b8a857a9ccc2ae638 /src | |
parent | e0e035c065fdfbbea1e734d137d87a2635dbd0fa (diff) | |
download | crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar.gz crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar.bz2 crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar.lz crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar.xz crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.tar.zst crosvm-54ab55f99cd593f71a9b572d23199101a48206ec.zip |
crosvm: add memfd server
Diffstat (limited to 'src')
-rw-r--r-- | src/crosvm.rs | 2 | ||||
-rw-r--r-- | src/linux.rs | 67 | ||||
-rw-r--r-- | src/main.rs | 6 |
3 files changed, 66 insertions, 9 deletions
diff --git a/src/crosvm.rs b/src/crosvm.rs index e6e7268..ab4429a 100644 --- a/src/crosvm.rs +++ b/src/crosvm.rs @@ -180,6 +180,7 @@ pub struct Config { pub vhost_net: bool, pub tap_fd: Vec<RawFd>, pub cid: Option<u64>, + pub wl_memfd: bool, pub wayland_socket_paths: BTreeMap<String, PathBuf>, pub remote_wayland_device_socket_path: Option<PathBuf>, pub wayland_dmabuf: bool, @@ -235,6 +236,7 @@ impl Default for Config { #[cfg(feature = "gpu")] gpu_parameters: None, software_tpm: false, + wl_memfd: false, wayland_socket_paths: BTreeMap::new(), remote_wayland_device_socket_path: None, wayland_dmabuf: false, diff --git a/src/linux.rs b/src/linux.rs index ee248a4..d5e12cd 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -5,8 +5,9 @@ use std::cmp::max; use std::collections::{BTreeMap, VecDeque}; use std::convert::TryFrom; +use std::env; use std::error::Error as StdError; -use std::ffi::CStr; +use std::ffi::{CStr, OsString}; use std::fmt::{self, Display}; use std::fs::{File, OpenOptions}; use std::io::{self, stdin, Read}; @@ -16,8 +17,9 @@ use std::net::Ipv4Addr; use std::num::NonZeroU8; use std::num::ParseIntError; use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; -use std::os::unix::net::UnixStream; +use std::os::unix::net::{UnixListener, UnixStream}; use std::path::{Path, PathBuf}; +use std::process; use std::ptr; use std::str; use std::sync::{Arc, Barrier}; @@ -42,6 +44,7 @@ use msg_socket::{MsgError, MsgReceiver, MsgResult, MsgSender, MsgSocket}; use net_util::{Error as NetError, MacAddress, Tap}; use remain::sorted; use resources::{Alloc, MmioType, SystemAllocator}; +use servers::MemfdServer; use sync::{Condvar, Mutex}; use sys_util::net::{UnixSeqpacket, UnixSeqpacketListener, UnlinkUnixSeqpacketListener}; @@ -63,8 +66,8 @@ use vm_control::{ use crate::{Config, DiskOption, Executable, SharedDir, SharedDirKind, TouchDeviceOption}; use arch::{ - self, LinuxArch, RunnableLinuxVm, SerialHardware, SerialParameters, VirtioDeviceStub, - VmComponents, VmImage, + self, LinuxArch, RunnableLinuxVm, SerialHardware, SerialParameters, ServerStub, + VirtioDeviceStub, VmComponents, VmImage, }; #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] @@ -407,6 +410,16 @@ fn simple_jail(cfg: &Config, policy: &str) -> Result<Option<Minijail>> { } type DeviceResult<T = VirtioDeviceStub> = std::result::Result<T, Error>; +type ServerResult<T = ServerStub> = std::result::Result<T, Error>; + +fn create_memfd_server(cfg: &Config, memfd_socket_path: &Path) -> ServerResult { + let sock = UnixListener::bind(&memfd_socket_path).map_err(Error::CreateSocket)?; + let server = MemfdServer::new(sock); + Ok(ServerStub { + server: Box::new(server), + jail: simple_jail(&cfg, "memfd_server")?, + }) +} fn create_block_device( cfg: &Config, @@ -461,7 +474,6 @@ fn create_rng_device(cfg: &Config) -> DeviceResult { fn create_tpm_device(cfg: &Config) -> DeviceResult { use std::ffi::CString; use std::fs; - use std::process; use sys_util::chown; let tpm_storage: PathBuf; @@ -756,12 +768,18 @@ fn create_gpu_device( fn create_wayland_device( cfg: &Config, + memfd_socket_path: Option<&Path>, vm_socket: VmMemoryControlRequestSocket, resource_bridge: Option<virtio::resource_bridge::ResourceRequestSocket>, memory_params: MemoryParams, ) -> DeviceResult { - let wayland_socket_dirs = cfg - .wayland_socket_paths + let mut wayland_socket_paths = cfg.wayland_socket_paths.clone(); + + if let Some(memfd_socket_path) = memfd_socket_path { + wayland_socket_paths.insert("__crosvm_memfd".to_string(), memfd_socket_path.into()); + } + + let wayland_socket_dirs = wayland_socket_paths .iter() .map(|(_name, path)| path.parent()) .collect::<Option<Vec<_>>>() @@ -778,7 +796,7 @@ fn create_wayland_device( None => Box::new( virtio::Wl::new(Params { - wayland_paths: cfg.wayland_socket_paths.clone(), + wayland_paths: wayland_socket_paths.clone(), vm_socket, resource_bridge, }) @@ -1076,6 +1094,7 @@ fn create_virtio_devices( vm: &mut Vm, resources: &mut SystemAllocator, _exit_evt: &EventFd, + memfd_socket_path: Option<&Path>, wayland_device_control_socket: VmMemoryControlRequestSocket, gpu_device_control_socket: VmMemoryControlRequestSocket, balloon_device_control_socket: BalloonControlResponseSocket, @@ -1171,6 +1190,7 @@ fn create_virtio_devices( devs.push(create_wayland_device( cfg, + memfd_socket_path, wayland_device_control_socket, wl_resource_bridge, mem_params, @@ -1279,6 +1299,7 @@ fn create_devices( vm: &mut Vm, resources: &mut SystemAllocator, exit_evt: &EventFd, + memfd_socket_path: Option<&Path>, control_sockets: &mut Vec<TaggedControlSocket>, wayland_device_control_socket: VmMemoryControlRequestSocket, gpu_device_control_socket: VmMemoryControlRequestSocket, @@ -1294,6 +1315,7 @@ fn create_devices( vm, resources, exit_evt, + memfd_socket_path, wayland_device_control_socket, gpu_device_control_socket, balloon_device_control_socket, @@ -1830,6 +1852,29 @@ pub fn run_config(cfg: Config) -> Result<()> { msg_socket::pair::<VmIrqResponse, VmIrqRequest>().map_err(Error::CreateSocket)?; control_sockets.push(TaggedControlSocket::VmIrq(ioapic_host_socket)); + let mut servers = vec![]; + let mut memfd_socket_path = None; + + if cfg.wl_memfd { + let mut sock_name = OsString::from("crosvm-"); + sock_name.push(process::id().to_string()); + sock_name.push("-memfd.sock"); + + memfd_socket_path = Some( + [ + env::var_os("XDG_RUNTIME_DIR").expect("XDG_RUNTIME_DIR not set"), + sock_name, + ] + .iter() + .collect::<PathBuf>(), + ); + + servers.push(create_memfd_server( + &cfg, + memfd_socket_path.as_ref().unwrap(), + )?); + } + let sandbox = cfg.sandbox; let linux = Arch::build_vm( components, @@ -1837,6 +1882,7 @@ pub fn run_config(cfg: Config) -> Result<()> { ioapic_device_control_socket, &cfg.serial_parameters, simple_jail(&cfg, "serial")?, + servers, |mem, mem_params, vm, sys_allocator, exit_evt| { create_devices( &cfg, @@ -1845,6 +1891,7 @@ pub fn run_config(cfg: Config) -> Result<()> { vm, sys_allocator, exit_evt, + memfd_socket_path.as_ref().map(Path::new), &mut control_sockets, wayland_device_control_socket, gpu_device_control_socket, @@ -1952,6 +1999,10 @@ fn run_control( drop_capabilities().map_err(Error::DropCapabilities)?; } + for server in &mut linux.servers { + server.activate(); + } + let mut vcpu_handles = Vec::with_capacity(linux.vcpus.len()); let vcpu_thread_barrier = Arc::new(Barrier::new(linux.vcpus.len() + 1)); let run_mode_arc = Arc::new(VcpuRunMode::default()); diff --git a/src/main.rs b/src/main.rs index 7ea2e01..87ecdb6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -829,7 +829,7 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument:: })?, ) } - + "wl-memfd" => cfg.wl_memfd = true, "wayland-sock" => { let mut components = value.unwrap().split(','); let path = @@ -1469,6 +1469,10 @@ Number of virtio-net virtual queue pairs. (default: 1) ", ), + Argument::flag( + "wl-memfd", + "Enable support for requesting memfds over virtio_wl.", + ), Argument::value( "wayland-sock", "PATH[,name=NAME]", |