@@ -7,7 +7,9 @@ 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 , repo:: get_imgref, utils:: { compute_store_boot_digest_for_uki, get_uki_cmdline}
12+ } ,
1113 composefs_consts:: {
1214 COMPOSEFS_CMDLINE , ORIGIN_KEY_BOOT_DIGEST , TYPE1_ENT_PATH , TYPE1_ENT_PATH_STAGED , USER_CFG ,
1315 } ,
@@ -350,26 +352,33 @@ pub(crate) async fn get_composefs_status(
350352 composefs_deployment_status_from ( & storage, booted_cfs. cmdline ) . await
351353}
352354
353- fn set_soft_reboot_capable_bls (
355+ /// Check whether any deployment is capable of being soft rebooted or not
356+ #[ context( "Checking soft reboot capability" ) ]
357+ fn set_soft_reboot_capability (
354358 storage : & Storage ,
355359 host : & mut Host ,
356- bls_entries : & Vec < BLSConfig > ,
360+ bls_entries : Option < Vec < BLSConfig > > ,
357361 cmdline : & ComposefsCmdline ,
358362) -> Result < ( ) > {
359363 let booted = host. require_composefs_booted ( ) ?;
360364
361365 match booted. boot_type {
362366 BootType :: Bls => {
363- set_reboot_capable_type1_deployments ( storage , cmdline , host , bls_entries) ? ;
364- }
367+ let mut bls_entries =
368+ bls_entries . ok_or_else ( || anyhow :: anyhow! ( "BLS entries not provided" ) ) ? ;
365369
366- BootType :: Uki => match booted. bootloader {
367- Bootloader :: Grub => todo ! ( ) ,
368- Bootloader :: Systemd => todo ! ( ) ,
369- } ,
370- } ;
370+ let staged_entries =
371+ get_sorted_staged_type1_boot_entries ( storage. require_boot_dir ( ) ?, false ) ?;
371372
372- Ok ( ( ) )
373+ // We will have a duplicate booted entry here, but that's fine as we only use this
374+ // vector to check for existence of an entry
375+ bls_entries. extend ( staged_entries) ;
376+
377+ set_reboot_capable_type1_deployments ( cmdline, host, bls_entries)
378+ }
379+
380+ BootType :: Uki => set_reboot_capable_uki_deployments ( storage, cmdline, host) ,
381+ }
373382}
374383
375384fn find_bls_entry < ' a > (
@@ -406,73 +415,112 @@ fn compare_cmdline_skip_cfs(first: &Cmdline<'_>, second: &Cmdline<'_>) -> bool {
406415 return true ;
407416}
408417
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 ,
418+ # [ context ( "Setting soft reboot capability for Type1 entries" ) ]
419+ fn set_reboot_capable_type1_deployments (
420+ booted_cmdline : & ComposefsCmdline ,
421+ host : & mut Host ,
422+ bls_entries : Vec < BLSConfig > ,
414423) -> Result < ( ) > {
415- let deployment_cfs = deployment. require_composefs ( ) ?;
424+ let booted = host
425+ . status
426+ . booted
427+ . as_ref ( )
428+ . ok_or_else ( || anyhow:: anyhow!( "Failed to find booted entry" ) ) ?;
429+
430+ let booted_boot_digest = booted. composefs_boot_digest ( ) ?;
431+
432+ let booted_bls_entry = find_bls_entry ( & * booted_cmdline. digest , & bls_entries) ?
433+ . ok_or_else ( || anyhow:: anyhow!( "Booted BLS entry not found" ) ) ?;
416434
417- // TODO: Unwrap
418- if deployment_cfs. boot_digest . as_ref ( ) . unwrap ( ) != booted_boot_digest {
419- deployment. soft_reboot_capable = false ;
420- return Ok ( ( ) ) ;
435+ let booted_cmdline = booted_bls_entry. get_cmdline ( ) ?;
436+
437+ for depl in host
438+ . status
439+ . staged
440+ . iter_mut ( )
441+ . chain ( host. status . rollback . iter_mut ( ) )
442+ . chain ( host. status . other_deployments . iter_mut ( ) )
443+ {
444+ let entry = find_bls_entry ( & depl. require_composefs ( ) ?. verity , & bls_entries) ?
445+ . ok_or_else ( || anyhow:: anyhow!( "Entry not found" ) ) ?;
446+
447+ let depl_cmdline = entry. get_cmdline ( ) ?;
448+
449+ depl. soft_reboot_capable = is_soft_rebootable (
450+ depl. composefs_boot_digest ( ) ?,
451+ booted_boot_digest,
452+ depl_cmdline,
453+ booted_cmdline,
454+ ) ;
421455 }
422456
423- let entry = find_bls_entry ( & deployment_cfs . verity , bls_entries ) ?
424- . ok_or_else ( || anyhow :: anyhow! ( "Entry not found" ) ) ? ;
457+ Ok ( ( ) )
458+ }
425459
426- let opts = entry. get_cmdline ( ) ?;
427- let booted_cmdline_opts = booted_bls_entry. get_cmdline ( ) ?;
460+ fn is_soft_rebootable (
461+ depl_boot_digest : & str ,
462+ booted_boot_digest : & str ,
463+ depl_cmdline : & Cmdline ,
464+ booted_cmdline : & Cmdline ,
465+ ) -> bool {
466+ if depl_boot_digest != booted_boot_digest {
467+ tracing:: debug!( "Soft reboot not allowed due to kernel skew" ) ;
468+ return false ;
469+ }
428470
429- if opts . len ( ) != booted_cmdline_opts . len ( ) {
471+ if depl_cmdline . as_bytes ( ) . len ( ) != booted_cmdline . as_bytes ( ) . len ( ) {
430472 tracing:: debug!( "Soft reboot not allowed due to differing cmdline" ) ;
431- deployment. soft_reboot_capable = false ;
432- return Ok ( ( ) ) ;
473+ return false ;
433474 }
434475
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 ( ( ) ) ;
476+ return compare_cmdline_skip_cfs ( depl_cmdline, booted_cmdline)
477+ && compare_cmdline_skip_cfs ( booted_cmdline, depl_cmdline) ;
439478}
440479
441- fn set_reboot_capable_type1_deployments (
480+ #[ context( "Setting soft reboot capability for UKI deployments" ) ]
481+ fn set_reboot_capable_uki_deployments (
442482 storage : & Storage ,
443483 cmdline : & ComposefsCmdline ,
444484 host : & mut Host ,
445- bls_entries : & Vec < BLSConfig > ,
446485) -> Result < ( ) > {
447486 let booted = host
448487 . status
449488 . booted
450489 . as_ref ( )
451490 . ok_or_else ( || anyhow:: anyhow!( "Failed to find booted entry" ) ) ?;
452491
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" ) ) ?;
492+ // Since older booted systems won't have the boot digest for UKIs
493+ let booted_boot_digest = match booted. composefs_boot_digest ( ) {
494+ Ok ( d) => d,
495+ Err ( _) => & compute_store_boot_digest_for_uki ( storage, & cmdline. digest ) ?,
496+ } ;
457497
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 ) ?;
498+ let booted_cmdline = get_uki_cmdline ( storage, & booted. require_composefs ( ) ?. verity ) ?;
461499
462- set_soft_reboot_capable_type1 (
463- staged,
464- & staged_entries,
465- booted_bls_entry,
466- booted_boot_digest,
467- ) ?;
468- }
500+ for deployment in host
501+ . status
502+ . staged
503+ . iter_mut ( )
504+ . chain ( host. status . rollback . iter_mut ( ) )
505+ . chain ( host. status . other_deployments . iter_mut ( ) )
506+ {
507+ // Since older booted systems won't have the boot digest for UKIs
508+ let depl_boot_digest = match deployment. composefs_boot_digest ( ) {
509+ Ok ( d) => d,
510+ Err ( _) => & compute_store_boot_digest_for_uki (
511+ storage,
512+ & deployment. require_composefs ( ) ?. verity ,
513+ ) ?,
514+ } ;
469515
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- }
516+ let depl_cmdline = get_uki_cmdline ( storage, & deployment. require_composefs ( ) ?. verity ) ?;
473517
474- for depl in & mut host. status . other_deployments {
475- set_soft_reboot_capable_type1 ( depl, bls_entries, booted_bls_entry, booted_boot_digest) ?;
518+ deployment. soft_reboot_capable = is_soft_rebootable (
519+ depl_boot_digest,
520+ booted_boot_digest,
521+ & depl_cmdline,
522+ & booted_cmdline,
523+ ) ;
476524 }
477525
478526 Ok ( ( ) )
@@ -645,9 +693,7 @@ pub(crate) async fn composefs_deployment_status_from(
645693 host. spec . boot_order = BootOrder :: Rollback
646694 } ;
647695
648- if let Some ( bls_configs) = sorted_bls_config {
649- set_soft_reboot_capable_bls ( storage, & mut host, & bls_configs, cmdline) ?;
650- }
696+ set_soft_reboot_capability ( storage, & mut host, sorted_bls_config, cmdline) ?;
651697
652698 Ok ( host)
653699}
0 commit comments