# HG changeset patch # User Heiko Schlittermann # Date 1263941154 -3600 # Node ID fd87c1e3b4512ba02087ac476e095677484bf22e # Parent 4e3753b998a93d363f32de2267b01e2a1c321c15 Works in KVM/Qemu now. diff -r 4e3753b998a9 -r fd87c1e3b451 SI/blkid.pm --- a/SI/blkid.pm Tue Jan 19 14:49:43 2010 +0100 +++ b/SI/blkid.pm Tue Jan 19 23:45:54 2010 +0100 @@ -4,6 +4,8 @@ use strict; use warnings; +use IO::File; +use File::Basename; use SI::tools; @@ -24,6 +26,26 @@ $devs->{volume}{$dev}{uuid} = $uuid; $devs->{volume}{$dev}{type} = $type; $devs->{volume}{$dev}{label} = $label; + + my ($of, $oh); + if (defined $uuid) { + $of = sprintf $file, "uuid." . basename $dev; + $oh = new IO::File ">$of" or die "ERR: Can't open $of: $!\n"; + $oh->print("$uuid\n"); + } + + if (defined $label) { + $of = sprintf $file, "label." . basename $dev; + $oh = new IO::File ">$of" or die "ERR: Can't open $of: $!\n"; + $oh->print("$label\n"); + } + + if (defined $type) { + $of = sprintf $file, "type." . basename $dev; + $oh = new IO::File ">$of" or die "ERR: Can't open $of: $!\n"; + $oh->print("$type\n"); + } + } } diff -r 4e3753b998a9 -r fd87c1e3b451 SI/dumper.pm --- a/SI/dumper.pm Tue Jan 19 14:49:43 2010 +0100 +++ b/SI/dumper.pm Tue Jan 19 23:45:54 2010 +0100 @@ -6,34 +6,17 @@ use SI::tools; use File::Basename; -my @cleanup; -END { - #map { eval { run("lvchange -an $_ 2>/dev/null") } } @cleanup; - #map { eval { run("lvremove -ff $_ 2>/dev/null") } } @cleanup; -} - sub dump($\%) { my ($file, $devs) = @_; foreach my $volume ( map { { name => $_, %{$devs->{volume}{$_}}}} keys %{$devs->{volume}}) { next if !defined $volume->{type} or $volume->{type} !~ /^ext/i; + system("fsck -f -C0 $volume->{name}"); + die "ERR: fsck failed\n" if $? > 2; + verbose("dumping volume $volume->{name}"); my $dumpdev = $volume->{name}; - -# if ($volume->{origin} =~ /lvm/i) { -# verbose("(lvm)"); -# my ($vg, $lv) = `lvdisplay -c $volume->{name}` =~ /\s*\/dev\/(.*?)\/(.*?):/; -# my $snap = "snap$$"; -# push @cleanup, "$vg/$lv"; -# -# #eval { -# # run("lvcreate -s -L 1G -n snap$$ $vg/$lv 2>/dev/null"); -# #}; -# if ($@) { warn "Can't create snapshot\n" } -# else { $dumpdev = "/dev/$vg/$snap$$" }; -# } - my $of = sprintf $file, basename($volume->{name}); run("dump -0 -z -f $of $dumpdev"); verbose("\n"); diff -r 4e3753b998a9 -r fd87c1e3b451 SI/lvm.pm --- a/SI/lvm.pm Tue Jan 19 14:49:43 2010 +0100 +++ b/SI/lvm.pm Tue Jan 19 23:45:54 2010 +0100 @@ -17,10 +17,13 @@ my $devs = shift; + # find the physical volumes we've already recognised as „non-removable“ + my @known = keys %{$devs->{volume}}, keys %{$devs->{disk}}; - # find the physical volumes we've already recognised as „non-removable“ - my @pvs = grep { $_ ~~ $devs->{known} } map { s/\s*//; (split /:/)[0] } `pvdisplay -c`; - return @volumegroups = map { (split /:/)[1] } `pvdisplay -c @pvs 2>/dev/null`; + my @pvs = grep { $_ ~~ @known } map { s/\s*//; (split /:/)[0] } `pvdisplay -c`; + @volumegroups = map { (split /:/)[1] } `pvdisplay -c @pvs 2>/dev/null`; + run("vgchange -ay @volumegroups 2>&1 >/dev/null"); + return @volumegroups; } sub volumes(\%) { @@ -30,8 +33,6 @@ # physical devices known to lvm, not just the non-removable my @vgs = _vgs(%$devs); - run("vgchange -ay @vgs 2>/dev/null"); - my @lvs = map { abs_path ((dirname $_) . "/" . readlink) } map { s/^\s*//; (split /:/)[0] } diff -r 4e3753b998a9 -r fd87c1e3b451 SI/ptable.pm --- a/SI/ptable.pm Tue Jan 19 14:49:43 2010 +0100 +++ b/SI/ptable.pm Tue Jan 19 23:45:54 2010 +0100 @@ -19,21 +19,23 @@ # LVs (used as disk itself) too) foreach (glob("/sys/block/*")) { my $name = basename($_); - # verbose("device $name"); + my $dev = "/dev/$name"; + + next if !-e "$_/device"; + next if (grep { /ATTR{removable}/ } `udevadm info --attribute-walk --name $name`)[0] !~ /==.0./; + next if (stat $dev)[0] == (stat $0)[0]; - if (!-e "$_/device") { - # verbose("skipping (non-dev)\n"); - next; - } - if ((grep { /ATTR{removable}/ } `udevadm info --attribute-walk --name $name`)[0] !~ /==.0./) { - # verbose("skipping (removable)\n"); - next; - } + # exclude the device (stick) we're part of - this HACK is + # only useful on KVM - the usb stick doesn't appear as a removeable + # device + next if (stat $0)[0] ~~ [map { (stat)[6] } map { "/dev/" . basename(dirname $_) } glob("$_/*/partition")]; + + verbose("\n"); - verbose("device $name\n"); + verbose("device $dev\n"); - die "ERR: /dev/$name does not exist. (should not happen)" - if !-e "/dev/$name"; + die "ERR: $dev does not exist. (should not happen): $!" + if !-b $dev; # now the physical disk -- let's ask for the partition table @@ -47,8 +49,6 @@ pt => \@sfdisk }; - push @{$devs->{known}}, "/dev/$name"; - # and let's prepare the volume entries foreach (@sfdisk) { /^(\S+)\s*:.*Id=\s*([[:xdigit:]]+)/ or next; @@ -56,7 +56,6 @@ origin => "ptable", ptable_type => $2, }; - push @{$devs->{known}}, $1; } } diff -r 4e3753b998a9 -r fd87c1e3b451 SI/system.pm --- a/SI/system.pm Tue Jan 19 14:49:43 2010 +0100 +++ b/SI/system.pm Tue Jan 19 23:45:54 2010 +0100 @@ -2,7 +2,9 @@ use strict; use warnings; +use File::Temp qw(tempdir); use if $ENV{DEBUG} ~~ qw(system) => "Smart::Comments"; +use SI::tools; $ENV{LC_ALL} = "C"; @@ -14,5 +16,24 @@ die "ERR: Can't get system identification (MAC address)\n"; } +sub hostname(\%) { + my $devs = shift; + my $mnt = tempdir(CLEANUP => 1); + my $r; + + foreach my $fs (grep { $devs->{volume}{$_}{type} =~ /^ext/i } + grep { exists $devs->{volume}{$_}{type} } + keys %{$devs->{volume}}) { + run("mount -r $fs $mnt"); + if (-f "$mnt/etc/hostname") { + die "ERR: found 2nd hostname" if defined $r; + chomp($r = cat("$mnt/etc/hostname")); + } + run("umount $mnt"); + } + + return $r; +} + 1; # vim:sts=4 sw=4 aw ai si: diff -r 4e3753b998a9 -r fd87c1e3b451 si --- a/si Tue Jan 19 14:49:43 2010 +0100 +++ b/si Tue Jan 19 23:45:54 2010 +0100 @@ -11,7 +11,7 @@ use IO::File; use Sys::Hostname; use Getopt::Long; -use File::Path; +use File::Path qw(make_path remove_tree); use File::Basename; use SI::ptable; @@ -38,31 +38,38 @@ } else { $dir = dirname($0) . "/../image-" . SI::system::id(); - rmtree($dir); + remove_tree($dir); -d $dir or mkdir($dir, 0700) or die "Can't mkdir $dir: $!\n"; } + make_path(map { "$dir/$_" } qw(ptable lvm blkid mbr dump)); - SI::ptable::volumes("$dir/partitions.%s", %devices); + SI::ptable::volumes("$dir/ptable/%s", %devices); die Dumper \%devices if $opt_exit =~ /ptable/; SI::lvm::volumes(%devices); die Dumper \%devices if $opt_exit =~ /lvm::volumes/; - SI::blkid::ids("$dir/blkid", %devices); + SI::blkid::ids("$dir/blkid/%s", %devices); die Dumper \%devices if $opt_exit =~ /blkid/; - SI::lvm::vgcfgbackup("$dir/vg.%s", %devices); + SI::lvm::vgcfgbackup("$dir/lvm/vg.%s", %devices); die Dumper \%devices if $opt_exit =~ /lvm::vgcfg/; - SI::mbr::save("$dir/mbr.%s", %devices); + SI::mbr::save("$dir/mbr/%s", %devices); die Dumper \%devices if $opt_exit =~ /mbr/; - SI::dumper::dump("$dir/dump.%s", %devices); + SI::dumper::dump("$dir/dump/%s", %devices); my $o = new IO::File ">$dir/devices" or die "ERR: Can't open $dir/devices: $!\n"; $o->print(Dumper \%devices); + # we wait until now, since now it's sure that + # the filesystems are checked and that we mount the + # devices we need + my $hostname = SI::system::hostname(%devices); + symlink(basename($dir), "../image-$hostname"); + exit;