# lvm-lib.pl # Common functions for managing VGs, PVs and LVs do '../web-lib.pl'; &init_config(); &foreign_require("mount", "mount-lib.pl"); if (&foreign_check("raid")) { &foreign_require("raid", "raid-lib.pl"); $has_raid++; } $lvm_proc = "/proc/lvm"; $lvm_tab = "/etc/lvmtab"; # list_physical_volumes(vg) # Returns a list of all physical volumes for some volume group sub list_physical_volumes { local @rv; opendir(DIR, "$lvm_proc/VGs/$_[0]/PVs"); foreach $f (readdir(DIR)) { next if ($f eq '.' || $f eq '..'); local $pv = { 'name' => $f, 'vg' => $_[0] }; local %p = &parse_colon_file("$lvm_proc/VGs/$_[0]/PVs/$f"); $pv->{'device'} = $p{'name'}; $pv->{'number'} = $p{'number'}; $pv->{'size'} = $p{'size'}/2; $pv->{'status'} = $p{'status'}; $pv->{'number'} = $p{'number'}; $pv->{'pe_size'} = $p{'PE size'}; $pv->{'pe_total'} = $p{'PE total'}; $pv->{'pe_alloc'} = $p{'PE allocated'}; $pv->{'alloc'} = $p{'allocatable'} == 2 ? 'y' : 'n'; push(@rv, $pv); } closedir(DIR); return @rv; } # create_physical_volume(&pv) sub create_physical_volume { local $cmd = "pvcreate -f -y '$_[0]->{'device'}'"; local $out = &backquote_logged("$cmd 2>&1 &1 &1 {'pe_alloc'}) { local $cmd = "(yes | pvmove '$_[0]->{'device'}')"; local $out = &backquote_logged("$cmd 2>&1"); return $out if ($?); } local $cmd = "vgreduce '$_[0]->{'vg'}' '$_[0]->{'device'}'"; local $out = &backquote_logged("$cmd 2>&1 $f }; local %g = &parse_colon_file("$lvm_proc/VGs/$f/group"); $vg->{'number'} = $g{'number'}; $vg->{'size'} = $g{'size'}; $vg->{'pe_size'} = $g{'PE size'}; $vg->{'pe_total'} = $g{'PE total'}; $vg->{'pe_alloc'} = $g{'PE allocated'}; push(@rv, $vg); } closedir(DIR); return @rv; } # delete_volume_group(&vg) sub delete_volume_group { local $cmd = "vgchange -a n '$_[0]->{'name'}'"; local $out = &backquote_logged("$cmd 2>&1 &1 /dev/null 2>&1 &1 {'pe_size'}); $cmd .= " '$_[0]->{'name'}' '$_[1]'"; $out = &backquote_logged("$cmd 2>&1 &1 &1 &1 $f, 'vg' => $_[0] }; local %p = &parse_colon_file("$lvm_proc/VGs/$_[0]/LVs/$f"); $lv->{'device'} = $p{'name'}; $lv->{'number'} = $p{'number'}; $lv->{'size'} = $p{'size'}/2; $lv->{'perm'} = $p{'access'} == 3 ? 'rw' : 'r'; $lv->{'alloc'} = $p{'allocation'} == 2 ? 'y' : 'n'; $lv->{'has_snap'} = $p{'access'} == 11; $lv->{'is_snap'} = $p{'access'} == 5; push(@rv, $lv); } closedir(DIR); return @rv; } # create_logical_volume(&lv) sub create_logical_volume { local $cmd = "lvcreate -n$_[0]->{'name'} -L$_[0]->{'size'}k"; if ($_[0]->{'is_snap'}) { $cmd .= " -s '/dev/$_[0]->{'vg'}/$_[0]->{'snapof'}'"; } else { $cmd .= " -p $_[0]->{'perm'}"; $cmd .= " -C $_[0]->{'alloc'}"; $cmd .= " -i $_[0]->{'stripe'}" if ($_[0]->{'stripe'}); $cmd .= " $_[0]->{'vg'}"; } local $out = &backquote_logged("$cmd 2>&1 &1 $_[0]->{'size'} ? "lvextend" : "lvreduce -f"; $cmd .= " -L$_[1]k"; $cmd .= " '$_[0]->{'device'}'"; local $out = &backquote_logged("$cmd 2>&1 &1 &1 ) { $out .= $_; } close($fh); waitpid($fpid, 0); &additional_log("exec", undef, $cmd); return $? ? $out : undef; } elsif ($_[1] eq "xfs") { # Resize the logical volume first # XXX resize the filesystem } else { return "???"; } } # parse_colon_file(file) sub parse_colon_file { local %rv; open(FILE, $_[0]); while() { if (/^([^:]+):\s*(.*)/) { $rv{$1} = $2; } } close(FILE); return %rv; } # device_status(device) # Returns an array of directory, type, mounted sub device_status { @mounted = &foreign_call("mount", "list_mounted") if (!@mounted); @mounts = &foreign_call("mount", "list_mounts") if (!@mounts); local $label = &fdisk::get_label($_[0]); local ($mounted) = grep { &same_file($_->[1], $_[0]) || $_->[1] eq "LABEL=$label" } @mounted; local ($mount) = grep { &same_file($_->[1], $_[0]) || $_->[1] eq "LABEL=$label" } @mounts; print STDERR "for $_[0] : mount = $mount mounted = $mounted\n"; if ($mounted) { return ($mounted->[0], $mounted->[2], 1, &indexof($mount, @mounts), &indexof($mounted, @mounted)); } elsif ($mount) { return ($mount->[0], $mount->[2], 0, &indexof($mount, @mounts)); } elsif ($has_raid) { $raidconf = &foreign_call("raid", "get_raidtab") if (!$raidconf); foreach $c (@$raidconf) { foreach $d (raid::find_value('device', $c->{'members'})) { return ( $c->{'value'}, "raid", 1 ) if ($d eq $_[0]); } } } return (); } sub device_message { $msg = $_[2] ? 'lv_mount' : 'lv_umount'; $msg .= 'vm' if ($_[1] eq 'swap'); $msg .= 'raid' if ($_[1] eq 'raid'); return &text($msg, "$_[0]", "$_[1]"); } # list_lvmtab() sub list_lvmtab { local @rv; open(TAB, $lvm_tab); local $/ = "\0"; while() { chop; push(@rv, $_) if ($_); } close(TAB); return @rv; } # device_input() sub device_input { local (%used, $vg, $pv, $d, $p); # Find partitions that are part of an LVM foreach $vg (&list_volume_groups()) { foreach $pv (&list_physical_volumes($vg->{'name'})) { $used{$pv->{'device'}}++; } } # Show available partitions print "\n"; print " ", &file_chooser_button("other"),"
\n"; print "$text{'pv_warn'}\n"; } 1;