diff options
Diffstat (limited to 'perl-install/fs')
-rw-r--r-- | perl-install/fs/format.pm | 3 | ||||
-rw-r--r-- | perl-install/fs/get.pm | 3 | ||||
-rw-r--r-- | perl-install/fs/loopback.pm | 125 |
3 files changed, 129 insertions, 2 deletions
diff --git a/perl-install/fs/format.pm b/perl-install/fs/format.pm index ad4e77508..4f0aff353 100644 --- a/perl-install/fs/format.pm +++ b/perl-install/fs/format.pm @@ -6,6 +6,7 @@ use strict; use run_program; use common; use fs::type; +use fs::loopback; use log; my %cmds = ( @@ -46,7 +47,7 @@ sub part { raid::format_part($raids, $part); } elsif (isLoopback($part)) { $wait_message->(N("Creating and formatting file %s", $part->{loopback_file})) if $wait_message; - loopback::format_part($part, $prefix); + fs::loopback::format_part($part, $prefix); } else { $wait_message->(N("Formatting partition %s", $part->{device})) if $wait_message; part_raw($part, $wait_message); diff --git a/perl-install/fs/get.pm b/perl-install/fs/get.pm index 6b982c1e9..dca0a5aa9 100644 --- a/perl-install/fs/get.pm +++ b/perl-install/fs/get.pm @@ -5,6 +5,7 @@ use strict; use partition_table; use fs::type; +use fs::loopback; use fs; use common; use log; @@ -87,7 +88,7 @@ sub file2part { $file = $b_keep_simple_symlinks ? common::expand_symlinks_but_simple("$::prefix$file") : expand_symlinks("$::prefix$file"); unless ($file =~ s/^$::prefix//) { - my $part = find { loopback::carryRootLoopback($_) } @$fstab or die; + my $part = find { fs::loopback::carryRootLoopback($_) } @$fstab or die; log::l("found $part->{mntpoint}"); $file =~ s|/initrd/loopfs|$part->{mntpoint}|; } diff --git a/perl-install/fs/loopback.pm b/perl-install/fs/loopback.pm new file mode 100644 index 000000000..a7c6c913d --- /dev/null +++ b/perl-install/fs/loopback.pm @@ -0,0 +1,125 @@ +package fs::loopback; # $Id$ + +use diagnostics; +use strict; + +#-###################################################################################### +#- misc imports +#-###################################################################################### +use common; +use fs::type; +use fs; +use log; + + +sub carryRootLoopback { + my ($part) = @_; + $_->{mntpoint} eq '/' and return 1 foreach @{$part->{loopback} || []}; + 0; +} + +sub check_circular_mounts { + my ($part, $all_hds) = @_; + + my $fstab = [ fs::get::fstab($all_hds), $part ]; # no pb if $part is already in $all_hds + + my $base_mntpoint = $part->{mntpoint}; + my $check; $check = sub { + my ($part, @seen) = @_; + push @seen, $part->{mntpoint} || return; + @seen > 1 && $part->{mntpoint} eq $base_mntpoint and die N("Circular mounts %s\n", join(", ", @seen)); + if (my $part = fs::get::up_mount_point($part->{mntpoint}, $fstab)) { + #- '/' carrier is a special case, it will be mounted first + $check->($part, @seen) if !carryRootLoopback($part); + } + if (isLoopback($part)) { + $check->($part->{loopback_device}, @seen); + } + }; + $check->($part) if !($base_mntpoint eq '/' && isLoopback($part)); #- '/' is a special case, no loop check +} + +sub carryRootCreateSymlink { + my ($part, $prefix) = @_; + + carryRootLoopback($part) or return; + + my $mntpoint = "$prefix$part->{mntpoint}"; + unless (-e $mntpoint) { + eval { mkdir_p(dirname($mntpoint)) }; + #- do non-relative link for install, should be changed to relative link before rebooting + symlink "/initrd/loopfs", $mntpoint; + + mkdir_p("/initrd/loopfs/lnx4win/boot"); + symlink "/initrd/loopfs/lnx4win/boot", "$prefix/boot"; + } + #- indicate kernel to keep initrd + mkdir_p("$prefix/initrd"); +} + + +sub format_part { + my ($part, $prefix) = @_; + fs::mount_part($part->{loopback_device}, $prefix); + create($part, $prefix); + fs::format::part_raw($part, undef); +} + +sub create { + my ($part, $prefix) = @_; + my $f = $part->{device} = "$prefix$part->{loopback_device}{mntpoint}$part->{loopback_file}"; + return if -e $f; + + eval { mkdir_p(dirname($f)) }; + + log::l("creating loopback file $f ($part->{size} sectors)"); + + my $block_size = 128; + my $s = "\0" x (512 * $block_size); + sysopen(my $F, $f, 2 | c::O_CREAT()) or die "failed to create loopback file"; + for (my $i = 0; $i < $part->{size}; $i += $block_size) { + syswrite $F, $s or die "failed to create loopback file"; + } +} + +sub getFree { + my ($dir, $part) = @_; + my $freespace = $dir ? + 2 * (MDK::Common::System::df($dir))[1] : #- df in KiB + $part->{size}; + + $freespace - sum map { $_->{size} } @{$part->{loopback} || []}; +} + +#- returns the size of the loopback file if it already exists +#- returns -1 is the loopback file can not be used +sub verifFile { + my ($dir, $file, $part) = @_; + -e "$dir$file" and return -s "$dir$file"; + + $_->{loopback_file} eq $file and return -1 foreach @{$part->{loopback} || []}; + + undef; +} + +sub prepare_boot() { + my $r = readlink "$::prefix/boot"; + unlink "$::prefix/boot"; + mkdir_p("$::prefix/boot"); + [$r, $::prefix]; +} + +sub save_boot { + my ($loop_boot, $prefix) = @{$_[0]}; + + $loop_boot or return; + + my @files = glob_("$prefix/boot/*"); + cp_af(@files, $loop_boot) if @files; + rm_rf("$prefix/boot"); + symlink $loop_boot, "$prefix/boot"; +} + + +1; + |