# HG changeset patch # User Heiko Schlittermann # Date 1264978681 -3600 # Node ID a61b92c603672c8b432afe0bf01b7e0a13bbf9b5 # Parent bdc967bf50d29e21ee910406833a8a79541586c4 recovery works diff -r bdc967bf50d2 -r a61b92c60367 is --- a/is Sun Jan 31 01:17:32 2010 +0100 +++ b/is Sun Jan 31 23:58:01 2010 +0100 @@ -14,6 +14,8 @@ use SI::system; use SI::ptable; use SI::lvm; +use SI::dumper; +use SI::grub; my $ME = basename $0; my $opt_base = ".."; @@ -43,10 +45,13 @@ do "$src/info/devices"; my %devices = %$VAR1; -# SI::ptable::restore(%devices); -# SI::ptable::mkfs(%devices); - SI::lvm::pvcreate(%devices); - SI::lvm::vgcfgrestore("$src/lvm/vg.*", %devices); + #SI::ptable::restore(%devices); + #SI::ptable::mkfs(%devices); + #SI::lvm::pvcreate(%devices); + #SI::lvm::vgcfgrestore("$src/lvm/vg.*", %devices); + #SI::lvm::mkfs(%devices); + #SI::dumper::restore("$src/dump/*", %devices); + SI::grub::restore(%devices); exit; diff -r bdc967bf50d2 -r a61b92c60367 lib/SI/dumper.pm --- a/lib/SI/dumper.pm Sun Jan 31 01:17:32 2010 +0100 +++ b/lib/SI/dumper.pm Sun Jan 31 23:58:01 2010 +0100 @@ -5,6 +5,8 @@ use warnings; use SI::tools; use File::Basename; +use File::Temp qw(tempdir); +use File::Find; sub dump($\%) { my ($file, $devs) = @_; @@ -24,6 +26,39 @@ } } +sub restore($\%) { + my @dumps = glob(shift); + my $devs = shift; + + my $tmpdir = tempdir (CLEANUP => 1); + + foreach my $dump (@dumps) { + # suppose it's gzipped + # find the device + my $dev; + my $base = basename($dump); + find(sub { + return if defined $dev; + if ($_ eq $base) { + $dev = $File::Find::name; + return; + } }, "/dev"); + my $fs = $devs->{volume}{$dev}{type}; + + verbose("restore $dump -> $dev : $fs\n"); + run("mount -t $fs $dev $tmpdir"); + my $pid = fork or do { + open(STDIN, $dump) or die "Can't open $dump as STDIN: $!\n"; + chdir $tmpdir or die "Can't chdir to $tmpdir: $!\n"; + exec restore => "-orf-"; + die "Can't exec restore: $!\n"; + }; + waitpid($pid, 0); + run("umount $tmpdir"); + } +} + + 1; # vim:sts=4 sw=4 aw ai sm: diff -r bdc967bf50d2 -r a61b92c60367 lib/SI/grub.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/SI/grub.pm Sun Jan 31 23:58:01 2010 +0100 @@ -0,0 +1,72 @@ +package SI::grub; + +use if $ENV{DEBUG} ~~ /grub|all/ => "Smart::Comments"; +use strict; +use warnings; +use File::Temp qw(tempdir); +use IO::File; + +use SI::tools; + +sub restore(\%) { + my $devs = shift; + + # assume the first ext is the boot device (should have + # been labeled + + my ($boot, undef) = grep { $devs->{volume}{$_}{type} =~ /^ext/ } + grep { $devs->{volume}{$_}{origin} eq "ptable" } + grep { defined $devs->{volume}{$_}{type} } + sort keys %{$devs->{volume}}; + + # now find the partition containing the fstab, it should + # be the root file system + my $tmpdir = tempdir(CLEANUP => 0); + + my @fs = + grep { $devs->{volume}{$_}{type} =~ /^ext/ } + grep { defined $devs->{volume}{$_}{type} } + keys %{$devs->{volume}}; + + + my @mounted; + eval { + + foreach (@fs) { + run("mount -oro -t $devs->{volume}{$_}{type} $_ $tmpdir"); + last if -f "$tmpdir/etc/fstab"; + run("umount $tmpdir"); + push @mounted, $tmpdir; + } + + # and now try to mount the rest + + + my $fstab = new IO::File "$tmpdir/etc/fstab"; + foreach (grep { /^\// } <$fstab>) { + my ($dev, $mp, $type, $options, undef) = split; + next if $options =~ /noauto/ + or $mp eq "/" + or $mp !~ /^\//; + run("mount -t $type $dev $tmpdir/$mp"); + push @mounted, "$tmpdir/$mp"; + } + close($fstab); + + run("mount -o bind /dev $tmpdir/dev"); + push @mounted, "$tmpdir/dev"; + + run("chroot $tmpdir grub-mkdevicemap"); + run("chroot $tmpdir /usr/sbin/grub-install '(hd0)'"); + #system("/bin/bash --login"); + }; + if ($@) { + warn "** EVAL: $@\n"; + } + map { system("umount $_") } reverse @mounted; + rmdir($tmpdir); + +} + +1; +# vim:sts=4 sw=4 aw ai sm: diff -r bdc967bf50d2 -r a61b92c60367 lib/SI/lvm.pm --- a/lib/SI/lvm.pm Sun Jan 31 01:17:32 2010 +0100 +++ b/lib/SI/lvm.pm Sun Jan 31 23:58:01 2010 +0100 @@ -84,10 +84,12 @@ my $devs = shift; foreach (@cfgs) { - my $vg = basename($_); - next if $vg eq "vg.*"; - print $vg, "\n"; + my $vg = (split /\./, basename($_))[1]; + next if $vg eq "*"; + run("vgcfgrestore -f $_ $vg"); + run("vgchange -ay $vg"); } + run("udevadm settle"); } sub mkfs(\%) { @@ -97,15 +99,15 @@ next if $v->{origin} ne "lvm" or not defined $v->{type}; - my $label = default("" => $v->{label}); - my $uuid = default("" => $v->{uuid}); + my $label = defined $v->{label} ? "-L '$v->{label}'" : ""; + my $uuid = defined $v->{uuid} ? "-U '$v->{uuid}'" : ""; given($v->{type}) { when(/ext/) { - run("mkfs -t $v->{type} -L '$label' -U '$uuid' $volume"); + run("mkfs -t $v->{type} $label $uuid $volume"); }; when(/swap/) { - run("mkswap -L '$label' -U '$uuid' $volume"); + run("mkswap $label $uuid $volume"); }; } } diff -r bdc967bf50d2 -r a61b92c60367 lib/SI/ptable.pm --- a/lib/SI/ptable.pm Sun Jan 31 01:17:32 2010 +0100 +++ b/lib/SI/ptable.pm Sun Jan 31 23:58:01 2010 +0100 @@ -75,11 +75,12 @@ die "I won't use the disk ($disk) I'm running on!" if (stat $0)[0] ~~ [ map { (stat)[6] } map { "/dev/" . basename dirname $_ } glob ("/sys/block/" . basename($disk) . "/*/partition")]; - my $sfdisk = new IO::File "|sfdisk $disk >/dev/null" + my $sfdisk = new IO::File "|sfdisk --force $disk >/dev/null" or die "Can't open |sfdisk $disk: $!\n"; print {$sfdisk} @{$devs->{disk}{$disk}{pt}}; $sfdisk->close or die $? >> 8; run("partprobe $disk"); + run("udevadm settle"); } } diff -r bdc967bf50d2 -r a61b92c60367 lib/SI/tools.pm --- a/lib/SI/tools.pm Sun Jan 31 01:17:32 2010 +0100 +++ b/lib/SI/tools.pm Sun Jan 31 23:58:01 2010 +0100 @@ -8,7 +8,7 @@ use Data::Dumper; use base "Exporter"; -our @EXPORT = qw(&run &verbose &find_by_devid &cat &barf &default); +our @EXPORT = qw(&run &verbose &find_by_devid &cat &barf &def); sub run(@) { system(@_); @@ -16,7 +16,7 @@ if $?; } -sub default($$) { +sub def($$) { return defined $_[1] ? $_[1] : $_[0]; }