@@ -348,12 +348,41 @@ impl Component for Efi {
348
348
. context ( "opening update dir" ) ?;
349
349
let updatef = filetree:: FileTree :: new_from_dir ( & updated) . context ( "reading update dir" ) ?;
350
350
let diff = currentf. diff ( & updatef) ?;
351
- self . ensure_mounted_esp ( Path :: new ( "/" ) ) ?;
352
- let destdir = self . open_esp ( ) . context ( "opening EFI dir" ) ?;
353
- validate_esp ( & destdir) ?;
351
+
352
+ /* copy "lowest" directory that we need to make the change
353
+ * e.g. we only affect EFI/fedora for example and not all of EFI
354
+ */
355
+ let vendor = if let Some ( v) = self . get_efi_vendor ( & sysroot) ? {
356
+ v
357
+ } else {
358
+ bail ! ( "Failed to get vendor dir" ) ;
359
+ } ;
360
+
361
+ let esp = self . esp_path ( ) ?;
362
+ let vendordir = esp. join ( & vendor) ;
363
+ let tmp_vendordir = esp. join ( format ! ( ".{vendor}.tmp" ) ) ;
364
+ // remove a previous directory if it exists in order to handle being interrupted in the middle.
365
+ std:: fs:: remove_dir_all ( & tmp_vendordir) ?;
366
+ copy_dir ( & vendordir, & tmp_vendordir) . context ( "copying existing files to temp dir" ) ?;
367
+ assert ! ( tmp_vendordir. exists( ) ) ;
368
+
369
+ let tmpdir = sysroot. sub_dir ( & vendordir) ?;
370
+ validate_esp ( & tmpdir) ?;
354
371
log:: trace!( "applying diff: {}" , & diff) ;
355
- filetree:: apply_diff ( & updated, & destdir, & diff, None )
356
- . context ( "applying filesystem changes" ) ?;
372
+ filetree:: apply_diff ( & updated, & tmpdir, & diff, None )
373
+ . context ( "applying filesystem changes to temp EFI" ) ?;
374
+ {
375
+ let esp = self . open_esp ( ) ?;
376
+ log:: trace!(
377
+ "doing local exchange for {} and {}" ,
378
+ tmp_vendordir. display( ) ,
379
+ vendordir. display( )
380
+ ) ;
381
+ esp. local_exchange ( & tmp_vendordir, & vendordir) ?;
382
+ // finally remove the temp dir
383
+ std:: fs:: remove_dir_all ( & tmp_vendordir) ?;
384
+ assert_eq ! ( tmp_vendordir. exists( ) , false ) ;
385
+ }
357
386
let adopted_from = None ;
358
387
Ok ( InstalledContent {
359
388
meta : updatemeta,
@@ -580,6 +609,18 @@ fn find_file_recursive<P: AsRef<Path>>(dir: P, target_file: &str) -> Result<Vec<
580
609
Ok ( result)
581
610
}
582
611
612
+ fn copy_dir ( src : & Path , dst : & Path ) -> Result < ( ) > {
613
+ let r = std:: process:: Command :: new ( "cp" )
614
+ . args ( [ "-a" ] )
615
+ . arg ( src)
616
+ . arg ( dst)
617
+ . status ( ) ?;
618
+ if !r. success ( ) {
619
+ anyhow:: bail!( "Failed to copy" ) ;
620
+ }
621
+ Ok ( ( ) )
622
+ }
623
+
583
624
#[ cfg( test) ]
584
625
mod tests {
585
626
use super :: * ;
0 commit comments