diff -urN e-smith-backup-2.6.0.old/root/usr/share/perl5/vendor_perl/esmith/BlockDevices.pm e-smith-backup-2.6.0/root/usr/share/perl5/vendor_perl/esmith/BlockDevices.pm --- e-smith-backup-2.6.0.old/root/usr/share/perl5/vendor_perl/esmith/BlockDevices.pm 2020-05-02 13:39:33.924455002 +0100 +++ e-smith-backup-2.6.0/root/usr/share/perl5/vendor_perl/esmith/BlockDevices.pm 2020-05-02 13:41:24.619648065 +0100 @@ -114,6 +114,13 @@ { if (/.*\/(.*?)\.ko/s){$fs {$1}=$1;} } + + # If ext4 driver is present, add ext2 and ext3 + if(exists($fs{ext4})) + { + $fs{'ext2'}='ext2'; + $fs{'ext3'}='ext3'; + } return \%fs; } diff -urN e-smith-backup-2.6.0.old/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm e-smith-backup-2.6.0/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm --- e-smith-backup-2.6.0.old/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm 2020-05-02 13:39:33.894454681 +0100 +++ e-smith-backup-2.6.0/root/usr/share/perl5/vendor_perl/esmith/console/perform_restore.pm 2020-05-02 13:41:24.622648097 +0100 @@ -8,8 +8,11 @@ use feature qw( say ); use esmith::BlockDevices; use Taint::Util; +use esmith::Backup; +use Data::UUID; my $EMPTY = q{}; +my $backup_lock; sub new { @@ -34,6 +37,112 @@ return $_[0]->{order}; } +sub SetLock +{ + print "Setting backup lock file\n"; + $backup_lock = esmith::Backup::set_lock; + return $backup_lock; +} + +sub RemoveLock +{ + if (defined($backup_lock)) + { + print "Removing backup lock file\n"; + esmith::Backup::remove_lock($backup_lock); + $backup_lock = undef; + } +} + +sub new_restore_id +{ + my $ug = Data::UUID->new; + my $uid = $ug->create_str(); + return $uid; +} + +sub make_restore_callback +{ + my ($mountpoint, $restoreid) = @_; + return sub { + my $fh = shift; + + # Check no other backups or restores are in progress + unless (SetLock()) { + die "Error: failed to create lock file. Is a backup or restore already running?"; + } + + open(OLDSTDOUT, ">&STDOUT"); + my $status = 0; + chdir "/"; + open(OLDSTDERR, ">&STDERR"); + my $logger = open(STDERR, "|-"); + die "Can't fork: $!\n" unless defined $logger; + + unless ($logger) + { + exec qw(/usr/bin/logger -p local1.info -t console_restore); + } + + my $tar = open(TAR, "|-"); + return "could not run tar" unless defined $tar; + unless($tar) + { + exec "tar xf -"; + } + + my $gunzip = open(GUNZIP, "|-"); + return "could not run gunzip" unless defined $gunzip; + unless($gunzip) + { + open(STDOUT, ">&TAR"); + close TAR; + exec "gunzip"; + exec "gunzip"; + } + + my $pv = fork; + return "could not run pv" unless defined $pv; + unless ($pv) + { + open(STDOUT, ">&GUNZIP"); + open(STDERR, ">&$fh"); + close GUNZIP; + close TAR; + exec "pv -n $mountpoint/smeserver.tgz"; + } + + waitpid($pv,0); + warn "status from pv was $?\n" if $?; + + unless(close GUNZIP) + { + $status |= $! ? $! : $?; + warn "status from gunzip is $status\n" if $status; + } + + unless(close TAR) + { + $status |= $! ? $! : $?; + warn "status from tar is $status\n" if $status; + } + + open(STDOUT, ">&OLDSTDOUT"); + open(STDERR, ">&OLDSTDERR"); + close(OLDSTDOUT); + close(OLDSTDERR); + + # Unlock and check for success or failure before returning + RemoveLock(); + if ($status) { + return gettext("Restore failed. Your system is likely in an inconsistent state - look at the log files for more details."); + } else { + system("touch", "/tmp/restore_$restoreid"); + return gettext("Restore successful."); + } + } +} + sub doit { my ($self, $console, $db) = @_; @@ -170,32 +279,47 @@ $devices->mount ($backupdrive); # mount the chosen filesystem sleep(1); # Some mounts take time to become active - ###ToDo This section has no error checking - ###ToDo 'Restoring data is not localized - # Execute the restore + # Prepare for restore + $console->infobox( + title => gettext("Preparing for restore"), + text => gettext("Please stand by while the system is prepared for restore..."), + ); + system("/sbin/e-smith/signal-event", "pre-restore"); - system("(cd / ; cat $mountpoint/smeserver.tgz | - pv -n -s $size | - gunzip | - tar xf - > /dev/null ) 2>&1 | - dialog --backtitle 'Restoring data' --guage 'Progress' 7 70"); - # Restore complete, now clean-up + # Create restore ID to check success later + my $restoreid = new_restore_id(); + + # Run restore + $console->gauge(make_restore_callback($mountpoint, $restoreid), 'title' => gettext('Restoring from backup')); + + # Restore complete, now clean-up. Only post-upgrade and reboot if the restore was successful. $devices->destroy; - system("/sbin/e-smith/signal-event", "post-upgrade"); - unless ( $self->{bootstrap} ) - { + + if (-e "/tmp/restore_$restoreid") { + system("/sbin/e-smith/signal-event", "post-upgrade"); + $db->set_prop("bootstrap-console", "Run", "yes"); $db->set_prop("bootstrap-console", "ForceSave", "yes"); $db->set_prop("bootstrap-console", "Restore", "disabled"); - system("/usr/bin/tput", "clear"); - system("/sbin/e-smith/signal-event", "reboot"); - - # A bit of a hack to avoid the console restarting before the - # reboot takes effect. - - sleep(600); + unless ( $self->{bootstrap} ) + { + ($rc, $choice) = $console->yesno_page + ( + title => gettext("Restore Complete"), + text => gettext('You must restart your system to finish the restore.')."\n\n". + gettext('Do you want to restart now?'), + ); + return unless ($rc == 0); + + system("/usr/bin/tput", "clear"); + system("/sbin/e-smith/signal-event", "reboot"); + + # A bit of a hack to avoid the console restarting before the + # reboot takes effect. + sleep(600); + } } return; }