Skip to content

Commit f31b92b

Browse files
composefs/bls: Get cmdline from usr/lib/bootc/kargs.d
Parse toml files in usr/lib/bootc/kargs.d and append them to kernel cmdline on install and upgrade/switch. Also, copy over current deployment's cmdline args on upgrade/switch to another deployment Signed-off-by: Pragyan Poudyal <pragyanpoudyal41999@gmail.com>
1 parent e0475cd commit f31b92b

File tree

2 files changed

+87
-4
lines changed

2 files changed

+87
-4
lines changed

crates/lib/src/bootc_composefs/boot.rs

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::path::Path;
55

66
use anyhow::{anyhow, Context, Result};
77
use bootc_blockdev::find_parent_devices;
8-
use bootc_kernel_cmdline::utf8::Cmdline;
8+
use bootc_kernel_cmdline::utf8::{Cmdline, Parameter};
99
use bootc_mount::inspect_filesystem_of_dir;
1010
use bootc_mount::tempmount::TempMount;
1111
use camino::{Utf8Path, Utf8PathBuf};
@@ -34,6 +34,7 @@ use schemars::JsonSchema;
3434
use serde::{Deserialize, Serialize};
3535

3636
use crate::bootc_composefs::status::get_sorted_grub_uki_boot_entries;
37+
use crate::bootc_kargs::kargs_from_composefs_filesystem;
3738
use crate::composefs_consts::{TYPE1_ENT_PATH, TYPE1_ENT_PATH_STAGED};
3839
use crate::parsers::bls_config::{BLSConfig, BLSConfigType};
3940
use crate::parsers::grub_menuconfig::MenuEntry;
@@ -51,7 +52,6 @@ use crate::{
5152
BOOT_LOADER_ENTRIES, COMPOSEFS_CMDLINE, ORIGIN_KEY_BOOT, ORIGIN_KEY_BOOT_DIGEST,
5253
STAGED_BOOT_LOADER_ENTRIES, STATE_DIR_ABS, USER_CFG, USER_CFG_STAGED,
5354
},
54-
install::RW_KARG,
5555
spec::{Bootloader, Host},
5656
};
5757

