!C99Shell v. 1.0 pre-release build #16!

Software: Apache/2.0.54 (Fedora). PHP/5.0.4 

uname -a: Linux mina-info.me 2.6.17-1.2142_FC4smp #1 SMP Tue Jul 11 22:57:02 EDT 2006 i686 

uid=48(apache) gid=48(apache) groups=48(apache)
context=system_u:system_r:httpd_sys_script_t
 

Safe-mode: OFF (not secure)

/usr/libexec/webmin/lvm/   drwxr-xr-x
Free 3.84 GB of 27.03 GB (14.2%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     lvm-lib.pl (24.87 KB)      -rwxr-xr-x
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# lvm-lib.pl
# Common functions for managing VGs, PVs and LVs

BEGIN { push(@INC, ".."); };
use WebminCore;
&init_config();
&foreign_require("mount");
if (&foreign_check("raid")) {
    &foreign_require("raid");
    $has_raid++;
    }
&foreign_require("fdisk");

$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;
if (-d $lvm_proc) {
    # Get list from /proc/lvm
    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);
    }
else {
    # Use pvdisplay command
    local $pv;
    local $_;
    open(DISPLAY, "pvdisplay 2>/dev/null |");
    while(<DISPLAY>) {
        s/\r|\n//g;
        if (/PV\s+Name\s+(.*)/i) {
            $pv = { 'name' => $1,
                'device' => $1,
                'number' => scalar(@rv) };
            $pv->{'name'} =~ s/^\/dev\///;
            push(@rv, $pv);
            }
        elsif (/VG\s+Name\s+(.*)/i) {
            $pv->{'vg'} = $1;
            $pv->{'vg'} =~ s/\s+\(.*\)//;
            }
        elsif (/PV\s+Size\s+<?(S+)s+(S+)/i) {
            
$pv->{'size'} = &mult_units($1, $2);
            }
        
elsif (/PEs+Sizes+(S+)s+(S+)/i) {
            
$pv->{'pe_size'} = $1;
            }
        
elsif (/PEs+Sizes+(S+)s+(S+)/i) {
            
$pv->{'pe_size'} = &mult_units($1, $2);
            }
        
elsif (/Totals+PEs+(S+)/i) {
            
$pv->{'pe_total'} = $1;
            }
        
elsif (/Allocateds+PEs+(S+)/i) {
            
$pv->{'pe_alloc'} = $1;
            }
        
elsif (/Allocatables+(S+)/i) {
            
$pv->{'alloc'} = lc($1) eq 'yes' ? 'y' : 'n';
            }
        }
    
close(DISPLAY);
    @
rv = grep { $_->{'vg'} eq $_[0] } @rv;
    @
rv = grep { $_->{'name'} ne 'unknown device' } @rv;
    }
return @
rv;
}

# get_physical_volume_usage(&lv)
# Returns a list of LVs and blocks used on this physical volume
sub get_physical_volume_usage
{
local @rv;
open(DISPLAY, "pvdisplay -m ".quotemeta($_[0]->{'device'})." 2>/dev/null |");
local $lastlen;
while(<
DISPLAY>) {
    if (/
Physicals+extents+(d+)s+tos+(d+)/) {
        
$lastlen = $2 - $1 + 1;
        }
    
elsif (/Logicals+volumes+/dev/(S+)/(S+)/) {
        
push(@rv, [ $2, $lastlen ]);
        }
    }
close(DISPLAY);
return @
rv;
}

