# HG changeset patch # User Heiko Schlittermann # Date 1263682984 -3600 # Node ID 1a6f6cfc46ea7adead1c01c6dda5415b9659513e # Parent 03ca6d811a17b9f49584afff8b60bb4af4e4f00f# Parent 2a66bb6a6a6ef2e46403307be210131244c59131 [savepoint] diff -r 2a66bb6a6a6e -r 1a6f6cfc46ea .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sun Jan 17 00:03:04 2010 +0100 @@ -0,0 +1,2 @@ +syntax: glob +out/ diff -r 2a66bb6a6a6e -r 1a6f6cfc46ea SI/blkid.pm --- a/SI/blkid.pm Sun Jan 17 00:00:02 2010 +0100 +++ b/SI/blkid.pm Sun Jan 17 00:03:04 2010 +0100 @@ -4,7 +4,12 @@ use warnings; use File::Find; -sub ff($$) { + +use if $ENV{DEBUG} ~~ /blkid|all/ => "Smart::Comments"; + +use SI::tools; + +sub find_by_devid($$) { my ($dir, $id) = @_; my $found; find( @@ -18,33 +23,40 @@ return $found; } -sub info($\%) { - my ($file, $part) = @_; + +sub ids($\%) { + my ($file, $devs) = @_; + verbose("reading blkids:"); foreach (`blkid -c /dev/null`) { - my ($dev) = (split /:/)[0]; + my $dev = (split /:/)[0]; + ### $dev + verbose($dev); my ($uuid) = /\sUUID=.(.*?).\s/; my ($type) = /\sTYPE=.(.*?).\s/; my ($label) = /\sLABEL=.(.*?).\s/; - if ($dev ~~ $part->{physical}) { - $part->{physical}{$dev}{uuid} = $uuid; - $part->{physical}{$dev}{type} = $type; - $part->{physical}{$dev}{label} = $label; - next; - } + #if ($dev ~~ $devs->{physical}) { + #$devs->{physical}{$dev}{uuid} = $uuid; + #$devs->{physical}{$dev}{type} = $type; + #$devs->{physical}{$dev}{label} = $label; + #next; + #} - # dev mapper names should be replace by nicer ones + # dev mapper names should be replaced by nicer ones if ($dev ~~ /^\/dev\/dm-/) { - $dev = ff("/dev/mapper", (stat $dev)[6]) - or next; - $part->{logical}{$dev}{uuid} = $uuid; - $part->{logical}{$dev}{type} = $type; - $part->{logical}{$dev}{label} = $label; - } + $dev = find_by_devid("/dev/mapper", (stat $dev)[6]); + }; + + if (exists $devs->{volume}{$dev}) { + $devs->{volume}{$dev}{uuid} = $uuid; + $devs->{volume}{$dev}{type} = $type; + $devs->{volume}{$dev}{label} = $label; + } } + verbose("\n"); } 1; diff -r 2a66bb6a6a6e -r 1a6f6cfc46ea SI/dumper.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SI/dumper.pm Sun Jan 17 00:03:04 2010 +0100 @@ -0,0 +1,22 @@ +package SI::dumper; + +use strict; +use warnings; +use SI::tools; +use if $ENV{DEBUG} ~~ /dumper|all/ => "Smart::Comments"; + +sub dump($\%) { + my ($file, $devs) = @_; + + ### $devs + + my %volume = %{$devs->{volume}}; + + foreach my $v ( grep { $volume{$_}{type} ~~ /^ext/ } keys %volume ) { + verbose("dumping $v\n"); + } +} + +1; + +# vim:sts=4 sw=4 aw ai sm: diff -r 2a66bb6a6a6e -r 1a6f6cfc46ea SI/lvm.pm --- a/SI/lvm.pm Sun Jan 17 00:00:02 2010 +0100 +++ b/SI/lvm.pm Sun Jan 17 00:03:04 2010 +0100 @@ -2,30 +2,61 @@ use strict; use warnings; +use IO::File; + +use if $ENV{DEBUG} ~~ /lvm|all/ => qw(Smart::Comments); + use SI::tools; -sub vg_info($\%) { - my ($file, $part) = @_; - foreach (map { (split /:/)[0] } - map { /^\s*(.*)/; } `vgs --noheadings --separator :`) - { - my $file = sprintf $file, $_; - run("vgcfgbackup -f $file >/dev/null"); - } +my @volumegroups = (); + +sub _vgs(\%) { + return @volumegroups if @volumegroups; + + my $devs = shift; + + my @pvs = grep { $devs->{volume}{$_}{type} =~ /^lvm/ } + grep { defined $devs->{volume}{$_} } + keys %{$devs->{volume}}; + + return @volumegroups = map { (split /:/)[1] } `pvdisplay -c @pvs`; } -sub lv_info($\%) { - my ($file, $part) = @_; +sub volumes(\%) { + my ($devs) = @_; + + # we can't just use `pvs', since this would return *all* + # physical devices known to lvm, not just the non-removable + my @pvs = grep { $devs->{volume}{$_}{type} =~ /^lvm/ } + grep { defined $devs->{volume}{$_} } + keys %{$devs->{volume}}; + + my @vgs = _vgs(%$devs); + my @lvs = map { readlink } + map { s/^\s*//; (split /:/)[0] } + grep { (split /:/)[1] ~~ @vgs } `lvdisplay -c`; - foreach my $p (keys %$part) { - `pvs -o +uuid --nameprefix --noheadings $p` =~ /\bLVM2_PV_UUID='(.*?)'/ - or next; + @{$devs->{volume}}{@lvs} = (); + + +} + +sub vgcfgbackup($\%) { + my ($file, $devs) = @_; - $part->{$p}{type} = "pv"; - $part->{$p}{uuid} = $1; - + # we save it vg by vg to have the restore more easy + my @vgs = _vgs(%$devs); + foreach ( map { s/^\s*(.*)/$1/; $_ = (split /:/)[0] } `vgs --noheadings --separator : @vgs`) + { + verbose("saving vg $_\n"); + my $file = sprintf $file, $_; + run("vgcfgbackup -f $file $_ >/dev/null"); } + # for testing let's save it all + verbose("saving vg *\n"); + $file = sprintf $file, "*"; + run("vgcfgbackup -f '$file' >/dev/null"); } 1; diff -r 2a66bb6a6a6e -r 1a6f6cfc46ea SI/mbr.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SI/mbr.pm Sun Jan 17 00:03:04 2010 +0100 @@ -0,0 +1,24 @@ +package SI::mbr; + +use strict; +use warnings; +use File::Basename; +use if $ENV{DEBUG} ~~ q(mbr) => "Smart::Comments"; + +use SI::tools; + +sub save($\%) { + my ($file, $devs) = @_; + + + foreach my $disk (keys %{$devs->{disks}}) { + verbose("saving mbr of $disk\n"); + open((my $o), $_ = sprintf(">$file", basename($disk))) or die "Can't open $_: $!\n"; + local $/ = \512; + + open(my $in, $disk) or die "Can't open $disk: $!\n"; + print $o $_ = <$in>; + } +} + +1; diff -r 2a66bb6a6a6e -r 1a6f6cfc46ea SI/ptable.pm --- a/SI/ptable.pm Sun Jan 17 00:00:02 2010 +0100 +++ b/SI/ptable.pm Sun Jan 17 00:03:04 2010 +0100 @@ -2,53 +2,55 @@ use strict; use warnings; -use if $ENV{DEBUG} ~~ "ptable" => "Smart::Comments"; use File::Find; +use IO::File; -$ENV{LC_ALL} = "C"; +use if $ENV{DEBUG} ~~ /ptable|all/ => qw(Smart::Comments); use SI::tools; - -sub info($\%) { - my ($file, $part) = @_; +$ENV{LC_ALL} = "C"; - # find major of devmapper - my $devmapper = 0; - { - local $/ = undef; - open(my ($i), "/proc/devices") - or die "ERR: Can't open /proc/devices: $!\n"; - ($devmapper) = <$i> =~ /^\s*(\d+)\s+device.mapper\b/m; - } +sub volumes($\%) { + my ($file, $devs) = @_; - my ($current, %dev); + # find the non-removable devices + my ($current, $of); foreach (`sfdisk -d 2>/dev/null`) { chomp; - ### $_ - if (/^# partition table .*?(\/\S+)/) { - $current = (stat $1)[6] >> 8 == $devmapper ? undef : $1 - and push(@{ $dev{$current} }, $_); - next; + if (/^# partition table .*?(\/\S+\/(\S+))/) { + # skip the removable devices + my ($device, $name) = ($1, $2); + verbose("device $device"); + if ((grep { /ATTR{removable}/ } `udevadm info --attribute-walk --name $name`)[0] !~ /==.0./) { + $current = undef; + verbose("skipping (removable)\n"); + next; + } + + # save in our data structure + verbose("scanning\n"); + $current = $device; + push @{$devs->{disk}{$current}{pt}}, $_; + + # and open the outfile + my $f = sprintf ">$file", $name; + $of = new IO::File $f or die "ERR: Can't open $f: $!\n"; + print $of "$_\n"; + + next; } next if not $current; - push @{ $dev{$current} }, $_; - } - ### partiton tables of useful blockdevices: - ### %dev + push @{$devs->{disk}{$current}{pt}}, $_; + print $of "$_\n"; - # process the partition tables - # and output the tables for relevant devices - foreach my $dev (keys %dev) { - ($_ = $dev) =~ s/^.*\///; - my $file = sprintf $file, $_; - die "ERR: $file exists already\n" if -f $file; - open(my $o, ">$file") or die "ERR: Can't open $file: $!\n"; - print $o join "\n", @{ $dev{$dev} }, ""; + if (/^(\/dev\/\S+)\s*:/) { + $devs->{volume}{$1} = undef; + } + } - # reserve entries in %part, one for each partition - @{ $part->{physical} }{ map { (split)[0] } - grep { /^\// } map { @$_ } values %dev } = (); +### $devs + return; } 1; # vim:sts=4 sw=4 aw ai si: diff -r 2a66bb6a6a6e -r 1a6f6cfc46ea SI/tools.pm --- a/SI/tools.pm Sun Jan 17 00:00:02 2010 +0100 +++ b/SI/tools.pm Sun Jan 17 00:03:04 2010 +0100 @@ -3,13 +3,22 @@ use strict; use warnings; use base "Exporter"; -our @EXPORT = qw(&run); +our @EXPORT = qw(&run &verbose); +use if $ENV{DEBUG} ~~ /tools|all/ => "Smart::Comments"; sub run(@) { system(@_); - die "$_[0] failed with exit code " . $? >> 8 . "\n" + die "$_[0] failed with exit code " . ($? >> 8) . "\n" if $?; } +my $last = "\n"; +sub verbose(@) { + print $last eq "\n" ? "" : " " + if not(@_ == 1 and length($_[0]) == 1); + print @_; + $last = substr($_[-1], -1, 1); +}; + 1; # vim:sts=4 sw=4 aw ai si: diff -r 2a66bb6a6a6e -r 1a6f6cfc46ea si --- a/si Sun Jan 17 00:00:02 2010 +0100 +++ b/si Sun Jan 17 00:03:04 2010 +0100 @@ -3,25 +3,38 @@ use strict; use warnings; -use if $ENV{DEBUG} => "Smart::Comments"; +use if $ENV{DEBUG} ~~ /main|all/ => "Smart::Comments"; -use SI::system; +use Sys::Hostname; + use SI::ptable; use SI::blkid; use SI::lvm; - -my $OUT = "out"; +use SI::mbr; +use SI::dumper; +use SI::system; -unlink(glob("$OUT/*")); --d $OUT or mkdir($OUT, 0700) or die "Can't mkdir $OUT: $!\n"; +MAIN: { + my $OUT = "../out-" . hostname; + + unlink(glob("$OUT/*")); + -d $OUT or mkdir($OUT, 0700) or die "Can't mkdir $OUT: $!\n"; -my %devices; + my %devices; + + SI::system::id("$OUT/system"); -SI::system::id("$OUT/system"); -SI::ptable::info("$OUT/partitions.%s", %devices); -SI::blkid::info("$OUT/blkid", %devices); -SI::lvm::vg_info("$OUT/vg.%s", %devices); + SI::ptable::volumes("$OUT/partitions.%s", %devices); + SI::lvm::volumes(%devices); + SI::blkid::ids("$OUT/blkid", %devices); + SI::lvm::vgcfgbackup("$OUT/vg.%s", %devices); + SI::mbr::save("$OUT/mbr.%s", %devices); + SI::dumper::dump("$OUT/dump.%s", %devices); +### %devices + exit; ### %devices; + } + # vim:sts=4 sw=4 aw ai si: