Skip to content

Commit ce23d07

Browse files
committed
krun_set_exec now also preserves raw argv (passed as base64-encoded variables) which is needed when booting FreeBSD
Signed-off-by: Jan Noha <nohajc@gmail.com>
1 parent bac5d8c commit ce23d07

4 files changed

Lines changed: 41 additions & 2 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/libkrun/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ polly = { path = "../polly" }
3333
utils = { path = "../utils" }
3434
vmm = { path = "../vmm" }
3535
rand = "0.9.2"
36+
base64 = "0.22.1"
3637

3738
[target.'cfg(target_os = "macos")'.dependencies]
3839
hvf = { path = "../hvf" }

src/libkrun/src/lib.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#[macro_use]
22
extern crate log;
33

4+
use base64::prelude::*;
45
use crossbeam_channel::unbounded;
56
#[cfg(feature = "blk")]
67
use devices::virtio::block::{ImageType, SyncMode};
@@ -1278,6 +1279,24 @@ unsafe fn collapse_str_array(array: &[*const c_char]) -> Result<String, std::str
12781279
Ok(strvec.join(" "))
12791280
}
12801281

1282+
// unlike collapse_str_array, this doesn't do the UTF-8 conversion
1283+
// and just keeps the null-terminated strings as raw bytes
1284+
unsafe fn flatten_cstr_array(array: &[*const c_char]) -> Vec<u8> {
1285+
let mut bytevec = Vec::new();
1286+
1287+
for item in array.iter().take(MAX_ARGS) {
1288+
if item.is_null() {
1289+
break;
1290+
} else {
1291+
let cs = CStr::from_ptr(*item);
1292+
bytevec.extend_from_slice(cs.to_bytes());
1293+
bytevec.push(0);
1294+
}
1295+
}
1296+
1297+
bytevec
1298+
}
1299+
12811300
#[allow(clippy::format_collect)]
12821301
#[allow(clippy::missing_safety_doc)]
12831302
#[no_mangle]
@@ -1308,7 +1327,14 @@ pub unsafe extern "C" fn krun_set_exec(
13081327
"".to_string()
13091328
};
13101329

1311-
let env = if !c_envp.is_null() {
1330+
let args_raw = if !c_argv.is_null() {
1331+
let argv_array: &[*const c_char] = slice::from_raw_parts(c_argv, MAX_ARGS);
1332+
flatten_cstr_array(argv_array)
1333+
} else {
1334+
vec![]
1335+
};
1336+
1337+
let mut env = if !c_envp.is_null() {
13121338
let envp_array: &[*const c_char] = slice::from_raw_parts(c_envp, MAX_ARGS);
13131339
match collapse_str_array(envp_array) {
13141340
Ok(s) => s,
@@ -1323,6 +1349,11 @@ pub unsafe extern "C" fn krun_set_exec(
13231349
.collect()
13241350
};
13251351

1352+
// KRUN_INIT_ARGVXX="<base64>" must have at most 128 bytes (KENV_MVALLEN on FreeBSD)
1353+
for (i, args_part) in args_raw.chunks(78).enumerate() {
1354+
env += &format!(" KRUN_INIT_ARGV{}={}", i, BASE64_STANDARD.encode(args_part));
1355+
}
1356+
13261357
match CTX_MAP.lock().unwrap().entry(ctx_id) {
13271358
Entry::Occupied(mut ctx_cfg) => {
13281359
let cfg = ctx_cfg.get_mut();

src/vmm/src/builder.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,11 +578,15 @@ pub fn build_microvm(
578578
)?;
579579

580580
let vcpu_config = vm_resources.vcpu_config();
581+
let mut kernel_is_freebsd = false;
581582

582583
// Clone the command-line so that a failed boot doesn't pollute the original.
583584
#[allow(unused_mut)]
584585
let mut kernel_cmdline = Cmdline::new(arch::CMDLINE_MAX_SIZE);
585586
if let Some(cmdline) = payload_config.kernel_cmdline {
587+
if cmdline.starts_with("FreeBSD:") {
588+
kernel_is_freebsd = true;
589+
}
586590
kernel_cmdline.insert_str(cmdline.as_str()).unwrap();
587591
} else if let Some(cmdline) = &vm_resources.kernel_cmdline.prolog {
588592
kernel_cmdline.insert_str(cmdline).unwrap();
@@ -1063,7 +1067,9 @@ pub fn build_microvm(
10631067
}
10641068

10651069
if let Some(s) = &vm_resources.kernel_cmdline.epilog {
1066-
vmm.kernel_cmdline.insert_str(s).unwrap();
1070+
if !kernel_is_freebsd {
1071+
vmm.kernel_cmdline.insert_str(s).unwrap();
1072+
}
10671073
};
10681074

10691075
// Write the kernel command line to guest memory. This is x86_64 specific, since on

0 commit comments

Comments
 (0)