6262//! 2. **Secondary**: Currently booted deployment (rollback option)
6363
6464use std:: fs:: create_dir_all;
65- use std:: io:: Read ;
66- use std:: io:: Write ;
65+ use std:: io:: { Read , Seek , SeekFrom , Write } ;
6766use std:: path:: Path ;
6867use std:: sync:: Arc ;
6968
@@ -347,12 +346,13 @@ fn compute_boot_digest_type1(dir: &Dir) -> Result<String> {
347346/// * entry - BootEntry containing VMlinuz and Initrd
348347/// * repo - The composefs repository
349348#[ context( "Computing boot digest" ) ]
350- pub ( crate ) fn compute_boot_digest_uki ( uki : & [ u8 ] ) -> Result < String > {
351- let vmlinuz =
352- uki:: get_section ( uki, ".linux" ) . ok_or_else ( || anyhow:: anyhow!( ".linux not present" ) ) ??;
353-
354- let initramfs = uki:: get_section ( uki, ".initrd" )
355- . ok_or_else ( || anyhow:: anyhow!( ".initrd not present" ) ) ??;
349+ pub ( crate ) fn compute_boot_digest_uki < R : Read + Seek > ( uki_reader : & mut R ) -> Result < String > {
350+ let vmlinuz = uki:: get_section_buffered ( uki_reader, ".linux" ) . context ( ".linux not present" ) ?;
351+ uki_reader
352+ . seek ( SeekFrom :: Start ( 0 ) )
353+ . context ( "Moving seek to 0" ) ?;
354+ let initramfs =
355+ uki:: get_section_buffered ( uki_reader, ".initrd" ) . context ( ".initrd not present" ) ?;
356356
357357 let mut hasher = openssl:: hash:: Hasher :: new ( openssl:: hash:: MessageDigest :: sha256 ( ) )
358358 . context ( "Creating hasher" ) ?;
@@ -796,17 +796,23 @@ fn write_pe_to_esp(
796796 missing_fsverity_allowed : bool ,
797797 mounted_efi : impl AsRef < Path > ,
798798) -> Result < Option < UKIInfo > > {
799- let efi_bin = read_file ( file, & repo) . context ( "Reading .efi binary" ) ?;
799+ let mut uki_reader = match file {
800+ RegularFile :: Inline ( ..) => {
801+ // UKI/Addons would always be large enough to be an external object
802+ anyhow:: bail!( "File too small to be UKI/Addon" )
803+ }
804+ RegularFile :: External ( id, ..) => std:: fs:: File :: from ( repo. open_object ( id) ?) ,
805+ } ;
800806
801807 let mut boot_label: Option < UKIInfo > = None ;
802808
803809 // UKI Extension might not even have a cmdline
804810 // TODO: UKI Addon might also have a composefs= cmdline?
805811 if matches ! ( pe_type, PEType :: Uki ) {
806- let cmdline = uki:: get_cmdline ( & efi_bin ) . context ( "Getting UKI cmdline" ) ?;
812+ let cmdline = uki:: get_cmdline_buffered ( & mut uki_reader ) . context ( "Getting UKI cmdline" ) ?;
807813
808814 let ( composefs_cmdline, missing_verity_allowed_cmdline) =
809- get_cmdline_composefs :: < Sha512HashValue > ( cmdline) . context ( "Parsing composefs=" ) ?;
815+ get_cmdline_composefs :: < Sha512HashValue > ( & cmdline) . context ( "Parsing composefs=" ) ?;
810816
811817 // If the UKI cmdline does not match what the user has passed as cmdline option
812818 // NOTE: This will only be checked for new installs and now upgrades/switches
@@ -830,14 +836,18 @@ fn write_pe_to_esp(
830836 ) ;
831837 }
832838
833- let osrel = uki:: get_text_section ( & efi_bin, ".osrel" ) ?;
839+ uki_reader. seek ( SeekFrom :: Start ( 0 ) ) ?;
840+ let osrel = uki:: get_text_section_buffered ( & mut uki_reader, ".osrel" ) ?;
834841
835- let parsed_osrel = OsReleaseInfo :: parse ( osrel) ;
842+ let parsed_osrel = OsReleaseInfo :: parse ( & osrel) ;
836843
837- let boot_digest = compute_boot_digest_uki ( & efi_bin) ?;
844+ uki_reader. seek ( SeekFrom :: Start ( 0 ) ) ?;
845+ let boot_digest = compute_boot_digest_uki ( & mut uki_reader) ?;
838846
847+ uki_reader. seek ( SeekFrom :: Start ( 0 ) ) ?;
839848 boot_label = Some ( UKIInfo {
840- boot_label : uki:: get_boot_label ( & efi_bin) . context ( "Getting UKI boot label" ) ?,
849+ boot_label : uki:: get_boot_label_buffered ( & mut uki_reader)
850+ . context ( "Getting UKI boot label" ) ?,
841851 version : parsed_osrel. get_version ( ) ,
842852 os_id : parsed_osrel. get_value ( & [ "ID" ] ) ,
843853 boot_digest,
@@ -883,8 +893,9 @@ fn write_pe_to_esp(
883893 . as_str ( ) ,
884894 } ;
885895
896+ uki_reader. seek ( SeekFrom :: Start ( 0 ) ) ?;
886897 pe_dir
887- . atomic_write ( pe_name, efi_bin )
898+ . atomic_replace_with ( pe_name, |writer| std :: io :: copy ( & mut uki_reader , writer ) )
888899 . context ( "Writing UKI" ) ?;
889900
890901 rustix:: fs:: fsync (
0 commit comments