lib/SI/lvm.pm
changeset 28 7d7ca3f05f25
parent 26 39421a9700c5
child 36 bdc967bf50d2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/SI/lvm.pm	Wed Jan 20 21:52:01 2010 +0100
@@ -0,0 +1,72 @@
+package SI::lvm;
+
+use if $ENV{DEBUG} ~~ /lvm|all/ => qw(Smart::Comments);
+
+use strict;
+use warnings;
+use IO::File;
+use Cwd qw(abs_path);
+use File::Basename;
+
+use SI::tools;
+
+my @volumegroups = ();
+
+sub _vgs(\%) {
+    return @volumegroups if @volumegroups;
+
+    my $devs = shift;
+
+    # find the physical volumes we've already recognised as „non-removable“
+    my @known = keys %{ $devs->{volume} }, keys %{ $devs->{disk} };
+
+    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");
+
+    # we wait for the /dev/mapper devices to appear
+    run("udevadm settle");
+    return @volumegroups;
+}
+
+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 @vgs = _vgs(%$devs);
+    my @lvs =
+      map { abs_path((dirname $_) . "/" . readlink) }
+      map { s/^\s*//; (split /:/)[0] }
+      grep { (split /:/)[1] ~~ @vgs } `lvdisplay -c`;
+    foreach (@lvs) {
+        $devs->{volume}{$_} = { origin => "lvm" };
+    }
+
+    push @{ $devs->{volumes} }, @lvs;
+}
+
+sub vgcfgbackup($\%) {
+    my ($file, $devs) = @_;
+
+    # 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;
+
+# vim:sts=4 sw=4 aw ai si: