Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add krun_add_disk() method #217

Merged
merged 5 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,14 @@ Each variant generates a dynamic library with a different name (and ```soname```

* virtio-console
* virtio-vsock (specialized for TSI, Transparent Socket Impersonation)
* virtio-block

### libkrun

* virtio-fs
* virtio-balloon (only free-page reporting)
* virtio-rng

### libkrun-sev

* virtio-block

## Networking

In ```libkrun```, networking is implemented using a novel technique called **Transparent Socket Impersonation**, or **TSI**. This allows the VM to have network connectivity without a virtual interface (hence, ```virtio-net``` is not among the list of supported devices).
Expand Down
29 changes: 26 additions & 3 deletions include/libkrun.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ int32_t krun_set_vm_config(uint32_t ctx_id, uint8_t num_vcpus, uint32_t ram_mib)
int32_t krun_set_root(uint32_t ctx_id, const char *root_path);

/**
* DEPRECATED. Use krun_add_disk instead.
*
* Sets the path to the disk image that contains the file-system to be used as root for the microVM.
* The only supported image format is "raw". Only available in libkrun-SEV.
* The only supported image format is "raw".
*
* Arguments:
* "ctx_id" - the configuration context ID.
Expand All @@ -77,8 +79,10 @@ int32_t krun_set_root(uint32_t ctx_id, const char *root_path);
int32_t krun_set_root_disk(uint32_t ctx_id, const char *disk_path);

/**
* Sets the path to the disk image that contains the file-system to be used as a data partition for the microVM.
* The only supported image format is "raw". Only available in libkrun-SEV.
* DEPRECATED. Use krun_add_disk instead.
*
* Sets the path to the disk image that contains the file-system to be used as
* a data partition for the microVM. The only supported image format is "raw".
*
* Arguments:
* "ctx_id" - the configuration context ID.
Expand All @@ -90,6 +94,25 @@ int32_t krun_set_root_disk(uint32_t ctx_id, const char *disk_path);
*/
int32_t krun_set_data_disk(uint32_t ctx_id, const char *disk_path);

/**
* Adds a disk image to be used as a general partition for the microVM.
*
* This API is mutually exclusive with the deprecated krun_set_root_disk and
* krun_set_data_disk methods and must not be used together.
*
* Arguments:
* "ctx_id" - the configuration context ID.
* "block_id" - a null-terminated string representing the partition.
* "disk_path" - a null-terminated string representing the path leading to the disk image that
* contains the root file-system.
* "read_only" - whether the mount should be read-only. Required if the caller does not have
* write permissions (for disk images in /usr/share).
*
* Returns:
* Zero on success or a negative error number on failure.
*/
int32_t krun_add_disk(uint32_t ctx_id, const char *block_id, const char *disk_path, bool read_only);

/**
* NO LONGER SUPPORTED. DO NOT USE.
*
Expand Down
82 changes: 58 additions & 24 deletions src/libkrun/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ struct ContextConfig {
net_cfg: NetworkConfig,
mac: Option<[u8; 6]>,
#[cfg(feature = "blk")]
block_cfgs: Vec<BlockDeviceConfig>,
#[cfg(feature = "blk")]
root_block_cfg: Option<BlockDeviceConfig>,
#[cfg(feature = "blk")]
data_block_cfg: Option<BlockDeviceConfig>,
Expand Down Expand Up @@ -156,13 +158,13 @@ impl ContextConfig {
}

#[cfg(feature = "blk")]
fn set_root_block_cfg(&mut self, block_cfg: BlockDeviceConfig) {
self.root_block_cfg = Some(block_cfg);
fn add_block_cfg(&mut self, block_cfg: BlockDeviceConfig) {
self.block_cfgs.push(block_cfg);
}

#[cfg(feature = "blk")]
fn get_root_block_cfg(&self) -> Option<BlockDeviceConfig> {
self.root_block_cfg.clone()
fn set_root_block_cfg(&mut self, block_cfg: BlockDeviceConfig) {
self.root_block_cfg = Some(block_cfg);
}

#[cfg(feature = "blk")]
Expand All @@ -171,8 +173,20 @@ impl ContextConfig {
}

#[cfg(feature = "blk")]
fn get_data_block_cfg(&self) -> Option<BlockDeviceConfig> {
self.data_block_cfg.clone()
fn get_block_cfg(&self) -> Vec<BlockDeviceConfig> {
// For backwards compat, when cfgs is empty (the new API is not used), this needs to be
// root and then data, in that order. Also for backwards compat, root/data are setters and
// need to discard redundant calls. So we have simple setters above and fix up here.
//
// When the new API is used, this is simpler.
if self.block_cfgs.is_empty() {
[&self.root_block_cfg, &self.data_block_cfg]
.into_iter()
.filter_map(|cfg| cfg.clone())
.collect()
} else {
self.block_cfgs.clone()
}
}

fn set_net_cfg(&mut self, net_cfg: NetworkConfig) {
Expand Down Expand Up @@ -484,14 +498,47 @@ pub unsafe extern "C" fn krun_set_mapped_volumes(
#[allow(clippy::missing_safety_doc)]
#[no_mangle]
#[cfg(feature = "blk")]
pub unsafe extern "C" fn krun_set_root_disk(ctx_id: u32, c_disk_path: *const c_char) -> i32 {
pub unsafe extern "C" fn krun_add_disk(
ctx_id: u32,
c_block_id: *const c_char,
c_disk_path: *const c_char,
read_only: bool,
) -> i32 {
let disk_path = match CStr::from_ptr(c_disk_path).to_str() {
Ok(disk) => disk,
Err(_) => return -libc::EINVAL,
};

//let fs_id = "/dev/root".to_string();
//let shared_dir = root_path.to_string();
let block_id = match CStr::from_ptr(c_block_id).to_str() {
Ok(block_id) => block_id,
Err(_) => return -libc::EINVAL,
};

match CTX_MAP.lock().unwrap().entry(ctx_id) {
Entry::Occupied(mut ctx_cfg) => {
let cfg = ctx_cfg.get_mut();
let block_device_config = BlockDeviceConfig {
block_id: block_id.to_string(),
cache_type: CacheType::Writeback,
disk_image_path: disk_path.to_string(),
is_disk_read_only: read_only,
};
cfg.add_block_cfg(block_device_config);
}
Entry::Vacant(_) => return -libc::ENOENT,
}

KRUN_SUCCESS
}

#[allow(clippy::missing_safety_doc)]
#[no_mangle]
#[cfg(feature = "blk")]
pub unsafe extern "C" fn krun_set_root_disk(ctx_id: u32, c_disk_path: *const c_char) -> i32 {
let disk_path = match CStr::from_ptr(c_disk_path).to_str() {
Ok(disk) => disk,
Err(_) => return -libc::EINVAL,
};

match CTX_MAP.lock().unwrap().entry(ctx_id) {
Entry::Occupied(mut ctx_cfg) => {
Expand All @@ -501,7 +548,6 @@ pub unsafe extern "C" fn krun_set_root_disk(ctx_id: u32, c_disk_path: *const c_c
cache_type: CacheType::Writeback,
disk_image_path: disk_path.to_string(),
is_disk_read_only: false,
is_disk_root: true,
};
cfg.set_root_block_cfg(block_device_config);
}
Expand All @@ -520,9 +566,6 @@ pub unsafe extern "C" fn krun_set_data_disk(ctx_id: u32, c_disk_path: *const c_c
Err(_) => return -libc::EINVAL,
};

//let fs_id = "/dev/root".to_string();
//let shared_dir = root_path.to_string();

match CTX_MAP.lock().unwrap().entry(ctx_id) {
Entry::Occupied(mut ctx_cfg) => {
let cfg = ctx_cfg.get_mut();
Expand All @@ -531,7 +574,6 @@ pub unsafe extern "C" fn krun_set_data_disk(ctx_id: u32, c_disk_path: *const c_c
cache_type: CacheType::Writeback,
disk_image_path: disk_path.to_string(),
is_disk_read_only: false,
is_disk_root: false,
};
cfg.set_data_block_cfg(block_device_config);
}
Expand Down Expand Up @@ -1016,17 +1058,9 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 {
};

#[cfg(feature = "blk")]
if let Some(block_cfg) = ctx_cfg.get_root_block_cfg() {
if ctx_cfg.vmr.add_block_device(block_cfg).is_err() {
error!("Error configuring virtio-blk for root block");
return -libc::EINVAL;
}
}

#[cfg(feature = "blk")]
if let Some(block_cfg) = ctx_cfg.get_data_block_cfg() {
for block_cfg in ctx_cfg.get_block_cfg() {
if ctx_cfg.vmr.add_block_device(block_cfg).is_err() {
error!("Error configuring virtio-blk for data block");
error!("Error configuring virtio-blk for block");
return -libc::EINVAL;
}
}
Expand Down
1 change: 0 additions & 1 deletion src/vmm/src/vmm_config/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ pub struct BlockDeviceConfig {
pub cache_type: CacheType,
pub disk_image_path: String,
pub is_disk_read_only: bool,
pub is_disk_root: bool,
}

#[derive(Default)]
Expand Down
Loading