diff -r de0a25512844 -r 7d7ca3f05f25 lib/SI/lvm.pm --- /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: