Skip to content

Commit 3f02b8f

Browse files
ahesfordzdykstra
andcommitted
Prevent copying of partial files when target volume is full
Co-authored-by: Andrew J. Hesford <[email protected]> Co-authored-by: Zach Dykstra <[email protected]>
1 parent 258d18a commit 3f02b8f

File tree

1 file changed

+89
-19
lines changed

1 file changed

+89
-19
lines changed

bin/generate-zbm

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -292,32 +292,58 @@ if ( enabled $config{EFI} ) {
292292

293293
my $efi_target;
294294

295-
my $efi_prefix = sprintf( "%s/%s", $config{EFI}{ImageDir}, $runConf{kernel_prefix} );
295+
my $efi_prefix = sprintf( "%s/%s", $config{EFI}{ImageDir}, $runConf{kernel_prefix} );
296+
Log("Setting \$efi_prefix: $efi_prefix");
297+
296298
my $efi_versions = int $config{EFI}{Versions};
297299

300+
make_path $config{EFI}{ImageDir};
301+
298302
if ( $efi_versions > 0 ) {
303+
Log("EFI.Versions is $efi_versions");
299304

300305
# Find UEFI bundles and group by apparent version
301306
my @efi = glob sprintf( "%s-*.EFI", $efi_prefix );
302307
my $efi_groups = groupKernels( \@efi, $efi_prefix, ".EFI" );
308+
Log($efi_groups);
303309

304310
# Determine the revision to use for this image
305311
my $revision = maxRevision( $efi_groups->{ $runConf{version} }, ".EFI" ) + 1;
306312
$efi_target = sprintf( "%s-%s_%s.EFI", $efi_prefix, $runConf{version}, $revision );
313+
Log("Setting \$efi_target: $efi_target");
314+
315+
# Attempt to copy the file, clean up if it does not
316+
unless ( safeCopy( $unified_efi, $efi_target, 0 ) ) {
317+
verboseUnlink( $efi_target, "Failed to create $efi_target" );
318+
exit 1;
319+
}
307320

308321
# Prune the old versions
309322
pruneVersions( $efi_groups, $runConf{version}, $efi_versions );
310323
} else {
311324
$efi_target = sprintf( "%s.EFI", $efi_prefix );
312-
my $efi_backup = sprintf( "%s-backup.EFI", $efi_prefix );
313325

314-
if ( -f $efi_target and safeCopy( $efi_target, $efi_backup ) ) {
326+
# Copy to a placeholder location to ensure success
327+
my ( $efi_fh, $efi_tempfile ) = tempfile( "zbm.XXXXXX", DIR => $config{EFI}{ImageDir}, UNLINK => 0 );
328+
close $efi_fh;
329+
330+
unless ( safeCopy( $unified_efi, $efi_tempfile, 0 ) ) {
331+
verboseUnlink( $efi_tempfile, "Failed to create $efi_target" );
332+
exit 1;
333+
}
334+
335+
# Roll backups
336+
my $efi_backup = sprintf( "%s-backup.EFI", $efi_prefix );
337+
if ( -f $efi_target and rename( $efi_target, $efi_backup ) ) {
315338
printf "Created backup %s -> %s\n", $efi_target, $efi_backup;
316339
}
340+
341+
unless ( rename( $efi_tempfile, $efi_target ) ) {
342+
verboseUnlink( $efi_tempfile, "Failed to create $efi_target" );
343+
exit 1;
344+
}
317345
}
318346

319-
make_path $config{EFI}{ImageDir};
320-
safeCopy( $unified_efi, $efi_target, 0 ) or exit 1;
321347
printf "Created new UEFI image %s\n", $efi_target;
322348
}
323349

@@ -330,6 +356,8 @@ if ( enabled $config{Components} ) {
330356
my $component_prefix = sprintf( "%s/%s", $config{Components}{ImageDir}, $runConf{kernel_prefix} );
331357
my $component_versions = int $config{Components}{Versions};
332358

359+
make_path $config{Components}{ImageDir};
360+
333361
if ( $component_versions > 0 ) {
334362

335363
# Find ZBM kernels and group by apparent version
@@ -341,10 +369,21 @@ if ( enabled $config{Components} ) {
341369
$initramfs_target =
342370
sprintf( "%s/initramfs-%s_%s.img", $config{Components}{ImageDir}, $runConf{version}, $revision );
343371

344-
# Prune old versions
372+
unless ( safeCopy( $initramfs, $initramfs_target, 0 ) ) {
373+
verboseUnlink( $initramfs_target, "Failed to create $initramfs_target" );
374+
exit 1;
375+
}
376+
377+
unless ( safeCopy( $runConf{kernel}, $kernel_target, 0 ) ) {
378+
verboseUnlink( $kernel_target, "Failed to create $kernel_target" );
379+
verboseUnlink( $initramfs_target, "" );
380+
exit 1;
381+
}
382+
383+
# Prune old versions of the kernel
345384
pruneVersions( $kern_groups, $runConf{version}, $component_versions );
346385

347-
# Map kernel to initramfs and prune
386+
# Map each kernel to initramfs and prune those too
348387
keys %$kern_groups;
349388
while ( my ( $kver, $image ) = each %$kern_groups ) {
350389
foreach (@$image) {
@@ -357,25 +396,49 @@ if ( enabled $config{Components} ) {
357396
$kernel_target = sprintf( "%s-bootmenu", $component_prefix );
358397
$initramfs_target = sprintf( "%s/initramfs-bootmenu.img", $config{Components}{ImageDir} );
359398

360-
my $kernel_backup = sprintf( "%s-backup", $kernel_target );
361-
my $initramfs_backup = sprintf( "%s/initramfs-bootmenu-backup.img", $config{Components}{ImageDir} );
399+
# Copy to a placeholder location to ensure success
400+
my ( $init_fh, $init_tempfile ) = tempfile( "init.XXXXXX", DIR => $config{Components}{ImageDir}, UNLINK => 0 );
401+
close $init_fh;
402+
403+
unless ( safeCopy( $initramfs, $init_tempfile, 0 ) ) {
404+
verboseUnlink( $init_tempfile, "Failed to create $initramfs_target" );
405+
exit 1;
406+
}
362407

363-
if ( -f $kernel_target and safeCopy( $kernel_target, $kernel_backup ) ) {
408+
my ( $kern_fh, $kern_tempfile ) = tempfile( "kern.XXXXXX", DIR => $config{Components}{ImageDir}, UNLINK => 0 );
409+
close $kern_fh;
410+
411+
unless ( safeCopy( $runConf{kernel}, $kern_tempfile, 0 ) ) {
412+
verboseUnlink( $kern_tempfile, "Failed to create $kernel_target" );
413+
verboseUnlink( $init_tempfile, "" );
414+
exit 1;
415+
}
416+
417+
# Roll backups
418+
my $kernel_backup = sprintf( "%s-backup", $kernel_target );
419+
if ( -f $kernel_target and rename( $kernel_target, $kernel_backup ) ) {
364420
printf "Created backup %s -> %s\n", $kernel_target, $kernel_backup;
365421
}
366422

367-
if ( -f $initramfs_target and safeCopy( $initramfs_target, $initramfs_backup ) ) {
423+
my $initramfs_backup = sprintf( "%s/initramfs-bootmenu-backup.img", $config{Components}{ImageDir} );
424+
if ( -f $initramfs_target and rename( $initramfs_target, $initramfs_backup ) ) {
368425
printf "Created backup %s -> %s\n", $initramfs_target, $initramfs_backup;
369426
}
370-
}
371427

372-
make_path $config{Components}{ImageDir};
428+
unless ( rename( $init_tempfile, $initramfs_target ) ) {
429+
verboseUnlink( $init_tempfile, "Failed to create $initramfs_target" );
430+
verboseUnlink( $kern_tempfile, "" );
431+
exit 1;
432+
}
373433

374-
safeCopy( $runConf{kernel}, $kernel_target, 0 ) or exit 1;
375-
printf "Created kernel image %s\n", $kernel_target;
434+
unless ( rename( $kern_tempfile, $kernel_target ) ) {
435+
verboseUnlink( $kern_tempfile, "Failed to create $kernel_target" );
436+
exit 1;
437+
}
438+
}
376439

377-
safeCopy( $initramfs, $initramfs_target, 0 ) or exit 1;
378440
printf "Created initramfs image %s\n", $initramfs_target;
441+
printf "Created kernel image %s\n", $kernel_target;
379442
}
380443

381444
# Generate syslinux.cfg, requires components to be built
@@ -660,14 +723,21 @@ sub purgeFiles {
660723
}
661724

662725
sub verboseUnlink {
663-
my $file = shift;
726+
my ( $file, $message ) = @_;
664727

665728
return unless ( -f $file );
666729

730+
# If a message is defined, display regardless of unlink success
731+
if ( defined $message and ( $message ne "" ) ) {
732+
print "$message\n";
733+
}
734+
667735
if ( unlink $file ) {
668-
print "Removed file $file\n";
736+
737+
# Print a default success message if none was defined
738+
print "Removed file $file\n" unless ( defined $message );
669739
} else {
670-
print "Unable to remove $file: $!\n";
740+
print "ERROR: unable to remove $file: $!\n";
671741
}
672742
}
673743

0 commit comments

Comments
 (0)