diff options
Diffstat (limited to 'perl-install/fs/get.pm')
| -rw-r--r-- | perl-install/fs/get.pm | 188 | 
1 files changed, 188 insertions, 0 deletions
| diff --git a/perl-install/fs/get.pm b/perl-install/fs/get.pm new file mode 100644 index 000000000..00c807738 --- /dev/null +++ b/perl-install/fs/get.pm @@ -0,0 +1,188 @@ +package fs::get; + +use diagnostics; +use strict; + +use partition_table; +use fs::type; +use fs::loopback; +use fs::wild_device; +use fs; +use common; +use log; + + +=head1 SYNOPSYS + +B<fs::get>  + +=head1 Functions + +=over + +=cut + +sub empty_all_hds() { +    { hds => [], lvms => [], raids => [], dmcrypts => [], loopbacks => [], raw_hds => [], nfss => [], smbs => [], davs => [], special => [] }; +} +sub fstab { +    my ($all_hds) = @_; +    my @parts = map { partition_table::get_normal_parts($_) } hds($all_hds); +    @parts, @{$all_hds->{raids}}, @{$all_hds->{dmcrypts}}, @{$all_hds->{loopbacks}}; +} +sub really_all_fstab { +    my ($all_hds) = @_; +    my @l = fstab($all_hds); +    @l, (grep { !$_->{is_removable} } @{$all_hds->{raw_hds}}), @{$all_hds->{nfss}}, @{$all_hds->{smbs}}, @{$all_hds->{davs}}; +} + +sub fstab_and_holes { +    my ($all_hds, $b_non_readonly) = @_; +    my @hds = grep { !($b_non_readonly && $_->{readonly}) } hds($all_hds); +    hds_fstab_and_holes(@hds), @{$all_hds->{raids}}, @{$all_hds->{dmcrypts}}, @{$all_hds->{loopbacks}}; +} + +sub holes { +    my ($all_hds, $b_non_readonly) = @_; +    grep { isEmpty($_) } fstab_and_holes($all_hds, $b_non_readonly); +} +sub hds_holes { +    grep { isEmpty($_) } hds_fstab_and_holes(@_); +} +sub free_space { +    my ($all_hds) = @_; +    sum map { $_->{size} } holes($all_hds); +} +sub hds_free_space { +    sum map { $_->{size} } hds_holes(@_); +} + +sub hds { +    my ($all_hds) = @_; +    (@{$all_hds->{hds}}, @{$all_hds->{lvms}}); +} + +=item hds_fstab(@hds) + +Get all normal partition. + +=cut + +sub hds_fstab { +    map { partition_table::get_normal_parts($_) } @_; +} + +sub vg_free_space { +    my ($hd) = @_; +    my @parts = partition_table::get_normal_parts($hd); +    $hd->{totalsectors} - sum map { $_->{size} } @parts; +} + +sub hds_fstab_and_holes { +    map { +	if (isLVM($_)) { +	    my @parts = partition_table::get_normal_parts($_); +	    my $free = vg_free_space($_); +	    my $free_part = { start => 0, size => $free, pt_type => 0, rootDevice => $_->{VG_name} }; +	    @parts, if_($free >= $_->cylinder_size, $free_part); +	} else { +	    partition_table::get_normal_parts_and_holes($_); +	} +    } @_; +} + + +sub device2part { +    my ($dev, $fstab) = @_; +    my $subpart = fs::wild_device::to_subpart($dev); +    my $part = find { is_same_hd($subpart, $_) } @$fstab; +    log::l("fs::get::device2part: unknown device <<$dev>>") if !$part; +    $part; +} + +sub part2hd { +    my ($part, $all_hds) = @_; +    my $hd = find { $part->{rootDevice} eq ($_->{device} || $_->{VG_name}) } hds($all_hds); +    $hd; +} + +sub file2part { +    my ($fstab, $file, $b_keep_simple_symlinks) = @_;     +    my $part; + +    $file = $b_keep_simple_symlinks ? common::expand_symlinks_but_simple("$::prefix$file") : expand_symlinks("$::prefix$file"); +    unless ($file =~ s/^$::prefix//) { +	my $part = find { fs::type::carry_root_loopback($_) } @$fstab or die; +	log::l("found $part->{mntpoint}"); +	$file =~ s|/initrd/loopfs|$part->{mntpoint}|; +    } +    foreach (@$fstab) { +	my $m = $_->{mntpoint}; +	$part = $_ if  +	  $file =~ /^\Q$m/ &&  +	    (!$part || length $part->{mntpoint} < length $m); +    } +    $part or die "file2part: not found $file"; +    $file =~ s|$part->{mntpoint}/?|/|; +    ($part, $file); +} + +sub mntpoint2part { +    my ($mntpoint, $fstab) = @_; +    find { $mntpoint eq $_->{mntpoint} } @$fstab; +} +sub has_mntpoint { +    my ($mntpoint, $all_hds) = @_; +    mntpoint2part($mntpoint, [ really_all_fstab($all_hds) ]); +} + +sub root_from_mounted() { +    foreach (`df -P`) { +        next if m!^[^/]!; # ignore tootfs +        my ($fs, undef, undef, undef, undef, $mntpnt) = split(/\s+/); +        return $fs if $mntpnt eq '/'; +    } +} + +sub root_ { +    my ($fstab, $o_boot) = @_; +    $o_boot && mntpoint2part("/boot", $fstab) || mntpoint2part("/", $fstab); +} +sub root { &root_ || {} } + +sub up_mount_point { +    my ($mntpoint, $fstab) = @_; +    while (1) { +	$mntpoint = dirname($mntpoint); +	$mntpoint ne "." or return; +	$_->{mntpoint} eq $mntpoint and return $_ foreach @$fstab; +    } +} + +sub is_same_hd { +    my ($hd1, $hd2) = @_; +    if ($hd1->{major} && $hd2->{major}) { +	$hd1->{major} == $hd2->{major} && $hd1->{minor} == $hd2->{minor}; +    } elsif (my ($s1) = $hd1->{device} =~ m|https?://(.+?)/*$|) { +	my ($s2) = $hd2->{device} =~ m|https?://(.+?)/*$|; +	$s1 eq $s2; +    } else { +	$hd1->{device_LABEL} && $hd2->{device_LABEL} && $hd1->{device_LABEL} eq $hd2->{device_LABEL} +	  || $hd1->{device_UUID} && $hd2->{device_UUID} && $hd1->{device_UUID} eq $hd2->{device_UUID} +	  || $hd1->{device} && $hd2->{device} && $hd1->{device} eq $hd2->{device} +	  || $hd1->{device} && $hd2->{device_alias} && $hd1->{device} eq $hd2->{device_alias} +	  || $hd1->{device_alias} && $hd2->{device} && $hd1->{device_alias} eq $hd2->{device} +	  || $hd1->{device_alias} && $hd2->{device_alias} && $hd1->{device_alias} eq $hd2->{device_alias}; +    } +} + +sub mntpoint_prefixed { +    my ($part) = @_; +    $::prefix . $part->{mntpoint}; +} + +=back + +=cut + +1; | 
