Skip to content

Commit 20eb4e4

Browse files
kargs: Handle addition/removal of kargs from kargs.d
Signed-off-by: Pragyan Poudyal <[email protected]>
1 parent 0c9b17f commit 20eb4e4

File tree

2 files changed

+57
-30
lines changed

2 files changed

+57
-30
lines changed

crates/lib/src/bootc_composefs/boot.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,10 +445,10 @@ pub(crate) fn setup_composefs_bls_boot(
445445
}
446446
};
447447

448-
kargs_from_composefs_filesystem(fs, &repo, &mut cmdline_refs)?;
449-
450448
let is_upgrade = matches!(setup_type, BootSetupType::Upgrade(..));
451449

450+
kargs_from_composefs_filesystem(fs, &repo, &mut cmdline_refs, !is_upgrade)?;
451+
452452
let (entry_paths, _tmpdir_guard) = match bootloader {
453453
Bootloader::Grub => {
454454
let root = Dir::open_ambient_dir(&root_path, ambient_authority())

crates/lib/src/bootc_kargs.rs

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
use anyhow::{Context, Result};
33
use bootc_kernel_cmdline::utf8::{Cmdline, CmdlineOwned};
44
use camino::Utf8Path;
5+
use cap_std_ext::cap_std::ambient_authority;
56
use cap_std_ext::cap_std::fs::Dir;
67
use cap_std_ext::cap_std::fs_utf8::Dir as DirUtf8;
78
use cap_std_ext::dirext::CapStdExtDirExt;
@@ -49,12 +50,52 @@ impl Config {
4950
}
5051
}
5152

53+
/// Compute the diff between existing and remote kargs
54+
/// Apply the diff to the new kargs
55+
fn compute_apply_kargs_diff(
56+
existing_kargs: &Cmdline,
57+
remote_kargs: &Cmdline,
58+
new_kargs: &mut Cmdline,
59+
) {
60+
// Calculate the diff between the existing and remote kargs
61+
let added_kargs: Vec<_> = remote_kargs
62+
.iter()
63+
.filter(|item| !existing_kargs.iter().any(|existing| *item == existing))
64+
.collect();
65+
let removed_kargs: Vec<_> = existing_kargs
66+
.iter()
67+
.filter(|item| !remote_kargs.iter().any(|remote| *item == remote))
68+
.collect();
69+
70+
tracing::debug!("kargs: added={:?} removed={:?}", added_kargs, removed_kargs);
71+
72+
// Apply the diff to the system kargs
73+
for arg in &removed_kargs {
74+
new_kargs.remove_exact(arg);
75+
}
76+
for arg in &added_kargs {
77+
new_kargs.add(arg);
78+
}
79+
}
80+
5281
/// Looks for files in usr/lib/bootc/kargs.d and parses cmdline agruments
5382
pub(crate) fn kargs_from_composefs_filesystem(
5483
fs: &ComposefsFilesystem,
5584
repo: &ComposefsRepository,
56-
cmdline: &mut Cmdline,
85+
new_kargs: &mut Cmdline,
86+
fresh_install: bool,
5787
) -> Result<()> {
88+
let existing_kargs = match fresh_install {
89+
// If we are freshly installing, we won't have any existing kargs
90+
true => Cmdline::new(),
91+
92+
false => {
93+
let root = Dir::open_ambient_dir("/", ambient_authority()).context("Opening root")?;
94+
let existing_kargs = get_kargs_in_root(&root, std::env::consts::ARCH)?;
95+
existing_kargs
96+
}
97+
};
98+
5899
let kargs_d = fs
59100
.root
60101
.get_directory_opt(OsStr::new(KARGS_PATH))
@@ -64,12 +105,18 @@ pub(crate) fn kargs_from_composefs_filesystem(
64105
return Ok(());
65106
};
66107

108+
let mut remote_kargs = Cmdline::new();
109+
67110
for (fname, inode) in kargs_d.sorted_entries() {
68111
let Inode::Leaf(..) = inode else { continue };
69112

70-
let fname_str = fname
71-
.to_str()
72-
.ok_or_else(|| anyhow::anyhow!("Failed to get filename as string"))?;
113+
let Some(fname_str) = fname.to_str() else {
114+
tracing::warn!(
115+
"Failed to convert filename to UTF-8, will skip parsing: {:?}",
116+
fname
117+
);
118+
continue;
119+
};
73120

74121
if !Config::filename_matches(fname_str) {
75122
continue;
@@ -84,10 +131,12 @@ pub(crate) fn kargs_from_composefs_filesystem(
84131
.with_context(|| format!("File {fname_str} is not a valid UTF-8"))?;
85132

86133
if let Some(kargs) = parse_kargs_toml(contents, std::env::consts::ARCH)? {
87-
cmdline.extend(&kargs);
134+
remote_kargs.extend(&kargs);
88135
};
89136
}
90137

138+
compute_apply_kargs_diff(&existing_kargs, &remote_kargs, new_kargs);
139+
91140
Ok(())
92141
}
93142

@@ -221,29 +270,7 @@ pub(crate) fn get_kargs(
221270
// Fetch the kernel arguments from the new root
222271
let remote_kargs = get_kargs_from_ostree(repo, &fetched_tree, sys_arch)?;
223272

224-
// Calculate the diff between the existing and remote kargs
225-
let added_kargs: Vec<_> = remote_kargs
226-
.iter()
227-
.filter(|item| !existing_kargs.iter().any(|existing| *item == existing))
228-
.collect();
229-
let removed_kargs: Vec<_> = existing_kargs
230-
.iter()
231-
.filter(|item| !remote_kargs.iter().any(|remote| *item == remote))
232-
.collect();
233-
234-
tracing::debug!(
235-
"kargs: added={:?} removed={:?}",
236-
&added_kargs,
237-
removed_kargs
238-
);
239-
240-
// Apply the diff to the system kargs
241-
for arg in &removed_kargs {
242-
kargs.remove_exact(arg);
243-
}
244-
for arg in &added_kargs {
245-
kargs.add(arg);
246-
}
273+
compute_apply_kargs_diff(&existing_kargs, &remote_kargs, &mut kargs);
247274

248275
Ok(kargs)
249276
}

0 commit comments

Comments
 (0)