runtime-rs: Add block device handling in cloud hypervisor

Add functions for adding a block device to a container for CH.

Fixes #6690

Signed-off-by: Chelsea Mafrica <chelsea.e.mafrica@intel.com>
This commit is contained in:
Chelsea Mafrica 2023-06-16 00:19:28 -07:00
parent 4e812009f5
commit a81ad3b587
2 changed files with 58 additions and 4 deletions

View File

@ -2,7 +2,7 @@
// //
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::{DeviceConfig, FsConfig, VmConfig}; use crate::{DeviceConfig, DiskConfig, FsConfig, VmConfig};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use api_client::simple_api_full_command_and_response; use api_client::simple_api_full_command_and_response;
@ -69,6 +69,24 @@ pub async fn cloud_hypervisor_vm_stop(mut socket: UnixStream) -> Result<Option<S
.await? .await?
} }
pub async fn cloud_hypervisor_vm_blockdev_add(
mut socket: UnixStream,
blk_config: DiskConfig,
) -> Result<Option<String>> {
task::spawn_blocking(move || -> Result<Option<String>> {
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)] #[allow(dead_code)]
pub async fn cloud_hypervisor_vm_device_add(mut socket: UnixStream) -> Result<Option<String>> { pub async fn cloud_hypervisor_vm_device_add(mut socket: UnixStream) -> Result<Option<String>> {
let device_config = DeviceConfig::default(); let device_config = DeviceConfig::default();

View File

@ -6,17 +6,21 @@
use super::inner::CloudHypervisorInner; use super::inner::CloudHypervisorInner;
use crate::device::DeviceType; use crate::device::DeviceType;
use crate::BlockConfig;
use crate::HybridVsockConfig; use crate::HybridVsockConfig;
use crate::ShareFsDeviceConfig; use crate::ShareFsDeviceConfig;
use crate::VmmState; use crate::VmmState;
use anyhow::{anyhow, Context, Result}; 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 ch_config::FsConfig;
use safe_path::scoped_join; use safe_path::scoped_join;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::path::PathBuf; use std::path::PathBuf;
const VIRTIO_FS: &str = "virtio-fs"; const VIRTIO_FS: &str = "virtio-fs";
const DEFAULT_DISK_QUEUES: usize = 1;
const DEFAULT_DISK_QUEUE_SIZE: u16 = 1024;
impl CloudHypervisorInner { impl CloudHypervisorInner {
pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<()> { pub(crate) async fn add_device(&mut self, device: DeviceType) -> Result<()> {
@ -43,6 +47,7 @@ impl CloudHypervisorInner {
match device { match device {
DeviceType::ShareFs(sharefs) => self.handle_share_fs_device(sharefs.config).await, DeviceType::ShareFs(sharefs) => self.handle_share_fs_device(sharefs.config).await,
DeviceType::HybridVsock(hvsock) => self.handle_hvsock_device(&hvsock.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)), _ => Err(anyhow!("unhandled device: {:?}", device)),
} }
} }
@ -125,6 +130,37 @@ impl CloudHypervisorInner {
Ok(()) 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<Option<Vec<FsConfig>>> { pub(crate) async fn get_shared_fs_devices(&mut self) -> Result<Option<Vec<FsConfig>>> {
let pending_root_devices = self.pending_devices.take(); let pending_root_devices = self.pending_devices.take();
@ -173,13 +209,13 @@ impl TryFrom<ShareFsSettings> for FsConfig {
let num_queues: usize = if cfg.queue_num > 0 { let num_queues: usize = if cfg.queue_num > 0 {
cfg.queue_num as usize cfg.queue_num as usize
} else { } else {
1 DEFAULT_DISK_QUEUES
}; };
let queue_size: u16 = if cfg.queue_num > 0 { let queue_size: u16 = if cfg.queue_num > 0 {
u16::try_from(cfg.queue_size)? u16::try_from(cfg.queue_size)?
} else { } else {
1024 DEFAULT_DISK_QUEUE_SIZE
}; };
let socket_path = if cfg.sock_path.starts_with('/') { let socket_path = if cfg.sock_path.starts_with('/') {