@@ -183,6 +183,76 @@ impl Efi {
183183 clear_efi_target ( & product_name) ?;
184184 create_efi_boot_entry ( device, esp_part_num. trim ( ) , & loader, & product_name)
185185 }
186+
187+ /// Copy from /usr/lib/efi to boot/ESP.
188+ fn package_mode_copy_to_boot_impl ( & self ) -> Result < ( ) > {
189+ let sysroot = Path :: new ( "/" ) ;
190+ let sysroot_path =
191+ Utf8Path :: from_path ( sysroot) . context ( "Sysroot path is not valid UTF-8" ) ?;
192+
193+ // Find components in /usr/lib/efi
194+ let efi_comps = match get_efi_component_from_usr ( sysroot_path, EFILIB ) ? {
195+ Some ( comps) if !comps. is_empty ( ) => comps,
196+ _ => {
197+ log:: debug!( "No EFI components found in /usr/lib/efi" ) ;
198+ return Ok ( ( ) ) ;
199+ }
200+ } ;
201+
202+ // Find all ESP devices
203+ let devices = blockdev:: get_devices ( sysroot) ?;
204+ let Some ( esp_devices) = blockdev:: find_colocated_esps ( & devices) ? else {
205+ anyhow:: bail!( "No ESP found" ) ;
206+ } ;
207+
208+ let sysroot_dir = openat:: Dir :: open ( sysroot) . context ( "Opening sysroot for reading" ) ?;
209+
210+ // Copy to all ESPs
211+ for esp in esp_devices {
212+ let esp_path = self . ensure_mounted_esp ( sysroot, Path :: new ( & esp) ) ?;
213+
214+ let esp_dir = openat:: Dir :: open ( & esp_path)
215+ . with_context ( || format ! ( "Opening ESP at {}" , esp_path. display( ) ) ) ?;
216+ validate_esp_fstype ( & esp_dir) ?;
217+
218+ // Copy each component
219+ for efi_comp in & efi_comps {
220+ log:: info!(
221+ "Copying EFI component {} version {} to ESP at {}" ,
222+ efi_comp. name,
223+ efi_comp. version,
224+ esp_path. display( )
225+ ) ;
226+
227+ let dest_str = esp_path
228+ . to_str ( )
229+ . context ( "ESP path contains invalid UTF-8" ) ?;
230+ filetree:: copy_dir_with_args (
231+ & sysroot_dir,
232+ efi_comp. path . as_str ( ) ,
233+ dest_str,
234+ OPTIONS ,
235+ )
236+ . with_context ( || {
237+ format ! (
238+ "Failed to copy {} from {} to {}" ,
239+ efi_comp. name, efi_comp. path, dest_str
240+ )
241+ } ) ?;
242+ }
243+
244+ // Sync filesystem
245+ let efidir = openat:: Dir :: open ( & esp_path. join ( "EFI" ) )
246+ . context ( "Opening EFI directory for sync" ) ?;
247+ fsfreeze_thaw_cycle ( efidir. open_file ( "." ) ?) ?;
248+ }
249+
250+ log:: info!(
251+ "Successfully copied {} EFI component(s) to all ESPs" ,
252+ efi_comps. len( )
253+ ) ;
254+ Ok ( ( ) )
255+ }
186256}
187257
188258#[ context( "Get product name" ) ]
@@ -622,6 +692,11 @@ impl Component for Efi {
622692 anyhow:: bail!( "Failed to find {SHIM} in the image" )
623693 }
624694 }
695+
696+ /// Package mode copy: Simple copy from /usr/lib/efi to boot/ESP.
697+ fn package_mode_copy_to_boot ( & self ) -> Result < ( ) > {
698+ self . package_mode_copy_to_boot_impl ( )
699+ }
625700}
626701
627702impl Drop for Efi {
0 commit comments