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

Support additional image types #22

Merged
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
3 changes: 2 additions & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ as a virtual machine's data disk (`/dev/vdb`).
#### Arguments

- `path`: Path to the disk image file.
- `format`: Format of the disk image. Supported formats: raw, qcow2.

#### Example

This adds a virtio-blk device to a virtual machine which will be backed by a raw image at
`/Users/user/disk-image.raw`:

```
--device virtio-blk,path=/Users/user/disk-image.raw
--device virtio-blk,path=/Users/user/disk-image.raw,format=raw
```

### Networking
Expand Down
11 changes: 8 additions & 3 deletions src/cmdline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,13 @@ mod tests {
"--bootloader",
"efi,variable-store=/Users/user/bootloader,create",
"--device",
"virtio-blk,path=/Users/user/root.raw",
"virtio-blk,path=/Users/user/root.qcow2,format=qcow2",
"--device",
"virtio-rng",
"--device",
"virtio-serial,logFilePath=/Users/user/serial.log",
"--device",
"virtio-blk,path=/Users/user/data.raw",
"virtio-blk,path=/Users/user/data.raw,format=raw",
"--device",
"virtio-vsock,port=1024,socketURL=/Users/user/vsock1.sock,listen",
"--device",
Expand Down Expand Up @@ -299,6 +299,7 @@ mod tests {
.expect("expected 4th virtio device config");
if let VirtioDeviceConfig::Blk(blk) = blk {
assert_eq!(blk.path, PathBuf::from_str("/Users/user/data.raw").unwrap());
assert_eq!(blk.format, DiskImageFormat::Raw);
} else {
panic!("expected virtio-blk device as 4th device config argument");
}
Expand Down Expand Up @@ -330,7 +331,11 @@ mod tests {
.pop()
.expect("expected 1st virtio device config");
if let VirtioDeviceConfig::Blk(blk) = blk {
assert_eq!(blk.path, PathBuf::from_str("/Users/user/root.raw").unwrap());
assert_eq!(
blk.path,
PathBuf::from_str("/Users/user/root.qcow2").unwrap()
);
assert_eq!(blk.format, DiskImageFormat::Qcow2);
} else {
panic!("expected virtio-blk device as 1st device config argument");
}
Expand Down
37 changes: 34 additions & 3 deletions src/virtio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ use mac_address::MacAddress;

#[link(name = "krun-efi")]
extern "C" {
fn krun_add_disk(
fn krun_add_disk2(
ctx_id: u32,
c_block_id: *const c_char,
c_disk_path: *const c_char,
disk_format: u32,
read_only: bool,
) -> i32;
fn krun_add_vsock_port(ctx_id: u32, port: u32, c_filepath: *const c_char) -> i32;
Expand All @@ -27,6 +28,25 @@ extern "C" {
fn krun_set_console_output(ctx_id: u32, c_filepath: *const c_char) -> i32;
}

#[repr(u32)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DiskImageFormat {
Raw = 0,
Qcow2 = 1,
}

impl FromStr for DiskImageFormat {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"raw" => Ok(DiskImageFormat::Raw),
"qcow2" => Ok(DiskImageFormat::Qcow2),
tylerfanelli marked this conversation as resolved.
Show resolved Hide resolved
_ => Err(anyhow!("unsupported disk image format")),
}
}
}

/// Each virito device configures itself with krun differently. This is used by each virtio device
/// to set their respective configurations with libkrun.
pub trait KrunContextSet {
Expand Down Expand Up @@ -100,17 +120,21 @@ impl KrunContextSet for VirtioDeviceConfig {
pub struct BlkConfig {
/// Path of the file to store as the root disk.
pub path: PathBuf,

/// Format of the disk image.
pub format: DiskImageFormat,
}

impl FromStr for BlkConfig {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let args = args_parse(s.to_string(), "virtio-blk", Some(1))?;
let args = args_parse(s.to_string(), "virtio-blk", Some(2))?;

Ok(Self {
path: PathBuf::from_str(&val_parse(&args[0], "path")?)
.context("path argument not a valid path")?,
format: DiskImageFormat::from_str(val_parse(&args[1], "format")?.as_str())?,
})
}
}
Expand All @@ -125,7 +149,14 @@ impl KrunContextSet for BlkConfig {
let block_id_cstr = CString::new(basename).context("can't convert basename to cstring")?;
let path_cstr = path_to_cstring(&self.path)?;

if krun_add_disk(id, block_id_cstr.as_ptr(), path_cstr.as_ptr(), false) < 0 {
if krun_add_disk2(
id,
block_id_cstr.as_ptr(),
path_cstr.as_ptr(),
self.format as u32,
false,
) < 0
{
return Err(anyhow!(format!(
"unable to set virtio-blk disk for {}",
self.path.display()
Expand Down
Loading