@@ -6,7 +6,10 @@ use bootc_mount::inspect_filesystem;
66use fn_error_context:: context;
77
88use crate :: {
9- bootc_composefs:: boot:: BootType ,
9+ bootc_composefs:: {
10+ boot:: BootType ,
11+ utils:: { compute_store_boot_digest_for_uki, get_uki_cmdline} ,
12+ } ,
1013 composefs_consts:: {
1114 COMPOSEFS_CMDLINE , ORIGIN_KEY_BOOT_DIGEST , TYPE1_ENT_PATH , TYPE1_ENT_PATH_STAGED , USER_CFG ,
1215 } ,
@@ -307,26 +310,33 @@ pub(crate) async fn get_composefs_status(
307310 composefs_deployment_status_from ( & storage, booted_cfs. cmdline ) . await
308311}
309312
310- fn set_soft_reboot_capable_bls (
313+ /// Check whether any deployment is capable of being soft rebooted or not
314+ #[ context( "Checking soft reboot capability" ) ]
315+ fn set_soft_reboot_capability (
311316 storage : & Storage ,
312317 host : & mut Host ,
313- bls_entries : & Vec < BLSConfig > ,
318+ bls_entries : Option < Vec < BLSConfig > > ,
314319 cmdline : & ComposefsCmdline ,
315320) -> Result < ( ) > {
316321 let booted = host. require_composefs_booted ( ) ?;
317322
318323 match booted. boot_type {
319324 BootType :: Bls => {
320- set_reboot_capable_type1_deployments ( storage , cmdline , host , bls_entries) ? ;
321- }
325+ let mut bls_entries =
326+ bls_entries . ok_or_else ( || anyhow :: anyhow! ( "BLS entries not provided" ) ) ? ;
322327
323- BootType :: Uki => match booted. bootloader {
324- Bootloader :: Grub => todo ! ( ) ,
325- Bootloader :: Systemd => todo ! ( ) ,
326- } ,
327- } ;
328+ let staged_entries =
329+ get_sorted_staged_type1_boot_entries ( storage. require_boot_dir ( ) ?, false ) ?;
328330
329- Ok ( ( ) )
331+ // We will have a duplicate booted entry here, but that's fine as we only use this
332+ // vector to check for existence of an entry
333+ bls_entries. extend ( staged_entries) ;
334+
335+ set_reboot_capable_type1_deployments ( cmdline, host, bls_entries)
336+ }
337+
338+ BootType :: Uki => set_reboot_capable_uki_deployments ( storage, cmdline, host) ,
339+ }
330340}
331341
332342fn find_bls_entry < ' a > (
@@ -363,73 +373,112 @@ fn compare_cmdline_skip_cfs(first: &Cmdline<'_>, second: &Cmdline<'_>) -> bool {
363373 return true ;
364374}
365375
366- fn set_soft_reboot_capable_type1 (
367- deployment : & mut BootEntry ,
368- bls_entries : & Vec < BLSConfig > ,
369- booted_bls_entry : & BLSConfig ,
370- booted_boot_digest : & String ,
376+ # [ context ( "Setting soft reboot capability for Type1 entries" ) ]
377+ fn set_reboot_capable_type1_deployments (
378+ booted_cmdline : & ComposefsCmdline ,
379+ host : & mut Host ,
380+ bls_entries : Vec < BLSConfig > ,
371381) -> Result < ( ) > {
372- let deployment_cfs = deployment. require_composefs ( ) ?;
382+ let booted = host
383+ . status
384+ . booted
385+ . as_ref ( )
386+ . ok_or_else ( || anyhow:: anyhow!( "Failed to find booted entry" ) ) ?;
387+
388+ let booted_boot_digest = booted. composefs_boot_digest ( ) ?;
389+
390+ let booted_bls_entry = find_bls_entry ( & * booted_cmdline. digest , & bls_entries) ?
391+ . ok_or_else ( || anyhow:: anyhow!( "Booted BLS entry not found" ) ) ?;
373392
374- // TODO: Unwrap
375- if deployment_cfs. boot_digest . as_ref ( ) . unwrap ( ) != booted_boot_digest {
376- deployment. soft_reboot_capable = false ;
377- return Ok ( ( ) ) ;
393+ let booted_cmdline = booted_bls_entry. get_cmdline ( ) ?;
394+
395+ for depl in host
396+ . status
397+ . staged
398+ . iter_mut ( )
399+ . chain ( host. status . rollback . iter_mut ( ) )
400+ . chain ( host. status . other_deployments . iter_mut ( ) )
401+ {
402+ let entry = find_bls_entry ( & depl. require_composefs ( ) ?. verity , & bls_entries) ?
403+ . ok_or_else ( || anyhow:: anyhow!( "Entry not found" ) ) ?;
404+
405+ let depl_cmdline = entry. get_cmdline ( ) ?;
406+
407+ depl. soft_reboot_capable = is_soft_rebootable (
408+ depl. composefs_boot_digest ( ) ?,
409+ booted_boot_digest,
410+ depl_cmdline,
411+ booted_cmdline,
412+ ) ;
378413 }
379414
380- let entry = find_bls_entry ( & deployment_cfs . verity , bls_entries ) ?
381- . ok_or_else ( || anyhow :: anyhow! ( "Entry not found" ) ) ? ;
415+ Ok ( ( ) )
416+ }
382417
383- let opts = entry. get_cmdline ( ) ?;
384- let booted_cmdline_opts = booted_bls_entry. get_cmdline ( ) ?;
418+ fn is_soft_rebootable (
419+ depl_boot_digest : & str ,
420+ booted_boot_digest : & str ,
421+ depl_cmdline : & Cmdline ,
422+ booted_cmdline : & Cmdline ,
423+ ) -> bool {
424+ if depl_boot_digest != booted_boot_digest {
425+ tracing:: debug!( "Soft reboot not allowed due to kernel skew" ) ;
426+ return false ;
427+ }
385428
386- if opts . len ( ) != booted_cmdline_opts . len ( ) {
429+ if depl_cmdline . as_bytes ( ) . len ( ) != booted_cmdline . as_bytes ( ) . len ( ) {
387430 tracing:: debug!( "Soft reboot not allowed due to differing cmdline" ) ;
388- deployment. soft_reboot_capable = false ;
389- return Ok ( ( ) ) ;
431+ return false ;
390432 }
391433
392- deployment. soft_reboot_capable = compare_cmdline_skip_cfs ( opts, booted_cmdline_opts)
393- && compare_cmdline_skip_cfs ( booted_cmdline_opts, opts) ;
394-
395- return Ok ( ( ) ) ;
434+ return compare_cmdline_skip_cfs ( depl_cmdline, booted_cmdline)
435+ && compare_cmdline_skip_cfs ( booted_cmdline, depl_cmdline) ;
396436}
397437
398- fn set_reboot_capable_type1_deployments (
438+ #[ context( "Setting soft reboot capability for UKI deployments" ) ]
439+ fn set_reboot_capable_uki_deployments (
399440 storage : & Storage ,
400441 cmdline : & ComposefsCmdline ,
401442 host : & mut Host ,
402- bls_entries : & Vec < BLSConfig > ,
403443) -> Result < ( ) > {
404444 let booted = host
405445 . status
406446 . booted
407447 . as_ref ( )
408448 . ok_or_else ( || anyhow:: anyhow!( "Failed to find booted entry" ) ) ?;
409449
410- let booted_boot_digest = booted. composefs_boot_digest ( ) ?;
411-
412- let booted_bls_entry = find_bls_entry ( & * cmdline. digest , bls_entries) ?
413- . ok_or_else ( || anyhow:: anyhow!( "Booted bls entry not found" ) ) ?;
450+ // Since older booted systems won't have the boot digest for UKIs
451+ let booted_boot_digest = match booted. composefs_boot_digest ( ) {
452+ Ok ( d) => d,
453+ Err ( _) => & compute_store_boot_digest_for_uki ( storage, & cmdline. digest ) ?,
454+ } ;
414455
415- if let Some ( staged) = host. status . staged . as_mut ( ) {
416- let staged_entries =
417- get_sorted_staged_type1_boot_entries ( storage. require_boot_dir ( ) ?, true ) ?;
456+ let booted_cmdline = get_uki_cmdline ( storage, & booted. require_composefs ( ) ?. verity ) ?;
418457
419- set_soft_reboot_capable_type1 (
420- staged,
421- & staged_entries,
422- booted_bls_entry,
423- booted_boot_digest,
424- ) ?;
425- }
458+ for deployment in host
459+ . status
460+ . staged
461+ . iter_mut ( )
462+ . chain ( host. status . rollback . iter_mut ( ) )
463+ . chain ( host. status . other_deployments . iter_mut ( ) )
464+ {
465+ // Since older booted systems won't have the boot digest for UKIs
466+ let depl_boot_digest = match deployment. composefs_boot_digest ( ) {
467+ Ok ( d) => d,
468+ Err ( _) => & compute_store_boot_digest_for_uki (
469+ storage,
470+ & deployment. require_composefs ( ) ?. verity ,
471+ ) ?,
472+ } ;
426473
427- if let Some ( rollback) = & mut host. status . rollback {
428- set_soft_reboot_capable_type1 ( rollback, bls_entries, booted_bls_entry, booted_boot_digest) ?;
429- }
474+ let depl_cmdline = get_uki_cmdline ( storage, & deployment. require_composefs ( ) ?. verity ) ?;
430475
431- for depl in & mut host. status . other_deployments {
432- set_soft_reboot_capable_type1 ( depl, bls_entries, booted_bls_entry, booted_boot_digest) ?;
476+ deployment. soft_reboot_capable = is_soft_rebootable (
477+ depl_boot_digest,
478+ booted_boot_digest,
479+ & depl_cmdline,
480+ & booted_cmdline,
481+ ) ;
433482 }
434483
435484 Ok ( ( ) )
@@ -602,9 +651,7 @@ pub(crate) async fn composefs_deployment_status_from(
602651 host. spec . boot_order = BootOrder :: Rollback
603652 } ;
604653
605- if let Some ( bls_configs) = sorted_bls_config {
606- set_soft_reboot_capable_bls ( storage, & mut host, & bls_configs, cmdline) ?;
607- }
654+ set_soft_reboot_capability ( storage, & mut host, sorted_bls_config, cmdline) ?;
608655
609656 Ok ( host)
610657}
0 commit comments