@@ -377,7 +377,7 @@ pub(crate) fn setup_composefs_bls_boot(
377377
) -> Result<String> {
378378
let id_hex = id.to_hex();
379379

380-
let (root_path, esp_device, cmdline_refs, fs, bootloader) = match setup_type {
380+
let (root_path, esp_device, mut cmdline_refs, fs, bootloader) = match setup_type {
381381
BootSetupType::Setup((root_setup, state, fs)) => {
382382
// root_setup.kargs has [root=UUID=<UUID>, "rw"]
383383
let mut cmdline_options = Cmdline::new();
@@ -408,16 +408,53 @@ pub(crate) fn setup_composefs_bls_boot(
408408
let sysroot_parent = get_sysroot_parent_dev(&storage.physical_root)?;
409409
let bootloader = host.require_composefs_booted()?.bootloader.clone();
410410

411+
let current_cfg = match bootloader {
412+
Bootloader::Grub => {
413+
let boot_dir = storage
414+
.physical_root
415+
.open_dir("boot")
416+
.context("Opening boot")?;
417+
418+
get_booted_bls(&boot_dir)?
419+
}
420+
421+
Bootloader::Systemd => {
422+
let esp = get_esp_partition(&sysroot_parent)?.0;
423+
let esp_mnt = mount_esp(&esp)?;
424+
425+
get_booted_bls(&esp_mnt.fd)?
426+
}
427+
};
428+
429+
let mut cmdline = match current_cfg.cfg_type {
430+
BLSConfigType::NonEFI { options, .. } => {
431+
let options = options
432+
.ok_or_else(|| anyhow::anyhow!("No 'options' found in BLS Config"))?;
433+
434+
Cmdline::from(options)
435+
}
436+
437+
_ => anyhow::bail!("Found NonEFI config"),
438+
};
439+
440+
// Copy all cmdline args, replacing only `composefs=`
441+
let param = format!("{COMPOSEFS_CMDLINE}={id_hex}");
442+
let param =
443+
Parameter::parse(&param).context("Failed to create 'composefs=' parameter")?;
444+
cmdline.add_or_modify(&param);
445+
411446
(
412447
Utf8PathBuf::from("/sysroot"),
413448
get_esp_partition(&sysroot_parent)?.0,
414-
Cmdline::from(format!("{RW_KARG} {COMPOSEFS_CMDLINE}={id_hex}")),
449+
cmdline,
415450
fs,
416451
bootloader,
417452
)
418453
}
419454
};
420455

456+
kargs_from_composefs_filesystem(fs, &repo, &mut cmdline_refs)?;
457+
421458
let is_upgrade = matches!(setup_type, BootSetupType::Upgrade(..));
422459

423460
let (entry_paths, _tmpdir_guard) = match bootloader {

crates/lib/src/bootc_kargs.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@ use cap_std_ext::cap_std::fs::Dir;
66
use cap_std_ext::cap_std::fs_utf8::Dir as DirUtf8;
77
use cap_std_ext::dirext::CapStdExtDirExt;
88
use cap_std_ext::dirext::CapStdExtDirExtUtf8;
9+
use composefs::fs::read_file;
10+
use composefs::generic_tree::Inode;
911
use ostree::gio;
1012
use ostree_ext::ostree;
1113
use ostree_ext::ostree::Deployment;
1214
use ostree_ext::prelude::Cast;
1315
use ostree_ext::prelude::FileEnumeratorExt;
1416
use ostree_ext::prelude::FileExt;
1517
use serde::Deserialize;
18+
use std::ffi::OsStr;
1619

1720
use crate::deploy::ImageState;
1821
use crate::store::Storage;
22+
use crate::store::{ComposefsFilesystem, ComposefsRepository};
1923

2024
/// The relative path to the kernel arguments which may be embedded in an image.
2125
const KARGS_PATH: &str = "usr/lib/bootc/kargs.d";
@@ -45,6 +49,48 @@ impl Config {
4549
}
4650
}
4751

52+
/// Looks for files in usr/lib/bootc/kargs.d and parses cmdline agruments
53+
pub(crate) fn kargs_from_composefs_filesystem(
54+
fs: &ComposefsFilesystem,
55+
repo: &ComposefsRepository,
56+
cmdline: &mut Cmdline,
57+
) -> Result<()> {
58+
let kargs_d = fs
59+
.root
60+
.get_directory_opt(OsStr::new(KARGS_PATH))
61+
.with_context(|| format!("Getting {KARGS_PATH}"))?;
62+
63+
let Some(kargs_d) = kargs_d else {
64+
return Ok(());
65+
};
66+
67+
for (fname, inode) in kargs_d.sorted_entries() {
68+
let Inode::Leaf(..) = inode else { continue };
69+
70+
let fname_str = fname
71+
.to_str()
72+
.ok_or_else(|| anyhow::anyhow!("Failed to get filename as string"))?;
73+
74+
if !Config::filename_matches(fname_str) {
75+
continue;
76+
}
77+
78+
let file = kargs_d
79+
.get_file(fname)
80+
.with_context(|| format!("Getting file {fname_str}"))?;
81+
82+
let contents = read_file(&file, &repo)?;
83+
let contents = std::str::from_utf8(&contents)
84+
.with_context(|| format!("File {fname_str} is not a valid UTF-8"))?;
85+
86+
if let Some(kargs) = parse_kargs_toml(contents, std::env::consts::ARCH)? {
87+
cmdline.extend(&kargs);
88+
};
89+
}
90+
91+
Ok(())
92+
}
93+
4894
/// Load and parse all bootc kargs.d files in the specified root, returning
4995
/// a combined list.
5096
pub(crate) fn get_kargs_in_root(d: &Dir, sys_arch: &str) -> Result<CmdlineOwned> {

0 commit comments

Comments
 (0)