From 11812a5bf92a9cd98c6ff2a9adf6a577f2ded091 Mon Sep 17 00:00:00 2001 From: Zihan Chen Date: Mon, 25 Jul 2022 16:54:13 -0700 Subject: [PATCH] crosvm: Make ballooning a compile time feature Balloon support can not be compiled out, and don't need to be disabled at run time. BUG=b:235887451 TEST=Guest has balloon device by default, does not have balloon device when disabled. Ballooning via cli functions by default, return not supported when running vm has ballooning compiled out. Change-Id: I737851496fe4c14cdbb69c48e6edf1ca9186c15a Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3786928 Tested-by: Zihan Chen Reviewed-by: Daniel Verkamp Commit-Queue: Zihan Chen --- Cargo.toml | 5 ++-- devices/Cargo.toml | 1 + devices/src/pci/coiommu.rs | 4 +-- devices/src/virtio/mod.rs | 2 ++ src/crosvm/cmdline.rs | 2 ++ src/crosvm/sys/unix.rs | 43 ++++++++++++++++++++------- src/crosvm/sys/unix/device_helpers.rs | 5 +++- src/main.rs | 8 ++++- vm_control/Cargo.toml | 1 + vm_control/src/lib.rs | 9 ++++-- 10 files changed, 62 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6af908c475..a9e2d07e4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -122,12 +122,13 @@ all-linux = [ win64 = [] audio = ["devices/audio"] audio_cras = ["devices/audio_cras"] +balloon = ["devices/balloon", "vm_control/balloon"] chromeos = ["base/chromeos", "audio_cras", "devices/chromeos"] composite-disk = ["protos/composite-disk", "protobuf", "disk/composite-disk"] crash-report = [] -default = ["audio", "gpu", "usb"] +default = ["audio", "balloon", "gpu", "usb"] default-no-sandbox = [] -direct = ["devices/direct", "arch/direct", "x86_64/direct"] +direct = ["balloon", "devices/direct", "arch/direct", "x86_64/direct"] ffmpeg = ["devices/ffmpeg"] gdb = ["gdbstub", "gdbstub_arch", "arch/gdb", "vm_control/gdb", "x86_64/gdb"] gfxstream = ["devices/gfxstream"] diff --git a/devices/Cargo.toml b/devices/Cargo.toml index 0b602aec28..9cb75842b1 100644 --- a/devices/Cargo.toml +++ b/devices/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [features] audio = [] audio_cras = ["libcras"] +balloon = [] chromeos = ["dbus", "protobuf", "system_api"] direct = [] gpu = ["gpu_display","rutabaga_gfx"] diff --git a/devices/src/pci/coiommu.rs b/devices/src/pci/coiommu.rs index 23d85d5276..28f57301f4 100644 --- a/devices/src/pci/coiommu.rs +++ b/devices/src/pci/coiommu.rs @@ -974,7 +974,7 @@ impl CoIommuDev { mem: GuestMemory, vfio_container: Arc>, device_tube: Tube, - unpin_tube: Tube, + unpin_tube: Option, endpoints: Vec, vcpu_count: u64, params: CoIommuParameters, @@ -1043,7 +1043,7 @@ impl CoIommuDev { pin_kill_evt: None, unpin_thread: None, unpin_kill_evt: None, - unpin_tube: Some(unpin_tube), + unpin_tube, ioevents, vfio_container, pinstate: Arc::new(Mutex::new(CoIommuPinState { diff --git a/devices/src/virtio/mod.rs b/devices/src/virtio/mod.rs index 3b197f23df..8195d23b15 100644 --- a/devices/src/virtio/mod.rs +++ b/devices/src/virtio/mod.rs @@ -6,6 +6,7 @@ mod async_device; mod async_utils; +#[cfg(feature = "balloon")] mod balloon; mod descriptor_utils; mod input; @@ -28,6 +29,7 @@ pub mod resource_bridge; pub mod snd; pub mod vhost; +#[cfg(feature = "balloon")] pub use self::balloon::*; pub use self::block::*; pub use self::console::*; diff --git a/src/crosvm/cmdline.rs b/src/crosvm/cmdline.rs index 13aa868cde..65678b8736 100644 --- a/src/crosvm/cmdline.rs +++ b/src/crosvm/cmdline.rs @@ -96,7 +96,9 @@ pub struct CrosvmCmdlineArgs { #[derive(FromArgs)] #[argh(subcommand)] pub enum CrossPlatformCommands { + #[cfg(feature = "balloon")] Balloon(BalloonCommand), + #[cfg(feature = "balloon")] BalloonStats(BalloonStatsCommand), Battery(BatteryCommand), #[cfg(feature = "composite-disk")] diff --git a/src/crosvm/sys/unix.rs b/src/crosvm/sys/unix.rs index 437dec0ada..e93b04f06c 100644 --- a/src/crosvm/sys/unix.rs +++ b/src/crosvm/sys/unix.rs @@ -27,12 +27,14 @@ use std::os::unix::prelude::OpenOptionsExt; use std::path::Path; use std::str::FromStr; use std::sync::{mpsc, Arc, Barrier}; +#[cfg(feature = "balloon")] use std::time::Duration; use std::process; #[cfg(all(target_arch = "x86_64", feature = "gdb"))] use std::thread; +#[cfg(feature = "balloon")] use devices::virtio::BalloonMode; use libc; @@ -114,9 +116,9 @@ fn create_virtio_devices( vm_evt_wrtube: &SendTube, gpu_device_tube: Tube, vhost_user_gpu_tubes: Vec<(Tube, Tube, Tube)>, - balloon_device_tube: Option, - balloon_inflate_tube: Option, - init_balloon_size: u64, + #[cfg(feature = "balloon")] balloon_device_tube: Option, + #[cfg(feature = "balloon")] balloon_inflate_tube: Option, + #[cfg(feature = "balloon")] init_balloon_size: u64, disk_device_tubes: &mut Vec, pmem_device_tubes: &mut Vec, map_request: Arc>>, @@ -386,6 +388,7 @@ fn create_virtio_devices( )?); } + #[cfg(feature = "balloon")] if let Some(balloon_device_tube) = balloon_device_tube { devs.push(create_balloon_device( cfg.protected_vm, @@ -589,8 +592,8 @@ fn create_devices( gpu_device_tube: Tube, // Tuple content: (host-side GPU tube, device-side GPU tube, device-side control tube). vhost_user_gpu_tubes: Vec<(Tube, Tube, Tube)>, - balloon_device_tube: Option, - init_balloon_size: u64, + #[cfg(feature = "balloon")] balloon_device_tube: Option, + #[cfg(feature = "balloon")] init_balloon_size: u64, disk_device_tubes: &mut Vec, pmem_device_tubes: &mut Vec, fs_device_tubes: &mut Vec, @@ -602,6 +605,7 @@ fn create_devices( iova_max_addr: &mut Option, ) -> DeviceResult, Option)>> { let mut devices: Vec<(Box, Option)> = Vec::new(); + #[cfg(feature = "balloon")] let mut balloon_inflate_tube: Option = None; if !cfg.vfio.is_empty() { let mut coiommu_attached_endpoints = Vec::new(); @@ -684,7 +688,10 @@ fn create_devices( bail!("Get rlimit failed"); } } - + #[cfg(feature = "balloon")] + let coiommu_tube: Option; + #[cfg(not(feature = "balloon"))] + let coiommu_tube: Option = None; if !coiommu_attached_endpoints.is_empty() { let vfio_container = VfioCommonSetup::vfio_get_container(IommuDevType::CoIommu, None as Option<&Path>) @@ -693,9 +700,14 @@ fn create_devices( Tube::pair().context("failed to create coiommu tube")?; control_tubes.push(TaggedControlTube::VmMemory(coiommu_host_tube)); let vcpu_count = cfg.vcpu_count.unwrap_or(1) as u64; - let (coiommu_tube, balloon_tube) = - Tube::pair().context("failed to create coiommu tube")?; - balloon_inflate_tube = Some(balloon_tube); + #[cfg(feature = "balloon")] + match Tube::pair() { + Ok((x, y)) => { + coiommu_tube = Some(x); + balloon_inflate_tube = Some(y); + } + Err(x) => return Err(x).context("failed to create coiommu tube"), + } let dev = CoIommuDev::new( vm.get_memory().clone(), vfio_container, @@ -721,8 +733,11 @@ fn create_devices( vm_evt_wrtube, gpu_device_tube, vhost_user_gpu_tubes, + #[cfg(feature = "balloon")] balloon_device_tube, + #[cfg(feature = "balloon")] balloon_inflate_tube, + #[cfg(feature = "balloon")] init_balloon_size, disk_device_tubes, pmem_device_tubes, @@ -1311,6 +1326,7 @@ where control_tubes.push(TaggedControlTube::VmMemory(host_control_tube)); } + #[cfg(feature = "balloon")] let (balloon_host_tube, balloon_device_tube) = if cfg.balloon { if let Some(ref path) = cfg.balloon_control { ( @@ -1446,6 +1462,7 @@ where (None, None) }; + #[cfg(feature = "balloon")] let init_balloon_size = components .memory_size .checked_sub(cfg.init_memory.map_or(components.memory_size, |m| { @@ -1531,7 +1548,9 @@ where &mut control_tubes, gpu_device_tube, vhost_user_gpu_tubes, + #[cfg(feature = "balloon")] balloon_device_tube, + #[cfg(feature = "balloon")] init_balloon_size, &mut disk_device_tubes, &mut pmem_device_tubes, @@ -1698,6 +1717,7 @@ where cfg, control_server_socket, control_tubes, + #[cfg(feature = "balloon")] balloon_host_tube, &disk_host_tubes, #[cfg(feature = "usb")] @@ -1877,7 +1897,7 @@ fn run_control( cfg: Config, control_server_socket: Option, mut control_tubes: Vec, - balloon_host_tube: Option, + #[cfg(feature = "balloon")] balloon_host_tube: Option, disk_host_tubes: &[Tube], #[cfg(feature = "usb")] usb_control_tube: Tube, vm_evt_rdtube: RecvTube, @@ -2067,6 +2087,7 @@ fn run_control( let mut exit_state = ExitState::Stop; let mut pvpanic_code = PvPanicCode::Unknown; + #[cfg(feature = "balloon")] let mut balloon_stats_id: u64 = 0; 'wait: loop { @@ -2194,7 +2215,9 @@ fn run_control( ), _ => request.execute( &mut run_mode_opt, + #[cfg(feature = "balloon")] balloon_host_tube.as_ref(), + #[cfg(feature = "balloon")] &mut balloon_stats_id, disk_host_tubes, &mut linux.pm, diff --git a/src/crosvm/sys/unix/device_helpers.rs b/src/crosvm/sys/unix/device_helpers.rs index ec156bd6cd..f76fe72e58 100644 --- a/src/crosvm/sys/unix/device_helpers.rs +++ b/src/crosvm/sys/unix/device_helpers.rs @@ -37,9 +37,11 @@ use devices::virtio::vhost::user::vmm::{ Wl as VhostUserWl, }; use devices::virtio::vhost::vsock::VhostVsockConfig; +#[cfg(feature = "balloon")] +use devices::virtio::BalloonMode; #[cfg(any(feature = "video-decoder", feature = "video-encoder"))] use devices::virtio::VideoBackendType; -use devices::virtio::{self, BalloonMode, VirtioDevice}; +use devices::virtio::{self, VirtioDevice}; use devices::IommuDevType; #[cfg(feature = "tpm")] use devices::SoftwareTpm; @@ -639,6 +641,7 @@ pub fn create_vinput_device( }) } +#[cfg(feature = "balloon")] pub fn create_balloon_device( protected_vm: ProtectionType, jail_config: &Option, diff --git a/src/main.rs b/src/main.rs index db48362f79..3b6ce75b10 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,8 +29,10 @@ use vm_control::{ do_modify_battery, do_usb_attach, do_usb_detach, do_usb_list, handle_request, vms_request, ModifyUsbResult, }, - BalloonControlCommand, DiskControlCommand, UsbControlResult, VmRequest, VmResponse, + DiskControlCommand, UsbControlResult, VmRequest, }; +#[cfg(feature = "balloon")] +use vm_control::{BalloonControlCommand, VmResponse}; use crate::sys::error_to_exit_code; use crate::sys::init_log; @@ -137,6 +139,7 @@ fn inject_gpe(cmd: cmdline::GpeCommand) -> std::result::Result<(), ()> { vms_request(&VmRequest::Gpe(cmd.gpe), cmd.socket_path) } +#[cfg(feature = "balloon")] fn balloon_vms(cmd: cmdline::BalloonCommand) -> std::result::Result<(), ()> { let command = BalloonControlCommand::Adjust { num_bytes: cmd.num_bytes, @@ -144,6 +147,7 @@ fn balloon_vms(cmd: cmdline::BalloonCommand) -> std::result::Result<(), ()> { vms_request(&VmRequest::BalloonCommand(command), cmd.socket_path) } +#[cfg(feature = "balloon")] fn balloon_stats(cmd: cmdline::BalloonStatsCommand) -> std::result::Result<(), ()> { let command = BalloonControlCommand::Stats {}; let request = &VmRequest::BalloonCommand(command); @@ -527,9 +531,11 @@ fn crosvm_main() -> Result { .map_err(|e| anyhow!("failed to initialize syslog: {}", e))?; match command { + #[cfg(feature = "balloon")] CrossPlatformCommands::Balloon(cmd) => { balloon_vms(cmd).map_err(|_| anyhow!("balloon subcommand failed")) } + #[cfg(feature = "balloon")] CrossPlatformCommands::BalloonStats(cmd) => { balloon_stats(cmd).map_err(|_| anyhow!("balloon_stats subcommand failed")) } diff --git a/vm_control/Cargo.toml b/vm_control/Cargo.toml index ba85755bbe..f2bd714fd4 100644 --- a/vm_control/Cargo.toml +++ b/vm_control/Cargo.toml @@ -5,6 +5,7 @@ authors = ["The Chromium OS Authors"] edition = "2021" [features] +balloon = [] gdb = ["gdbstub_arch"] [dependencies] diff --git a/vm_control/src/lib.rs b/vm_control/src/lib.rs index 7a53f77b67..921fc1c83f 100644 --- a/vm_control/src/lib.rs +++ b/vm_control/src/lib.rs @@ -39,6 +39,7 @@ use libc::{EINVAL, EIO, ENODEV, ENOTSUP, ERANGE}; use serde::{Deserialize, Serialize}; pub use balloon_control::BalloonStats; +#[cfg(feature = "balloon")] use balloon_control::{BalloonTubeCommand, BalloonTubeResult}; use base::{ @@ -844,8 +845,8 @@ impl VmRequest { pub fn execute( &self, run_mode: &mut Option, - balloon_host_tube: Option<&Tube>, - balloon_stats_id: &mut u64, + #[cfg(feature = "balloon")] balloon_host_tube: Option<&Tube>, + #[cfg(feature = "balloon")] balloon_stats_id: &mut u64, disk_host_tubes: &[Tube], pm: &mut Option>>, usb_control_tube: Option<&Tube>, @@ -920,6 +921,7 @@ impl VmRequest { } VmResponse::Ok } + #[cfg(feature = "balloon")] VmRequest::BalloonCommand(BalloonControlCommand::Adjust { num_bytes }) => { if let Some(balloon_host_tube) = balloon_host_tube { match balloon_host_tube.send(&BalloonTubeCommand::Adjust { @@ -933,6 +935,7 @@ impl VmRequest { VmResponse::Err(SysError::new(ENOTSUP)) } } + #[cfg(feature = "balloon")] VmRequest::BalloonCommand(BalloonControlCommand::Stats) => { if let Some(balloon_host_tube) = balloon_host_tube { // NB: There are a few reasons stale balloon stats could be left @@ -982,6 +985,8 @@ impl VmRequest { VmResponse::Err(SysError::new(ENOTSUP)) } } + #[cfg(not(feature = "balloon"))] + VmRequest::BalloonCommand(_) => VmResponse::Err(SysError::new(ENOTSUP)), VmRequest::DiskCommand { disk_index, ref command,