diff --git a/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs b/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs index 191cb54578..c1c8685c79 100644 --- a/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs +++ b/src/runtime-rs/crates/hypervisor/ch-config/src/ch_api.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: Apache-2.0 -use crate::{DeviceConfig, FsConfig, VmConfig}; +use crate::{DeviceConfig, DiskConfig, FsConfig, VmConfig}; use anyhow::{anyhow, Result}; use api_client::simple_api_full_command_and_response; @@ -69,6 +69,24 @@ pub async fn cloud_hypervisor_vm_stop(mut socket: UnixStream) -> Result Result> { + task::spawn_blocking(move || -> Result> { + let response = simple_api_full_command_and_response( + &mut socket, + "PUT", + "vm.add-disk", + Some(&serde_json::to_string(&blk_config)?), + ) + .map_err(|e| anyhow!(e))?; + + Ok(response) + }) + .await? +} + #[allow(dead_code)] pub async fn cloud_hypervisor_vm_device_add(mut socket: UnixStream) -> Result> { let device_config = DeviceConfig::default(); diff --git a/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs b/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs index e06832cbd1..d876b31093 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner_device.rs @@ -6,17 +6,21 @@ use super::inner::CloudHypervisorInner; use crate::device::DeviceType; +use crate::BlockConfig; use crate::HybridVsockConfig; use crate::ShareFsDeviceConfig; use crate::VmmState; use anyhow::{anyhow, Context, Result}; -use ch_config::ch_api::cloud_hypervisor_vm_fs_add; +use ch_config::ch_api::{cloud_hypervisor_vm_blockdev_add, cloud_hypervisor_vm_fs_add}; +use ch_config::DiskConfig; use ch_config::FsConfig; use safe_path::scoped_join; use std::convert::TryFrom; use std::path::PathBuf; const VIRTIO_FS: &str = "virtio-fs"; +const DEFAULT_DISK_QUEUES: usize = 1; +const DEFAULT_DISK_QUEUE_SIZE: u16 = 1024; impl CloudHypervisorInner { pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<()> { @@ -43,6 +47,7 @@ impl CloudHypervisorInner { match device { DeviceType::ShareFs(sharefs) => self.handle_share_fs_device(sharefs.config).await, DeviceType::HybridVsock(hvsock) => self.handle_hvsock_device(&hvsock.config).await, + DeviceType::Block(block) => self.handle_block_device(block.config).await, _ => Err(anyhow!("unhandled device: {:?}", device)), } } @@ -125,6 +130,37 @@ impl CloudHypervisorInner { Ok(()) } + async fn handle_block_device(&mut self, cfg: BlockConfig) -> Result<()> { + let socket = self + .api_socket + .as_ref() + .ok_or("missing socket") + .map_err(|e| anyhow!(e))?; + + let num_queues: usize = DEFAULT_DISK_QUEUES; + let queue_size: u16 = DEFAULT_DISK_QUEUE_SIZE; + + let block_config = DiskConfig { + path: Some(cfg.path_on_host.as_str().into()), + readonly: cfg.is_readonly, + num_queues, + queue_size, + ..Default::default() + }; + + let response = cloud_hypervisor_vm_blockdev_add( + socket.try_clone().context("failed to clone socket")?, + block_config, + ) + .await?; + + if let Some(detail) = response { + debug!(sl!(), "blockdev add response: {:?}", detail); + } + + Ok(()) + } + pub(crate) async fn get_shared_fs_devices(&mut self) -> Result>> { let pending_root_devices = self.pending_devices.take(); @@ -173,13 +209,13 @@ impl TryFrom for FsConfig { let num_queues: usize = if cfg.queue_num > 0 { cfg.queue_num as usize } else { - 1 + DEFAULT_DISK_QUEUES }; let queue_size: u16 = if cfg.queue_num > 0 { u16::try_from(cfg.queue_size)? } else { - 1024 + DEFAULT_DISK_QUEUE_SIZE }; let socket_path = if cfg.sock_path.starts_with('/') {