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,10 @@ 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 : & mut R ) -> Result < String > {
350+ let vmlinuz = uki:: get_section_buffered ( uki, ".linux" ) . context ( ".linux not present" ) ?;
351+ uki. seek ( SeekFrom :: Start ( 0 ) ) . context ( "Moving seek to 0" ) ?;
352+ let initramfs = uki:: get_section_buffered ( uki, ".initrd" ) . context ( ".initrd not present" ) ?;
356353
357354 let mut hasher = openssl:: hash:: Hasher :: new ( openssl:: hash:: MessageDigest :: sha256 ( ) )
358355 . context ( "Creating hasher" ) ?;
@@ -796,17 +793,23 @@ fn write_pe_to_esp(
796793 missing_fsverity_allowed : bool ,
797794 mounted_efi : impl AsRef < Path > ,
798795) -> Result < Option < UKIInfo > > {
799- let efi_bin = read_file ( file, & repo) . context ( "Reading .efi binary" ) ?;
796+ let mut uki_reader = match file {
797+ RegularFile :: Inline ( ..) => {
798+ // UKI/Addons would always be large enough to be an external object
799+ anyhow:: bail!( "File too small to be UKI/Addon" )
800+ }
801+ RegularFile :: External ( id, ..) => std:: fs:: File :: from ( repo. open_object ( id) ?) ,
802+ } ;
800803
801804 let mut boot_label: Option < UKIInfo > = None ;
802805
803806 // UKI Extension might not even have a cmdline
804807 // TODO: UKI Addon might also have a composefs= cmdline?
805808 if matches ! ( pe_type, PEType :: Uki ) {
806- let cmdline = uki:: get_cmdline ( & efi_bin ) . context ( "Getting UKI cmdline" ) ?;
809+ let cmdline = uki:: get_cmdline_buffered ( & mut uki_reader ) . context ( "Getting UKI cmdline" ) ?;
807810
808811 let ( composefs_cmdline, missing_verity_allowed_cmdline) =
809- get_cmdline_composefs :: < Sha512HashValue > ( cmdline) . context ( "Parsing composefs=" ) ?;
812+ get_cmdline_composefs :: < Sha512HashValue > ( & cmdline) . context ( "Parsing composefs=" ) ?;
810813
811814 // If the UKI cmdline does not match what the user has passed as cmdline option
812815 // NOTE: This will only be checked for new installs and now upgrades/switches
@@ -830,14 +833,18 @@ fn write_pe_to_esp(
830833 ) ;
831834 }
832835
833- let osrel = uki:: get_text_section ( & efi_bin, ".osrel" ) ?;
836+ uki_reader. seek ( SeekFrom :: Start ( 0 ) ) ?;
837+ let osrel = uki:: get_text_section_buffered ( & mut uki_reader, ".osrel" ) ?;
834838
835- let parsed_osrel = OsReleaseInfo :: parse ( osrel) ;
839+ let parsed_osrel = OsReleaseInfo :: parse ( & osrel) ;
836840
837- let boot_digest = compute_boot_digest_uki ( & efi_bin) ?;
841+ uki_reader. seek ( SeekFrom :: Start ( 0 ) ) ?;
842+ let boot_digest = compute_boot_digest_uki ( & mut uki_reader) ?;
838843
844+ uki_reader. seek ( SeekFrom :: Start ( 0 ) ) ?;
839845 boot_label = Some ( UKIInfo {
840- boot_label : uki:: get_boot_label ( & efi_bin) . context ( "Getting UKI boot label" ) ?,
846+ boot_label : uki:: get_boot_label_buffered ( & mut uki_reader)
847+ . context ( "Getting UKI boot label" ) ?,
841848 version : parsed_osrel. get_version ( ) ,
842849 os_id : parsed_osrel. get_value ( & [ "ID" ] ) ,
843850 boot_digest,
@@ -883,8 +890,9 @@ fn write_pe_to_esp(
883890 . as_str ( ) ,
884891 } ;
885892
893+ uki_reader. seek ( SeekFrom :: Start ( 0 ) ) ?;
886894 pe_dir
887- . atomic_write ( pe_name, efi_bin )
895+ . atomic_replace_with ( pe_name, |writer| std :: io :: copy ( & mut uki_reader , writer ) )
888896 . context ( "Writing UKI" ) ?;
889897
890898 rustix:: fs:: fsync (
0 commit comments