@@ -7,7 +7,11 @@ use fn_error_context::context;
77use serde:: { Deserialize , Serialize } ;
88
99use crate :: {
10- bootc_composefs:: { boot:: BootType , repo:: get_imgref} ,
10+ bootc_composefs:: {
11+ boot:: BootType ,
12+ repo:: get_imgref,
13+ utils:: { compute_store_boot_digest_for_uki, get_uki_cmdline} ,
14+ } ,
1115 composefs_consts:: {
1216 COMPOSEFS_CMDLINE , ORIGIN_KEY_BOOT_DIGEST , TYPE1_ENT_PATH , TYPE1_ENT_PATH_STAGED , USER_CFG ,
1317 } ,
@@ -350,26 +354,33 @@ pub(crate) async fn get_composefs_status(
350354 composefs_deployment_status_from ( & storage, booted_cfs. cmdline ) . await
351355}
352356
353- fn set_soft_reboot_capable_bls (
357+ /// Check whether any deployment is capable of being soft rebooted or not
358+ #[ context( "Checking soft reboot capability" ) ]
359+ fn set_soft_reboot_capability (
354360 storage : & Storage ,
355361 host : & mut Host ,
356- bls_entries : & Vec < BLSConfig > ,
362+ bls_entries : Option < Vec < BLSConfig > > ,
357363 cmdline : & ComposefsCmdline ,
358364) -> Result < ( ) > {
359365 let booted = host. require_composefs_booted ( ) ?;
360366
361367 match booted. boot_type {
362368 BootType :: Bls => {
363- set_reboot_capable_type1_deployments ( storage , cmdline , host , bls_entries) ? ;
364- }
369+ let mut bls_entries =
370+ bls_entries . ok_or_else ( || anyhow :: anyhow! ( "BLS entries not provided" ) ) ? ;
365371
366- BootType :: Uki => match booted. bootloader {
367- Bootloader :: Grub => todo ! ( ) ,
368- Bootloader :: Systemd => todo ! ( ) ,
369- } ,
370- } ;
372+ let staged_entries =
373+ get_sorted_staged_type1_boot_entries ( storage. require_boot_dir ( ) ?, false ) ?;
371374
372- Ok ( ( ) )
375+ // We will have a duplicate booted entry here, but that's fine as we only use this
376+ // vector to check for existence of an entry
377+ bls_entries. extend ( staged_entries) ;
378+
379+ set_reboot_capable_type1_deployments ( cmdline, host, bls_entries)
380+ }
381+
382+ BootType :: Uki => set_reboot_capable_uki_deployments ( storage, cmdline, host) ,
383+ }
373384}
374385
375386fn find_bls_entry < ' a > (
@@ -406,73 +417,112 @@ fn compare_cmdline_skip_cfs(first: &Cmdline<'_>, second: &Cmdline<'_>) -> bool {
406417 return true ;
407418}
408419
409- fn set_soft_reboot_capable_type1 (
410- deployment : & mut BootEntry ,
411- bls_entries : & Vec < BLSConfig > ,
412- booted_bls_entry : & BLSConfig ,
413- booted_boot_digest : & String ,
420+ # [ context ( "Setting soft reboot capability for Type1 entries" ) ]
421+ fn set_reboot_capable_type1_deployments (
422+ booted_cmdline : & ComposefsCmdline ,
423+ host : & mut Host ,
424+ bls_entries : Vec < BLSConfig > ,
414425) -> Result < ( ) > {
415- let deployment_cfs = deployment. require_composefs ( ) ?;
426+ let booted = host
427+ . status
428+ . booted
429+ . as_ref ( )
430+ . ok_or_else ( || anyhow:: anyhow!( "Failed to find booted entry" ) ) ?;
431+
432+ let booted_boot_digest = booted. composefs_boot_digest ( ) ?;
433+
434+ let booted_bls_entry = find_bls_entry ( & * booted_cmdline. digest , & bls_entries) ?
435+ . ok_or_else ( || anyhow:: anyhow!( "Booted BLS entry not found" ) ) ?;
416436
417- // TODO: Unwrap
418- if deployment_cfs. boot_digest . as_ref ( ) . unwrap ( ) != booted_boot_digest {
419- deployment. soft_reboot_capable = false ;
420- return Ok ( ( ) ) ;
437+ let booted_cmdline = booted_bls_entry. get_cmdline ( ) ?;
438+
439+ for depl in host
440+ . status
441+ . staged
442+ . iter_mut ( )
443+ . chain ( host. status . rollback . iter_mut ( ) )
444+ . chain ( host. status . other_deployments . iter_mut ( ) )
445+ {
446+ let entry = find_bls_entry ( & depl. require_composefs ( ) ?. verity , & bls_entries) ?
447+ . ok_or_else ( || anyhow:: anyhow!( "Entry not found" ) ) ?;
448+
449+ let depl_cmdline = entry. get_cmdline ( ) ?;
450+
451+ depl. soft_reboot_capable = is_soft_rebootable (
452+ depl. composefs_boot_digest ( ) ?,
453+ booted_boot_digest,
454+ depl_cmdline,
455+ booted_cmdline,
456+ ) ;
421457 }
422458
423- let entry = find_bls_entry ( & deployment_cfs . verity , bls_entries ) ?
424- . ok_or_else ( || anyhow :: anyhow! ( "Entry not found" ) ) ? ;
459+ Ok ( ( ) )
460+ }
425461
426- let opts = entry. get_cmdline ( ) ?;
427- let booted_cmdline_opts = booted_bls_entry. get_cmdline ( ) ?;
462+ fn is_soft_rebootable (
463+ depl_boot_digest : & str ,
464+ booted_boot_digest : & str ,
465+ depl_cmdline : & Cmdline ,
466+ booted_cmdline : & Cmdline ,
467+ ) -> bool {
468+ if depl_boot_digest != booted_boot_digest {
469+ tracing:: debug!( "Soft reboot not allowed due to kernel skew" ) ;
470+ return false ;
471+ }
428472
429- if opts . len ( ) != booted_cmdline_opts . len ( ) {
473+ if depl_cmdline . as_bytes ( ) . len ( ) != booted_cmdline . as_bytes ( ) . len ( ) {
430474 tracing:: debug!( "Soft reboot not allowed due to differing cmdline" ) ;
431- deployment. soft_reboot_capable = false ;
432- return Ok ( ( ) ) ;
475+ return false ;
433476 }
434477
435- deployment. soft_reboot_capable = compare_cmdline_skip_cfs ( opts, booted_cmdline_opts)
436- && compare_cmdline_skip_cfs ( booted_cmdline_opts, opts) ;
437-
438- return Ok ( ( ) ) ;
478+ return compare_cmdline_skip_cfs ( depl_cmdline, booted_cmdline)
479+ && compare_cmdline_skip_cfs ( booted_cmdline, depl_cmdline) ;
439480}
440481
441- fn set_reboot_capable_type1_deployments (
482+ #[ context( "Setting soft reboot capability for UKI deployments" ) ]
483+ fn set_reboot_capable_uki_deployments (
442484 storage : & Storage ,
443485 cmdline : & ComposefsCmdline ,
444486 host : & mut Host ,
445- bls_entries : & Vec < BLSConfig > ,
446487) -> Result < ( ) > {
447488 let booted = host
448489 . status
449490 . booted
450491 . as_ref ( )
451492 . ok_or_else ( || anyhow:: anyhow!( "Failed to find booted entry" ) ) ?;
452493
453- let booted_boot_digest = booted. composefs_boot_digest ( ) ?;
454-
455- let booted_bls_entry = find_bls_entry ( & * cmdline. digest , bls_entries) ?
456- . ok_or_else ( || anyhow:: anyhow!( "Booted bls entry not found" ) ) ?;
494+ // Since older booted systems won't have the boot digest for UKIs
495+ let booted_boot_digest = match booted. composefs_boot_digest ( ) {
496+ Ok ( d) => d,
497+ Err ( _) => & compute_store_boot_digest_for_uki ( storage, & cmdline. digest ) ?,
498+ } ;
457499
458- if let Some ( staged) = host. status . staged . as_mut ( ) {
459- let staged_entries =
460- get_sorted_staged_type1_boot_entries ( storage. require_boot_dir ( ) ?, true ) ?;
500+ let booted_cmdline = get_uki_cmdline ( storage, & booted. require_composefs ( ) ?. verity ) ?;
461501
462- set_soft_reboot_capable_type1 (
463- staged,
464- & staged_entries,
465- booted_bls_entry,
466- booted_boot_digest,
467- ) ?;
468- }
502+ for deployment in host
503+ . status
504+ . staged
505+ . iter_mut ( )
506+ . chain ( host. status . rollback . iter_mut ( ) )
507+ . chain ( host. status . other_deployments . iter_mut ( ) )
508+ {
509+ // Since older booted systems won't have the boot digest for UKIs
510+ let depl_boot_digest = match deployment. composefs_boot_digest ( ) {
511+ Ok ( d) => d,
512+ Err ( _) => & compute_store_boot_digest_for_uki (
513+ storage,
514+ & deployment. require_composefs ( ) ?. verity ,
515+ ) ?,
516+ } ;
469517
470- if let Some ( rollback) = & mut host. status . rollback {
471- set_soft_reboot_capable_type1 ( rollback, bls_entries, booted_bls_entry, booted_boot_digest) ?;
472- }
518+ let depl_cmdline = get_uki_cmdline ( storage, & deployment. require_composefs ( ) ?. verity ) ?;
473519
474- for depl in & mut host. status . other_deployments {
475- set_soft_reboot_capable_type1 ( depl, bls_entries, booted_bls_entry, booted_boot_digest) ?;
520+ deployment. soft_reboot_capable = is_soft_rebootable (
521+ depl_boot_digest,
522+ booted_boot_digest,
523+ & depl_cmdline,
524+ & booted_cmdline,
525+ ) ;
476526 }
477527
478528 Ok ( ( ) )
@@ -645,9 +695,7 @@ pub(crate) async fn composefs_deployment_status_from(
645695 host. spec . boot_order = BootOrder :: Rollback
646696 } ;
647697
648- if let Some ( bls_configs) = sorted_bls_config {
649- set_soft_reboot_capable_bls ( storage, & mut host, & bls_configs, cmdline) ?;
650- }
698+ set_soft_reboot_capability ( storage, & mut host, sorted_bls_config, cmdline) ?;
651699
652700 Ok ( host)
653701}
0 commit comments