Works in KVM/Qemu now.
authorHeiko Schlittermann <hs@schlittermann.de>
Tue, 19 Jan 2010 23:45:54 +0100
changeset 16 fd87c1e3b451
parent 15 4e3753b998a9
child 17 d4942418a9ea
Works in KVM/Qemu now.
SI/blkid.pm
SI/dumper.pm
SI/lvm.pm
SI/ptable.pm
SI/system.pm
si
--- 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");
+	    }
+
 	}
 
     }
--- 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");
--- 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] } 
--- 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;
 	    }
     }
 
--- 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:
--- 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;