--- /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/
--- 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;
--- /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:
--- 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;
--- /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;
--- 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:
--- 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:
--- 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: