summaryrefslogtreecommitdiffstats
path: root/perl-install/lvm.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/lvm.pm')
-rw-r--r--perl-install/lvm.pm90
1 files changed, 79 insertions, 11 deletions
diff --git a/perl-install/lvm.pm b/perl-install/lvm.pm
index 28a7cb41a..bf212bd6f 100644
--- a/perl-install/lvm.pm
+++ b/perl-install/lvm.pm
@@ -1,4 +1,4 @@
-package lvm; # $Id$
+package lvm;
use diagnostics;
use strict;
@@ -12,12 +12,22 @@ use devices;
use fs::type;
use run_program;
+=head1 SYNOPSYS
+
+Manage LVM (PV, VG, LV)
+
+=head1 Functions
+
+=over 4
+
+=cut
+
#- for partition_table_xxx emulation
sub new {
my ($class, $name) = @_;
$name =~ s/[^\w-]/_/g;
$name = substr($name, 0, 63); # max length must be < NAME_LEN / 2 where NAME_LEN is 128
- bless { disks => [], VG_name => $name }, $class;
+ bless { disks => [], VG_name => $name, device => $name }, $class;
}
sub use_pt_type { 0 }
sub hasExtended { 0 }
@@ -29,17 +39,38 @@ sub cylinder_size {
$hd->{extent_size};
}
-init() or log::l("lvm::init failed");
+=item detect_durting_install()
+
+Explicitly scan VGs.
+
+=cut
+
+sub detect_during_install() {
+ run_program::run('lvm2', 'vgscan');
+ run_program::run('lvm2', 'vgchange', '-a', 'y');
+}
+
+=item init()
+
+Loads LVM modules and scan VGs (if in installer, not in standalone tool).
+
+=cut
sub init() {
devices::init_device_mapper();
- if ($::isInstall) {
- run_program::run('lvm2', 'vgscan');
- run_program::run('lvm2', 'vgchange', '-a', 'y');
- }
+ detect_during_install() if $::isInstall || $::isLiveInstall;
1;
}
+init() or log::l("lvm::init failed");
+
+=item lvm_cmd(...)
+
+Run a LVM command, then rescan VG.
+See run_program::run() for arguments.
+
+=cut
+
sub lvm_cmd {
if (my $r = run_program::run('lvm2', @_)) {
$r;
@@ -47,18 +78,31 @@ sub lvm_cmd {
$? >> 8 == 98 or return;
#- sometimes, it needs running vgscan again, doing so:
+ log::l("forcing rescan because of prior failure");
run_program::run('lvm2', 'vgscan');
run_program::run('lvm2', @_);
}
}
+
+=item lvm_cmd_or_die($prog, @para)
+
+Like lvm_cmd() but die if there's an error.
+
+=cut
+
sub lvm_cmd_or_die {
my ($prog, @para) = @_;
- lvm_cmd($prog, @para) or die "$prog failed\n";
+ my @err;
+ lvm_cmd("2>", \@err, $prog, @para) or do {
+ my $err = $err[-1]; # prevent "Modification of non-creatable array value attempted"
+ chomp($err);
+ die "$prog failed: $err\n";
+ };
}
sub check {
my ($do_pkgs) = @_;
-
+ local $::prefix = ''; # We want lvm2 on current system
$do_pkgs->ensure_binary_is_installed('lvm2', 'lvm2') or return;
init();
1;
@@ -104,6 +148,12 @@ sub lv_nb_pvs {
listlength(lv_to_pvs($lv));
}
+=item get_lvs($lvm)
+
+Return list of LVs.
+
+=cut
+
sub get_lvs {
my ($lvm) = @_;
my @l = run_program::get_stdout('lvm2', 'lvs', '--noheadings', '--nosuffix', '--units', 's', '-o', 'lv_name', $lvm->{VG_name}) =~ /(\S+)/g;
@@ -111,15 +161,18 @@ sub get_lvs {
[
map {
my $device = "$lvm->{VG_name}/$_";
+ my $p = fs::wild_device::to_subpart("/dev/$device");
my $part = {
device => $device,
lv_name => $_,
rootDevice => $lvm->{VG_name},
+ minor => $p->{minor},
+ major => $p->{major},
size => get_lv_size($device) };
if (my $type = -e "/dev/$device" && fs::type::type_subpart_from_magic($part)) {
put_in_hash($part, $type);
} else {
- $part->{fs_type} = 'ext2';
+ $part->{fs_type} = defaultFS();
}
$part;
} @l
@@ -167,10 +220,21 @@ sub lv_delete {
@$list = grep { $_ != $lv } @$list;
}
+sub suggest_lv_name_from_mnt_point {
+ my ($lv) = @_;
+ my $str = $lv->{mntpoint};
+ $str = "root" if $str eq '/';
+ $str =~ s!^/!!;
+ $str =~ s!/!_!g;
+ $str =~ s! !_!g;
+ 'lv_' . $str;
+}
+
sub suggest_lv_name {
my ($lvm, $lv) = @_;
my $list = $lvm->{primary}{normal} ||= [];
- $lv->{lv_name} ||= 1 + max(map { if_($_->{device} =~ /(\d+)$/, $1) } @$list);
+ $lv->{lv_name} ||= suggest_lv_name_from_mnt_point($lv);
+ $lv->{lv_name} ||= "lv_" . (1 + max(map { if_($_->{device} =~ /(\d+)$/, $1) } @$list));
}
sub lv_create {
@@ -220,4 +284,8 @@ sub create_singleton_vg {
add_to_VG($part, $lvm);
}
+=back
+
+=cut
+
1;