@@ -121,6 +121,26 @@ pub(crate) struct StagedDeployment {
121121 pub ( crate ) finalization_locked : bool ,
122122}
123123
124+ #[ derive( Debug , PartialEq ) ]
125+ pub ( crate ) struct BootloaderEntry {
126+ /// The fsverity digest associated with the bootloader entry
127+ /// This is the value of composefs= param
128+ pub ( crate ) fsverity : String ,
129+ /// The name of the (UKI/Kernel+Initrd directory) related to the entry
130+ ///
131+ /// For UKI, this is the name of the UKI stripped of our custom
132+ /// prefix and .efi suffix
133+ ///
134+ /// For Type1 entries, this is the name to the directory containing
135+ /// Kernel+Initrd, stripped of our custom prefix
136+ ///
137+ /// Since this is stripped of all our custom prefixes + file extensions
138+ /// this is basically the verity digest part of the name
139+ ///
140+ /// We mainly need this in order to GC shared Type1 entries
141+ pub ( crate ) boot_artifact_name : String ,
142+ }
143+
124144/// Detect if we have `composefs=<digest>` in `/proc/cmdline`
125145pub ( crate ) fn composefs_booted ( ) -> Result < Option < & ' static ComposefsCmdline > > {
126146 static CACHED_DIGEST_VALUE : OnceLock < Option < ComposefsCmdline > > = OnceLock :: new ( ) ;
@@ -263,7 +283,7 @@ fn get_sorted_type1_boot_entries_helper(
263283 Ok ( all_configs)
264284}
265285
266- fn list_type1_entries ( boot_dir : & Dir ) -> Result < Vec < String > > {
286+ fn list_type1_entries ( boot_dir : & Dir ) -> Result < Vec < BootloaderEntry > > {
267287 // Type1 Entry
268288 let boot_entries = get_sorted_type1_boot_entries ( boot_dir, true ) ?;
269289
@@ -274,7 +294,12 @@ fn list_type1_entries(boot_dir: &Dir) -> Result<Vec<String>> {
274294 boot_entries
275295 . into_iter ( )
276296 . chain ( staged_boot_entries)
277- . map ( |entry| entry. get_verity ( ) )
297+ . map ( |entry| {
298+ Ok ( BootloaderEntry {
299+ fsverity : entry. get_verity ( ) ?,
300+ boot_artifact_name : entry. boot_artifact_name ( ) ?. to_string ( ) ,
301+ } )
302+ } )
278303 . collect :: < Result < Vec < _ > , _ > > ( )
279304}
280305
@@ -283,7 +308,7 @@ fn list_type1_entries(boot_dir: &Dir) -> Result<Vec<String>> {
283308/// # Returns
284309/// The fsverity of EROFS images corresponding to boot entries
285310#[ fn_error_context:: context( "Listing bootloader entries" ) ]
286- pub ( crate ) fn list_bootloader_entries ( storage : & Storage ) -> Result < Vec < String > > {
311+ pub ( crate ) fn list_bootloader_entries ( storage : & Storage ) -> Result < Vec < BootloaderEntry > > {
287312 let bootloader = get_bootloader ( ) ?;
288313 let boot_dir = storage. require_boot_dir ( ) ?;
289314
@@ -304,8 +329,13 @@ pub(crate) fn list_bootloader_entries(storage: &Storage) -> Result<Vec<String>>
304329 boot_entries
305330 . into_iter ( )
306331 . chain ( boot_entries_staged)
307- . map ( |entry| entry. get_verity ( ) )
308- . collect :: < Result < Vec < _ > , _ > > ( ) ?
332+ . map ( |entry| {
333+ Ok ( BootloaderEntry {
334+ fsverity : entry. get_verity ( ) ?,
335+ boot_artifact_name : entry. boot_artifact_name ( ) ?,
336+ } )
337+ } )
338+ . collect :: < Result < Vec < _ > , anyhow:: Error > > ( ) ?
309339 } else {
310340 list_type1_entries ( boot_dir) ?
311341 }
@@ -739,7 +769,11 @@ async fn composefs_deployment_status_from(
739769 // Rollback deployment is in here, but may also contain stale deployment entries
740770 let mut extra_deployment_boot_entries: Vec < BootEntry > = Vec :: new ( ) ;
741771
742- for verity_digest in bootloader_entry_verity {
772+ for BootloaderEntry {
773+ fsverity : verity_digest,
774+ ..
775+ } in bootloader_entry_verity
776+ {
743777 // read the origin file
744778 let config = state_dir
745779 . open_dir ( & verity_digest)
@@ -877,6 +911,7 @@ async fn composefs_deployment_status_from(
877911 . map ( |menu| menu. get_verity ( ) ) ,
878912 )
879913 . collect :: < Result < HashSet < _ > > > ( ) ?;
914+
880915 let rollback_candidates: Vec < _ > = extra_deployment_boot_entries
881916 . into_iter ( )
882917 . filter ( |entry| {
0 commit comments