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