# create_physical_volume(&pv, [force])
# Add a new physical volume to a volume group
sub create_physical_volume
{
local $cmd = "pvcreate -y ".($_[1] ? "-ff " : "-f ");
$cmd .= quotemeta($_[0]->{'device'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return
$out if ($?);
$cmd = "vgextend ".quotemeta($_[0]->{'vg'})." ".quotemeta($_[0]->{'device'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# change_physical_volume(&pv)
# Change the allocation flag for a physical volume
sub change_physical_volume
{
local $cmd = "pvchange -x ".quotemeta($_[0]->{'alloc'}).
         
" ".quotemeta($_[0]->{'device'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# delete_physical_volume(&pv)
# Remove a physical volume from a volume group
sub delete_physical_volume
{
if (
$_[0]->{'pe_alloc'}) {
    
local $cmd;
    if (&
get_lvm_version() >= 2) {
        
$cmd = "yes | pvmove ".quotemeta($_[0]->{'device'});
        }
    else {
        
$cmd = "pvmove -f ".quotemeta($_[0]->{'device'});
        }
    
local $out = &backquote_logged("$cmd 2>&1");
    return
$out if ($? && $out !~ /--s+f/);
    }
local $cmd = "vgreduce ".quotemeta($_[0]->{'vg'})." ".
         
quotemeta($_[0]->{'device'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# resize_physical_volume(&pv)
# Set the size of a physical volume to match the underlying device
sub resize_physical_volume
{
local $cmd = "pvresize ".quotemeta($_[0]->{'device'});
local $out = &backquote_logged("$cmd 2>&1");
return $? ?
$out : undef;
}

# list_volume_groups()
# Returns a list of all volume groups
sub list_volume_groups
{
local (@rv, $f);
if (-
d $lvm_proc) {
    
# Can scan /proc/lvm
    
opendir(DIR, "$lvm_proc/VGs");
    foreach
$f (readdir(DIR)) {
        
next if ($f eq '.' || $f eq '..');
        
local $vg = { 'name' => $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);
    }
else {
    
# Parse output of vgdisplay
    
local $vg;
    
open(DISPLAY, "vgdisplay 2>/dev/null |");
    while(<
DISPLAY>) {
        
s/r|n//g;
        
if (/VGs+Names+(.*)/i) {
            
$vg = { 'name' => $1 };
            
push(@rv, $vg);
            }
        
elsif (/VGs+Sizes+<?(S+)s+(S+)/i) {
            
$vg->{'size'} = &mult_units($1, $2);
            }
        
elsif (/PEs+Sizes+(S+)s+(S+)/i) {
            
$vg->{'pe_size'} = &mult_units($1, $2);
            }
        
elsif (/Totals+PEs+(d+)/i) {
            
$vg->{'pe_total'} = $1;
            }
        
elsif (/Allocs+PEs+/s+Sizes+(d+)/i) {
            
$vg->{'pe_alloc'} = $1;
            }
        }
    
close(DISPLAY);
    }
return @
rv;
}

sub mult_units
{
local ($n, $u) = @_;
return
$n*(uc($u) eq "KB" || uc($u) eq "KIB" ? 1 :
       
uc($u) eq "MB" || uc($u) eq "MIB" ? 1024 :
       
uc($u) eq "GB" || uc($u) eq "GIB" ? 1024*1024 :
       
uc($u) eq "TB" || uc($u) eq "TIB" ? 1024*1024*1024 :
       
uc($u) eq "PB" || uc($u) eq "PIB" ? 1024*1024*1024 : 1);
}

# delete_volume_group(&vg)
sub delete_volume_group
{
local $cmd = "vgchange -a n ".quotemeta($_[0]->{'name'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return
$out if ($?);
$cmd = "vgremove ".quotemeta($_[0]->{'name'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# create_volume_group(&vg, device)
sub create_volume_group
{
&
system_logged("vgscan >/dev/null 2>&1 </dev/null");
local $cmd = "pvcreate -f -y ".quotemeta($_[1]);
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return
$out if ($?);
$cmd = "vgcreate";
$cmd .= " -s ".quotemeta($_[0]->{'pe_size'})."k" if ($_[0]->{'pe_size'});
$cmd .= " ".quotemeta($_[0]->{'name'})." ".quotemeta($_[1]);
$out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# rename_volume_group(&vg, name)
sub rename_volume_group
{
local $cmd = "vgrename ".quotemeta($_[0]->{'name'})." ".quotemeta($_[1]);
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return
$out if ($?);
$cmd = "vgchange -a n ".quotemeta($_[1]);
$out = &backquote_logged("$cmd 2>&1 </dev/null");
return
$out if ($?);
$cmd = "vgchange -a y ".quotemeta($_[1]);
$out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}


# list_logical_volumes(vg)
sub list_logical_volumes
{
local @rv;
if (-
d $lvm_proc) {
    
# Get LVs from /proc/lvm
    
opendir(DIR, "$lvm_proc/VGs/$_[0]/LVs");
    foreach
$f (readdir(DIR)) {
        
next if ($f eq '.' || $f eq '..');
        
local $lv = { 'name' => $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;
        
$lv->{'stripes'} = $p{'stripes'};
        
push(@rv, $lv);

        
# For snapshots, use the lvdisplay command to get usage
        
if ($lv->{'is_snap'}) {
            
local $out = &backquote_command(
                
"lvdisplay ".quotemeta($lv->{'device'}).
                
" 2>/dev/null");
            if (
$out =~/Allocateds+tos+snapshots+([0-9.]+)%/i) {
                
$lv->{'snapusage'} = $1;
                }
            }
        }
    
closedir(DIR);
    }
else {
    
# Use the lvdisplay command
    
local $lv;
    
local $_;
    
local ($vg) = grep { $_->{'name'} eq $_[0] } &list_volume_groups();
    
open(DISPLAY, "lvdisplay -m 2>/dev/null |");
    while(<
DISPLAY>) {
        
s/r|n//g;
        
if (/LVs+(Name|Path)s+(.*/(S+))/i) {
            
$lv = { 'name' => $3,
                
'device' => $2,
                
'number' => scalar(@rv) };
            
push(@rv, $lv);
            }
        
elsif (/LVs+Names+([^/ ]+)/) {
            
# Ignore this, as we got the name from LV Path line.
            # UNLESS it doesn't match the current LV, in which
            # case it is the start of a new thinpool LV.
            
if (!@rv || $rv[$#rv]->{'name'} ne $1) {
                
$lv = { 'name' => $1,
                    
'device' => $1,
                    
'thin' => $1,
                    
'number' => scalar(@rv) };
                
push(@rv, $lv);
                }
            }
        
elsif (/VGs+Names+(.*)/) {
            
$lv->{'vg'} = $1;
            }
        
elsif (/LVs+Sizes+<?(S+)s+(S+)/i) {
            
$lv->{'size'} = &mult_units($1, $2);
            }
        
elsif (/Currents+LEs+(d+)/ && $vg) {
            
$lv->{'size'} = $1 * $vg->{'pe_size'};
            }
        
elsif (/COW-tables+LEs+(d+)/ && $vg) {
            
$lv->{'cow_size'} = $1 * $vg->{'pe_size'};
            }
        
elsif (/LVs+Writes+Accesss+(S+)/i) {
            
$lv->{'perm'} = $1 eq 'read/write' ? 'rw' : 'r';
            }
        
elsif (/Allocations+(.*)/i) {
            
$lv->{'alloc'} = $1 eq 'contiguous' ? 'y' : 'n';
            }
        
elsif (/LVs+snapshots+statuss+(.*)/i) {
            if ($
1 =~ /source/) {
                
$lv->{'has_snap'} = 1;
                }
            else {
                
$lv->{'is_snap'} = 1;
                }
            if (/
destinations+fors+/dev/[^/]+/(S+)/) {
                
$lv->{'snap_of'} = $1;
                }
            if (/
actives+destination/i) {
                
$lv->{'snap_active'} = 1;
                }
            
elsif (/INACTIVEs+destination/i) {
                
$lv->{'snap_active'} = 0;
                }
            }
        
elsif (/LVs+Thins+origins+names+(S+)/) {
            
# Snapshot in a thin pool
            
$lv->{'is_snap'} = 1;
            
$lv->{'snap_of'} = $1;
            }
        
elsif (/Read ahead sectorss+(d+|auto)/) {
                        
$lv->{'readahead'} = $1;
                        }
        
elsif (/Stripess+(d+)/) {
            
$lv->{'stripes'} = $1;
            }
        
elsif (/Stripes+sizes+(S+)s+(S+)/) {
            
$lv->{'stripesize'} = &mult_units($1, $2);
            }
        
elsif (/Allocateds+tos+snapshots+([0-9.]+)%/i) {
            
$lv->{'snapusage'} = $1;
            }
        
elsif (/LVs+Pools+names+(S+)/) {
            
$lv->{'thin_in'} = $1;
            }
        
elsif (/Allocateds+pools+datas+(S+)%/) {
            
$lv->{'thin_percent'} = $1;
            
$lv->{'thin_used'} = $1 / 100.0 * $lv->{'size'};
            }
        }
    
close(DISPLAY);
    @
rv = grep { $_->{'vg'} eq $_[0] } @rv;
    }
return @
rv;
}

# get_logical_volume_usage(&lv)
# Returns a list of PVs and blocks used by this logical volume. Each is an
# array ref of : device physical-blocks reads writes
sub get_logical_volume_usage
{
local ($lv) = @_;
local @rv;
if (&
get_lvm_version() >= 2) {
    
# LVdisplay has new format in version 2
    
open(DISPLAY, "lvdisplay -m ".quotemeta($lv->{'device'})." 2>/dev/null |");
    while(<
DISPLAY>) {
        if (/
s+Physicals+volumes+/dev/(S+)/) {
            
push(@rv, [ $1, undef ]);
            }
        
elsif (/s+Physicals+extentss+(d+)s+tos+(d+)/ && @rv) {
            
$rv[$#rv]->[1] = $2-$1+1;
            
}
        }
    
close(DISPLAY);
    }
else {
    
# Old version 1 format
    
open(DISPLAY, "lvdisplay -v ".quotemeta($lv->{'device'})." 2>/dev/null |");
    
local $started;
    while(<
DISPLAY>) {
        if (/^
s*PVs+Name/i) {
            
$started = 1;
            }
        
elsif ($started && /^s*/dev/(S+)s+(d+)s+(d+)s+(d+)/) {
            
push(@rv, [ $1, $2, $3, $4 ]);
            }
        
elsif ($started) {
            
last;
            }
        }
    
close(DISPLAY);
    }
return @
rv;
}

# create_logical_volume(&lv)
# Creates a new LV, and returns undef on success or an error message on failure
sub create_logical_volume
{
local ($lv) = @_;
local $cmd = "lvcreate -n".quotemeta($lv->{'name'})." ";
local $suffix;
if (
$lv->{'size_of'} eq 'VG' || $lv->{'size_of'} eq 'FREE' ||
    
$lv->{'size_of'} eq 'ORIGIN') {
    
$cmd .= "-l ".quotemeta("$lv->{'size'}%$lv->{'size_of'}");
    }
elsif ($lv->{'size_of'}) {
    
$cmd .= "-l $lv->{'size'}%PVS";
    
$suffix = " ".quotemeta("/dev/".$lv->{'size_of'});
    }
elsif ($lv->{'thin_in'} && $lv->{'is_snap'}) {
    
# For a snapshot inside a thin pool, no size is needed
    
}
else {
    
$cmd .= ($lv->{'thin_in'} ? "-V" : "-L").$lv->{'size'}."k";
    }
if (
$lv->{'is_snap'}) {
    
$cmd .= " -s ".quotemeta("/dev/$lv->{'vg'}/$lv->{'snapof'}");
    }
else {
    
$cmd .= " -p ".quotemeta($lv->{'perm'});
    if (!
$lv->{'thin_in'}) {
        
$cmd .= " -C ".quotemeta($lv->{'alloc'});
        }
    
$cmd .= " -r ".quotemeta($lv->{'readahead'})
        if (
$lv->{'readahead'} && $lv->{'readahead'} ne "auto");
    
$cmd .= " -i ".quotemeta($lv->{'stripe'})
        if (
$lv->{'stripe'});
    
$cmd .= " -I ".quotemeta($lv->{'stripesize'})
        if (
$lv->{'stripesize'} && $lv->{'stripe'});
    if (
$lv->{'thin_in'}) {
        
$cmd .= " --thinpool ".quotemeta($lv->{'vg'})."/".
                       
quotemeta($lv->{'thin_in'});
        }
    else {
        
$cmd .= " ".quotemeta($lv->{'vg'});
        }
    }
$cmd .= $suffix;
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# delete_logical_volume(&lv)
# Deletes an existing LV, and returns undef on success or an error message
sub delete_logical_volume
{
local ($lv) = @_;

# First delete any /dev/mapper entries for the LV
my $mapper = $lv->{'vg'}."-".$lv->{'lv'};
my $dashvg = $lv->{'vg'};
$dashvg =~ s/-/--/g;
my $dashmapper = $dashvg."-".$lv->{'lv'};
opendir(MAPPER, "/dev/mapper");
my @files = readdir(MAPPER);
closedir(MAPPER);
my @delmaps;
foreach
my $f (@files) {
    if (
$f =~ /^Q$mapperEp?d+$/ ||
        
$f =~ /^Q$dashmapperEp?d+$/) {
        
push(@delmaps, $f);
        }
    }
foreach
my $f (@files) {
    if (
$f eq $mapper || $f eq $dashmapper) {
        
push(@delmaps, $f);
        }
    }
foreach
my $f (@delmaps) {
    &
system_logged("dmsetup remove /dev/mapper/$f >/dev/null 2>&1");
    }

# Finally remove the LV
local $cmd = "lvremove -f ".quotemeta($lv->{'device'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# resize_logical_volume(&lv, size)
# Grows or shrinks a regular LV to the new size in KB
sub resize_logical_volume
{
local ($lv, $size) = @_;
local $cmd = $size > $lv->{'size'} ? "lvextend" : "lvreduce -f";
$cmd .= " -L".quotemeta($size)."k";
$cmd .= " ".quotemeta($lv->{'device'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# resize_snapshot_volume(&lv, size)
# Grows or shrinks a snapshot LV to the new size in KB
sub resize_snapshot_volume
{
local ($lv, $size) = @_;
local $cmd = $size > $lv->{'cow_size'} ? "lvextend" : "lvreduce -f";
$cmd .= " -L".quotemeta($size)."k";
$cmd .= " ".quotemeta($lv->{'device'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# change_logical_volume(&lv, [&old-lv])
# Changes various parameters of an LV< like the permissions and readahead
sub change_logical_volume
{
local ($lv, $oldlv) = @_;
local $cmd = "lvchange ";
$cmd .= " -p ".quotemeta($lv->{'perm'})
    if (!
$oldlv || $lv->{'perm'} ne $oldlv->{'perm'});
$cmd .= " -r ".quotemeta($lv->{'readahead'})
    if (!
$oldlv || $lv->{'readahead'} ne $oldlv->{'readahead'});
$cmd .= " -C ".quotemeta($lv->{'alloc'})
    if (!
$oldlv || $lv->{'alloc'} ne $oldlv->{'alloc'});
$cmd .= " ".quotemeta($lv->{'device'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# rename_logical_volume(&lv, name)
# Renames an existing LV
sub rename_logical_volume
{
local ($lv, $name) = @_;
local $cmd = "lvrename ".quotemeta($lv->{'device'})." ".
         
quotemeta("/dev/$lv->{'vg'}/$name");
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# rollback_snapshot(&lv)
# Returns the underlying LV to the state in the given snapshot
sub rollback_snapshot
{
local ($lv) = @_;
local $cmd = "lvconvert --merge ".quotemeta($lv->{'device'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

# can_resize_filesystem(type)
# 0 = no, 1 = enlarge only, 2 = enlarge or shrink
sub can_resize_filesystem
{
local ($type) = @_;
if (
$type =~ /^extd+$/) {
    if (&
has_command("e2fsadm")) {
        return
2;    # Can extend and reduce
        
}
    
elsif (&has_command("resize2fs")) {
        
# Only new versions can reduce a FS
        
local $out = &backquote_command("resize2fs 2>&1");
        return
$out =~ /resize2fss+([0-9.]+)/i && $1 >= 1.4 ? 2 : 1;
        }
    else {
        return
0;
        }
    }
elsif ($type eq "xfs") {
    return &
has_command("xfs_growfs") ? 1 : 0;
    }
elsif ($type eq "reiserfs") {
    return &
has_command("resize_reiserfs") ? 2 : 0;
    }
elsif ($type eq "jfs") {
    return
1;
    }
else {
    return
0;
    }
}

# can_resize_lv_stat(dir, type, mounted)
# Returns 1 if some LV can be enlarged, 2 if enlarged or shrunk, or 0
# if neither, based on the details provided by device_status
sub can_resize_lv_stat
{
local ($dir, $type, $mounted) = @_;
if (!
$type) {
    
# No FS known, assume can resize safely
    
return 2;
    }
else {
    
my $can = &can_resize_filesystem($type);
    if (
$can && $mounted) {
        
# If currently mounted, check if resizing is possible
        
if ($type =~ /^ext[3-9]$/ || $type eq "xfs" ||
            
$type eq "reiserfs" || $type eq "jfs") {
            
# ext*, xfs, jfs and reiserfs can be resized up
            
$can = 1;
            }
        else {
            
# Nothing else can
            
$can = 0;
            }
        }
    return
$can;
    }
}

# resize_filesystem(&lv, type, size)
sub resize_filesystem
{
if (
$_[1] =~ /^extd+$/) {
    &
foreign_require("proc");
    if (&
has_command("e2fsadm")) {
        
# The e2fsadm command can re-size an LVM and filesystem together
        
local $cmd = "e2fsadm -v -L ".quotemeta($_[2])."k ".
                 
quotemeta($_[0]->{'device'});
        
local ($fh, $fpid) = &proc::pty_process_exec($cmd);
        print
$fh "yes\n";
        
local $out;
        while(<
$fh>) {
            
$out .= $_;
            }
        
close($fh);
        
waitpid($fpid, 0);
        &
additional_log("exec", undef, $cmd);
        return $? ?
$out : undef;
        }
    else {
        if (
$_[2] > $_[0]->{'size'}) {
            
# Need to enlarge LV first, then filesystem
            
local $err = &resize_logical_volume($_[0], $_[2]);
            return
$err if ($err);

            
local $cmd = "resize2fs -f ".
                     
quotemeta($_[0]->{'device'});
            
local $out = &backquote_logged("$cmd 2>&1");
            return $? ?
$out : undef;
            }
        else {
            
# Need to shrink filesystem first, then LV
            
local $cmd = "resize2fs -f ".
                     
quotemeta($_[0]->{'device'})." ".
                     
quotemeta($_[2])."k";
            
local $out = &backquote_logged("$cmd 2>&1");
            return
$out if ($?);

            
local $err = &resize_logical_volume($_[0], $_[2]);
            return
$err;
            }
        }
    }
elsif ($_[1] eq "xfs") {
    
# Resize the logical volume first
    
local $err = &resize_logical_volume($_[0], $_[2]);
    return
$err if ($err);

    
# Resize the filesystem .. which must be mounted!
    
local @stat = &device_status($_[0]->{'device'});
    
local ($m, $mount);
    foreach
$m (&mount::list_mounts()) {
        if (
$m->[1] eq $_[0]->{'device'}) {
            
$mount = $m;
            }
        }
    if (!
$stat[2]) {
        
$mount || return "Mount not found";
        &
mount::mount_dir(@$mount);
        }
    
local $cmd = "xfs_growfs ".quotemeta($stat[0] || $mount->[0]);
    
local $out = &backquote_logged("$cmd 2>&1");
    
local $q = $?;
    if (!
$stat[2]) {
        &
mount::unmount_dir(@$mount);
        }
    return
$q ? $out : undef;
    }
elsif ($_[1] eq "reiserfs") {
    if (
$_[2] > $_[0]->{'size'}) {
        
# Enlarge the logical volume first
        
local $err = &resize_logical_volume($_[0], $_[2]);
        return
$err if ($err);

        
# Now enlarge the reiserfs filesystem
        
local $cmd = "resize_reiserfs ".quotemeta($_[0]->{'device'});
        
local $out = &backquote_logged("$cmd 2>&1");
        return $? ?
$out : undef;
        }
    else {
        
# Try to shrink the filesystem
        
local $cmd = "yes | resize_reiserfs -s ".
                 
quotemeta($_[2])."K ".quotemeta($_[0]->{'device'});
        
local $out = &backquote_logged("$cmd 2>&1");
        return
$out if ($?);

        
# Now shrink the logical volume
        
local $err = &resize_logical_volume($_[0], $_[2]);
        return
$err ? $err : undef;
        }
    }
elsif ($_[1] eq "jfs") {
    
# Enlarge the logical volume first
    
local $err = &resize_logical_volume($_[0], $_[2]);
    return
$err if ($err);

    
# Now enlarge the jfs filesystem with a remount - must be mounted first
    
local @stat = &device_status($_[0]->{'device'});
    
local ($m, $mount);
    foreach
$m (&mount::list_mounts()) {
        if (
$m->[1] eq $_[0]->{'device'}) {
            
$mount = $m;
            }
        }
    if (!
$stat[2]) {
        
$mount || return "Mount not found";
        &
mount::mount_dir(@$mount);
        }
    
local $ropts = $mount->[3];
    
$ropts = $ropts eq "-" ? "resize,remount" : "$ropts,resize,remount";
    
local $err = &mount::mount_dir($mount->[0], $mount->[1],
                       
$mount->[2], $ropts);
    if (!
$stat[2]) {
        &
mount::unmount_dir(@$mount);
        }
    return
$err ? $err : undef;
    }
else {
    return
"???";
    }
}


# parse_colon_file(file)
sub parse_colon_file
{
local %rv;
open(FILE, $_[0]);
while(<
FILE>) {
    if (/^([^:]+):
s*(.*)/) {
        
$rv{$1} = $2;
        }
    }
close(FILE);
return %
rv;
}

# device_status(device)
# Returns an array of  directory, type, mounted
sub device_status
{
local ($dev) = @_;
return ( ) if (
$dev !~ /^//);
local @st = &fdisk::device_status($dev);
return @
st if (@st);
if (&
foreign_check("server-manager")) {
    
# Look for Cloudmin systems using the disk, hosted on this system
    
if (!@server_manager_systems) {
        &
foreign_require("server-manager");
        @
server_manager_systems =
            
grep { my $p = &server_manager::get_parent_server($_);
                   
$p && $p->{'id'} eq '0' }
                 &
server_manager::list_managed_servers();
        }
    foreach
my $s (@server_manager_systems) {
        if (
$s->{$s->{'manager'}.'_filesystem'} eq $_[0]) {
            return (
$s->{'host'}, 'cloudmin',
                     
$s->{'status'} ne 'down' );
            }
        
my $ffunc = "type_".$s->{'manager'}."_list_disk_devices";
        if (&
foreign_defined("server-manager", $ffunc)) {
            
my @disks = &foreign_call("server-manager", $ffunc, $s);
            if (&
indexof($_[0], @disks) >= 0) {
                return (
$s->{'host'}, 'cloudmin',
                    
$s->{'status'} ne 'down' );
                }
            }
        }
    }
return ();
}

# device_message(stat)
# Returns a text string about the status of an LV
sub device_message
{
my $msg;
if (
$_[1] eq 'cloudmin') {
    
# Used by Cloudmin system
    
$msg = $_[2] ? 'lv_mountcm' : 'lv_umountcm';
    return &
text($msg, "<tt>$_[0]</tt>");
    }
else {
    
# Used by filesystem or RAID or iSCSI
    
$msg = $_[2] ? 'lv_mount' : 'lv_umount';
    
$msg .= 'vm' if ($_[1] eq 'swap');
    
$msg .= 'raid' if ($_[1] eq 'raid');
    
$msg .= 'iscsi' if ($_[1] eq 'iscsi');
    return &
text($msg, "<tt>$_[0]</tt>", "<tt>$_[1]</tt>");
    }
}

# list_lvmtab()
sub list_lvmtab
{
local @rv;
open(TAB, $lvm_tab);
local $/ = "\0";
while(<
TAB>) {
    
chop;
    
push(@rv, $_) if ($_);
    }
close(TAB);
return @
rv;
}

# device_input()
# Returns a selector for a free device
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
local @opts;
foreach
$d (&fdisk::list_disks_partitions()) {
    foreach
$p (@{$d->{'parts'}}) {
        
next if ($used{$p->{'device'}} || $p->{'extended'});
        
local @ds = &device_status($p->{'device'});
        
next if (@ds);
        if (
$p->{'type'} eq '83' || $p->{'type'} eq 'ext2') {
            
local $label = &fdisk::get_label($p->{'device'});
            
next if ($used{"LABEL=$label"});
            }
        
local $tag = &fdisk::tag_name($p->{'type'});
        
push(@opts, [ $p->{'device'},
            
$p->{'desc'}.
            (
$tag ? " ($tag)" : "").
            (
$d->{'cylsize'} ? " (".&nice_size($d->{'cylsize'}*($p->{'end'} - $p->{'start'} + 1)).")" :
            
" ($p->{'blocks'} $text{'blocks'})") ]);
        }
    }

# Show available RAID devices
local $conf = &raid::get_raidtab();
foreach
$c (@$conf) {
    
next if ($used{$c->{'value'}});
    
local @ds = &device_status($c->{'value'});
    
next if (@ds);
    
push(@opts, [ $c->{'value'}, &text('pv_raid', $c->{'value'} =~ /md(d+)$/ ? "$1" : $c->{'value'}) ]);
    }

push(@opts, [ '', $text{'pv_other'} ]);
return &
ui_select("device", $opts[0]->[0], @opts)." ".
       &
ui_textbox("other", undef, 30)." ".&file_chooser_button("other").
       
"<br>\n<b>$text{'pv_warn'}</b>";
}

# get_lvm_version()
# Returns the lvm version number and optionally output from the vgdisplay
# command used to get it.
sub get_lvm_version
{
local $out = `vgdisplay --version 2>&1`;
local $ver = $out =~ /s+([0-9.]+)/ ? $1 : undef;
return
wantarray ? ( $ver, $out ) : $ver;
}

# nice_round(number)
# Round some number to TB, GB, MB or kB, depending on size
sub nice_round
{
local ($bytes) = @_;
my $units;
if (
$bytes >= 10*1024*1024*1024*1024) {
        
$units = 1024*1024*1024*1024;
        }
elsif ($bytes >= 10*1024*1024*1024) {
        
$units = 1024*1024*1024;
        }
elsif ($bytes >= 10*1024*1024) {
        
$units = 1024*1024;
        }
elsif ($bytes >= 10*1024) {
        
$units = 1024;
        }
else {
    
$units = 1;
    }
return
int($bytes / $units) * $units;
}

# move_logical_volume(&lv, from, to, [print])
# Moves blocks on an LV from one PV to another. Returns an error message on
# failure, or undef on success
sub move_logical_volume
{
local ($lv, $from, $to, $print) = @_;
local $cmd = "pvmove -n $lv->{'name'} /dev/$from /dev/$to";
if (
$print) {
    
open(OUT, "$cmd 2>&1 </dev/null |");
    
my $old = select(OUT);
    $| =
1;
    
select($old);
    while(<
OUT>) {
        print &
html_escape($_);
        }
    
my $ex = close(OUT);
    return $? ?
"Failed" : undef;
    }
else {
    
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
    return $? ?
$out : undef;
    }
}

# supports_snapshot_rollback()
# Only newer kernels safely support this (2.6.35 and above)
sub supports_snapshot_rollback
{
my $out = &backquote_command("uname -r 2>/dev/null </dev/null");
return
$out =~ /^(d+)./ && $1 >= 3 ||
       
$out =~ /^(d+).(d+)/ && $1 == 2 && $2 >= 7 ||
       
$out =~ /^(d+).(d+).(d+)/ && $1 == 2 && $2 == 6 && $3 >= 35;
}

# create_thin_pool(&data-lv, &metadata-lv)
# Convert two LVs into a thin pool
sub create_thin_pool
{
local ($datalv, $metadatalv) = @_;
local $cmd = "lvconvert -y --type thin-pool --poolmetadata ".
         
quotemeta($metadatalv->{'device'})." ".
         
quotemeta($datalv->{'device'});
local $out = &backquote_logged("$cmd 2>&1 </dev/null");
return $? ?
$out : undef;
}

1;


:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #16 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0055 ]--