22use anyhow:: { Context , Result } ;
33use bootc_kernel_cmdline:: utf8:: { Cmdline , CmdlineOwned } ;
44use camino:: Utf8Path ;
5+ use cap_std_ext:: cap_std:: ambient_authority;
56use cap_std_ext:: cap_std:: fs:: Dir ;
67use cap_std_ext:: cap_std:: fs_utf8:: Dir as DirUtf8 ;
78use 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
5382pub ( 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