From bf8f55e6c8c8a92e794963de8b874c1cbab61db0 Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Sat, 1 Nov 2025 15:16:57 +0100 Subject: [PATCH 1/4] Add "disk_image" as a positional argument Add "disk_image" as an optional positional argument. If present, this is attached to the VM as a virtio-blk device. Signed-off-by: Sergio Lopez --- src/cmdline.rs | 3 +++ src/context.rs | 24 +++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/cmdline.rs b/src/cmdline.rs index a5bc57e..066917d 100644 --- a/src/cmdline.rs +++ b/src/cmdline.rs @@ -59,6 +59,9 @@ pub struct Args { /// Path of log file #[arg(long = "log-file")] pub log_file: Option, + + /// Disk image for easy mode. + pub disk_image: Option, } /// Parse the input string into a hash map of key value pairs, associating the argument with its diff --git a/src/context.rs b/src/context.rs index 3cad6fd..6ff3dd1 100644 --- a/src/context.rs +++ b/src/context.rs @@ -4,7 +4,7 @@ use super::*; use crate::{ status::{get_shutdown_eventfd, status_listener, RestfulUri}, - virtio::KrunContextSet, + virtio::{DiskImageFormat, KrunContextSet}, }; use std::os::fd::{AsRawFd, RawFd}; @@ -20,6 +20,13 @@ use env_logger::{Builder, Env, Target}; #[link(name = "krun-efi")] extern "C" { + 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_create_ctx() -> i32; fn krun_init_log(target: RawFd, level: u32, style: u32, options: u32) -> i32; fn krun_set_gpu_options2(ctx_id: u32, virgl_flags: u32, shm_size: u64) -> i32; @@ -141,6 +148,21 @@ impl TryFrom for KrunContext { return Err(anyhow!("unable to set krun vCPU/RAM configuration")); } + if let Some(ref disk_image) = args.disk_image { + if unsafe { + krun_add_disk2( + id, + CString::new("root").unwrap().as_ptr(), + CString::new(disk_image.clone()).unwrap().as_ptr(), + DiskImageFormat::Raw as u32, + false, + ) + } < 0 + { + return Err(anyhow!("error configuring disk image")); + } + } + // Configure each virtio device to include in the VM. for device in &args.devices { unsafe { device.krun_ctx_set(id)? } From f06e47ba96d4e0d94e6a478d49733fe5e72ef95f Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Sat, 1 Nov 2025 15:20:58 +0100 Subject: [PATCH 2/4] Set default values for cpu and memory Set up some safe default values for both cpu and memory so they become optional arguments. Signed-off-by: Sergio Lopez --- src/cmdline.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmdline.rs b/src/cmdline.rs index 066917d..d7089af 100644 --- a/src/cmdline.rs +++ b/src/cmdline.rs @@ -17,11 +17,11 @@ use clap::Parser; #[command(version, about, long_about = None)] pub struct Args { /// Number of vCPUs for the VM. - #[arg(long, short)] + #[arg(long, short, default_value_t = 2)] pub cpus: u8, /// Amount of RAM available to VM. - #[arg(long, short)] + #[arg(long, short, default_value_t = 4096)] pub memory: u32, /// Bootloader configuration. From 3ad4185020b31aea998b824bb2e276021974822f Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Sat, 1 Nov 2025 15:42:50 +0100 Subject: [PATCH 3/4] Automatically spawn gvproxy --- src/context.rs | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/context.rs b/src/context.rs index 6ff3dd1..748e1c5 100644 --- a/src/context.rs +++ b/src/context.rs @@ -8,15 +8,18 @@ use crate::{ }; use std::os::fd::{AsRawFd, RawFd}; +use std::process::Command; use std::{convert::TryFrom, ptr, thread}; use std::{ - ffi::{c_char, CString}, + ffi::{c_char, c_int, CString}, fs::OpenOptions, io, + str::FromStr, }; use anyhow::{anyhow, Context}; use env_logger::{Builder, Env, Target}; +use mac_address::MacAddress; #[link(name = "krun-efi")] extern "C" { @@ -27,6 +30,14 @@ extern "C" { disk_format: u32, read_only: bool, ) -> i32; + fn krun_add_net_unixstream( + ctx_id: u32, + c_path: *const c_char, + fd: c_int, + c_mac: *const u8, + features: u32, + flags: u32, + ) -> i32; fn krun_create_ctx() -> i32; fn krun_init_log(target: RawFd, level: u32, style: u32, options: u32) -> i32; fn krun_set_gpu_options2(ctx_id: u32, virgl_flags: u32, shm_size: u64) -> i32; @@ -161,6 +172,37 @@ impl TryFrom for KrunContext { { return Err(anyhow!("error configuring disk image")); } + + match Command::new("gvproxy") + .arg("-listen-qemu") + .arg("unix:///tmp/gvproxy-krun.sock") + .spawn() + { + Ok(child) => { + println!("Process spawned successfully with PID: {}", child.id()); + unsafe { + if krun_add_net_unixstream( + id, + CString::new("/tmp/gvproxy-krun.sock").unwrap().as_ptr(), + -1, + MacAddress::from_str("56:c8:d4:db:e1:47") + .unwrap() + .bytes() + .as_ptr(), + 0, + 0, + ) < 0 + { + return Err(anyhow!(format!( + "virtio-net unable to configure default interface", + ))); + } + } + } + Err(e) => { + eprintln!("Failed to spawn process: {}", e); + } + } } // Configure each virtio device to include in the VM. From 7cbc4ccbd337578774ffa00c0062ec94f7261028 Mon Sep 17 00:00:00 2001 From: Sergio Lopez Date: Sat, 1 Nov 2025 15:53:17 +0100 Subject: [PATCH 4/4] autodetect disk image format --- src/context.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/context.rs b/src/context.rs index 748e1c5..1b80211 100644 --- a/src/context.rs +++ b/src/context.rs @@ -12,8 +12,8 @@ use std::process::Command; use std::{convert::TryFrom, ptr, thread}; use std::{ ffi::{c_char, c_int, CString}, - fs::OpenOptions, - io, + fs::{File, OpenOptions}, + io::{self, Read}, str::FromStr, }; @@ -68,6 +68,23 @@ pub const KRUN_LOG_STYLE_AUTO: u32 = 0; pub const KRUN_LOG_OPTION_ENV: u32 = 0; pub const KRUN_LOG_OPTION_NO_ENV: u32 = 1; +const QCOW_MAGIC: [u8; 4] = [0x51, 0x46, 0x49, 0xfb]; + +fn get_image_format(disk_image: String) -> Result { + let mut file = File::open(disk_image)?; + + let mut buffer = [0u8; 4]; + file.read_exact(&mut buffer)?; + + if buffer == QCOW_MAGIC { + println!("Image detected as Qcow2"); + Ok(DiskImageFormat::Qcow2) + } else { + println!("Image deteced as Raw"); + Ok(DiskImageFormat::Raw) + } +} + /// A wrapper of all data used to configure the krun VM. pub struct KrunContext { id: u32, @@ -160,12 +177,14 @@ impl TryFrom for KrunContext { } if let Some(ref disk_image) = args.disk_image { + let image_format = get_image_format(disk_image.to_string())?; + if unsafe { krun_add_disk2( id, CString::new("root").unwrap().as_ptr(), CString::new(disk_image.clone()).unwrap().as_ptr(), - DiskImageFormat::Raw as u32, + image_format as u32, false, ) } < 0