diff options
Diffstat (limited to 'perl-install/fsedit.pm')
| -rw-r--r-- | perl-install/fsedit.pm | 454 |
1 files changed, 148 insertions, 306 deletions
diff --git a/perl-install/fsedit.pm b/perl-install/fsedit.pm index acf5a023f..42404bfe8 100644 --- a/perl-install/fsedit.pm +++ b/perl-install/fsedit.pm @@ -8,10 +8,10 @@ use vars qw(%suggestions); #- misc imports #-###################################################################################### use common; -use partition_table qw(:types); +use partition_table; use partition_table::raw; +use fs::type; use detect_devices; -use fsedit; use devices; use loopback; use log; @@ -19,21 +19,21 @@ use fs; %suggestions = ( N_("simple") => [ - { mntpoint => "/", size => 300 << 11, pt_type =>0x483, ratio => 5, maxsize => 6000 << 11 }, - { mntpoint => "swap", size => 64 << 11, pt_type => 0x82, ratio => 1, maxsize => 500 << 11 }, - { mntpoint => "/home", size => 300 << 11, pt_type =>0x483, ratio => 3 }, + { mntpoint => "/", size => 300 << 11, fs_type => 'ext3', ratio => 5, maxsize => 6000 << 11 }, + { mntpoint => "swap", size => 64 << 11, fs_type => 'swap', ratio => 1, maxsize => 1100 << 11 }, + { mntpoint => "/home", size => 300 << 11, fs_type => 'ext3', ratio => 3 }, ], N_("with /usr") => [ - { mntpoint => "/", size => 250 << 11, pt_type =>0x483, ratio => 1, maxsize => 2000 << 11 }, - { mntpoint => "swap", size => 64 << 11, pt_type => 0x82, ratio => 1, maxsize => 500 << 11 }, - { mntpoint => "/usr", size => 300 << 11, pt_type =>0x483, ratio => 4, maxsize => 4000 << 11 }, - { mntpoint => "/home", size => 100 << 11, pt_type =>0x483, ratio => 3 }, + { mntpoint => "/", size => 250 << 11, fs_type => 'ext3', ratio => 1, maxsize => 2000 << 11 }, + { mntpoint => "swap", size => 64 << 11, fs_type => 'swap', ratio => 1, maxsize => 1100 << 11 }, + { mntpoint => "/usr", size => 300 << 11, fs_type => 'ext3', ratio => 4, maxsize => 4000 << 11 }, + { mntpoint => "/home", size => 100 << 11, fs_type => 'ext3', ratio => 3 }, ], N_("server") => [ - { mntpoint => "/", size => 150 << 11, pt_type =>0x483, ratio => 1, maxsize => 800 << 11 }, - { mntpoint => "swap", size => 64 << 11, pt_type => 0x82, ratio => 2, maxsize => 800 << 11 }, - { mntpoint => "/usr", size => 300 << 11, pt_type =>0x483, ratio => 4, maxsize => 4000 << 11 }, - { mntpoint => "/var", size => 200 << 11, pt_type =>0x483, ratio => 3 }, - { mntpoint => "/home", size => 150 << 11, pt_type =>0x483, ratio => 3 }, - { mntpoint => "/tmp", size => 150 << 11, pt_type =>0x483, ratio => 2, maxsize => 1000 << 11 }, + { mntpoint => "/", size => 150 << 11, fs_type => 'ext3', ratio => 1, maxsize => 800 << 11 }, + { mntpoint => "swap", size => 64 << 11, fs_type => 'swap', ratio => 2, maxsize => 1600 << 11 }, + { mntpoint => "/usr", size => 300 << 11, fs_type => 'ext3', ratio => 4, maxsize => 4000 << 11 }, + { mntpoint => "/var", size => 200 << 11, fs_type => 'ext3', ratio => 3 }, + { mntpoint => "/home", size => 150 << 11, fs_type => 'ext3', ratio => 3 }, + { mntpoint => "/tmp", size => 150 << 11, fs_type => 'ext3', ratio => 2, maxsize => 1000 << 11 }, ], ); foreach (values %suggestions) { @@ -48,105 +48,34 @@ my @suggestions_mntpoints = ( #- RedHat also has /usr/local and /opt ); -my @partitions_signatures = ( - [ 0x8e, 0, "HM\1\0" ], - [ 0x83, 0x438, "\x53\xEF" ], - [ 0x183, 0x10034, "ReIsErFs" ], - [ 0x183, 0x10034, "ReIsEr2Fs" ], - [ 0x283, 0, 'XFSB', 0x200, 'XAGF', 0x400, 'XAGI' ], - [ 0x383, 0x8000, 'JFS1' ], - [ 0x82, 4086, "SWAP-SPACE" ], - [ 0x82, 4086, "SWAPSPACE2" ], - [ 0x107, 0x1FE, "\x55\xAA", 0x3, "NTFS" ], - [ 0xc, 0x1FE, "\x55\xAA", 0x52, "FAT32" ], -if_(arch() !~ /^sparc/, - [ 0x6, 0x1FE, "\x55\xAA", 0x36, "FAT" ], -), -); - -sub typeOfPart { - my $dev = devices::make($_[0]); - my $t = typeFromMagic($dev, @partitions_signatures); - if ($t == 0x83) { - #- there is no magic to differentiate ext3 and ext2. Using libext2fs - #- to check if it has a journal - $t = 0x483 if c::is_ext3($dev); - } - $t; -} - #-###################################################################################### #- Functions #-###################################################################################### -sub empty_all_hds() { - { hds => [], lvms => [], raids => [], loopbacks => [], raw_hds => [], nfss => [], smbs => [], davs => [], special => [] }; -} sub recompute_loopbacks { my ($all_hds) = @_; - my @fstab = get_all_fstab($all_hds); + my @fstab = fs::get::fstab($all_hds); @{$all_hds->{loopbacks}} = map { isPartOfLoopback($_) ? @{$_->{loopback}} : () } @fstab; } sub raids { my ($hds) = @_; - my @parts = get_fstab(@$hds); - { - my @l = grep { isRawRAID($_) } @parts or return []; - detect_devices::raidAutoStart(@l); - } - - fs::get_major_minor(@parts); - - my @raids; - my @mdstat = cat_("/proc/mdstat"); - for (my $i = 0; $i < @mdstat; $i++) { - - my ($nb, $level, $mdparts) = - #- line format is: - #- md%d : {in}?active{ (read-only)}? {linear|raid1|raid4|raid5}{ DEVNAME[%d]{(F)}?}* - $mdstat[$i] =~ /^md(\d+).* ([^ \[\]]+) (\S+\[\d+\].*)/ or next; - - $level =~ s/raid//; #- { linear | raid0 | raid1 | raid5 } -> { linear | 0 | 1 | 5 } - - my $chunks = $mdstat[$i+1] =~ /(\S+) chunks/ ? $1 : "64k"; + my @parts = fs::get::hds_fstab(@$hds); - my @raw_mdparts = map { /([^\[]+)/ } split ' ', $mdparts; - - my $pt_type = typeOfPart("md$nb"); - log::l("RAID: found md$nb (raid $level) chunks $chunks ", if_($pt_type, "type $pt_type "), "with parts ", join(", ", @raw_mdparts)); - $raids[$nb] = { 'chunk-size' => $chunks, pt_type => $pt_type || 0x83, raw_mdparts => \@raw_mdparts, - device => "md$nb", notFormatted => !$pt_type, level => $level }; - } - - my %devname2part = map { $_->{dev} => { %$_, device => $_->{dev} } } devices::read_proc_partitions_raw(); - each_index { - my $raw_mdparts = delete $_->{raw_mdparts}; - my @mdparts = - map { - my $mdpart = $devname2part{$_} || { device => $_ }; - if (my $part = find { is_same_hd($mdpart, $_) } @parts, @raids) { - $part->{raid} = $::i; - $part->{pt_type} = 0xfd; - delete $part->{mntpoint}; - $part; - } else { - #- forget it when not found? that way it won't break much... beurk. - (); - } - } @$raw_mdparts; - - $_->{disks} = \@mdparts; - } @raids; + my @l = grep { isRawRAID($_) } @parts or return []; + log::l("looking for raids in " . join(' ', map { $_->{device} } @l)); + require raid; - raid::update(@raids); - \@raids; + raid::detect_during_install(@l) if $::isInstall; + raid::get_existing(@l); } sub lvms { my ($all_hds) = @_; - my @pvs = grep { isRawLVM($_) } get_all_fstab($all_hds) or return; + my @pvs = grep { isRawLVM($_) } fs::get::fstab($all_hds) or return; + + log::l("looking for vgs in " . join(' ', map { $_->{device} } @pvs)); #- otherwise vgscan won't find them devices::make($_->{device}) foreach @pvs; @@ -168,28 +97,32 @@ sub lvms { @lvms; } -sub hds { - my ($flags, $o_ask_before_blanking) = @_; - $flags ||= {}; +sub get_hds { + my ($o_flags, $o_in) = @_; + my $flags = $o_flags || {}; $flags->{readonly} && ($flags->{clearall} || $flags->{clear}) and die "conflicting flags readonly and clear/clearall"; my @drives = detect_devices::hds(); - my (@hds, @raw_hds); foreach my $hd (@drives) { $hd->{file} = devices::make($hd->{device}); $hd->{prefix} ||= $hd->{device}; - $hd->{readonly} = $flags->{readonly}; + } + + @drives = partition_table::raw::get_geometries(@drives); - my $h = partition_table::raw::get_geometry($hd->{file}) or log::l("An error occurred while getting the geometry of block device $hd->{file}: $!"), next; - add2hash_($hd, $h); + my (@hds, @raw_hds); + foreach my $hd (@drives) { + $hd->{readonly} = $flags->{readonly}; eval { partition_table::raw::test_for_bad_drives($hd) }; if (my $err = $@) { if ($err =~ /write error:/) { $hd->{readonly} = 1; + } elsif ($err =~ /read error:/) { + next; } else { - cdie $err if $err !~ /read error:/; + $o_in and $o_in->ask_warn('', $err); next; } } @@ -197,18 +130,48 @@ sub hds { if ($flags->{clearall} || member($hd->{device}, @{$flags->{clear} || []})) { partition_table::raw::zero_MBR_and_dirty($hd); } else { - eval { - partition_table::read($hd); - compare_with_proc_partitions($hd) if $::isInstall; - }; - if (my $err = $@) { + my $handle_die_and_cdie = sub { if ($hd->{readonly}) { log::l("using /proc/partitions since diskdrake failed :("); use_proc_partitions($hd); - } elsif (exists $hd->{usb_description} && ($hd->{pt_type} ||= typeOfPart($hd->{device}))) { + 1; + } elsif (exists $hd->{usb_description} && fs::type::fs_type_from_magic($hd)) { + #- non partitioned drive + $hd->{fs_type} = fs::type::fs_type_from_magic($hd); push @raw_hds, $hd; - next; - } elsif ($o_ask_before_blanking && $o_ask_before_blanking->($hd->{device}, $err)) { + $hd = ''; + 1; + } else { + 0; + } + }; + my $handled; + eval { + catch_cdie { + partition_table::read($hd); + compare_with_proc_partitions($hd) if $::isInstall; + } sub { + my $err = $@; + if ($handle_die_and_cdie->()) { + $handled = 1; + 0; #- don't continue, transform cdie into die + } else { + !$o_in || $o_in->ask_okcancel('', formatError($err)); + } + } + }; + if (my $err = $@) { + if ($handled) { + #- already handled in cdie handler above + } elsif ($handle_die_and_cdie->()) { + } elsif ($o_in && $o_in->ask_yesorno(N("Error"), +N("I can't read the partition table of device %s, it's too corrupted for me :( +I can try to go on, erasing over bad partitions (ALL DATA will be lost!). +The other solution is to not allow DrakX to modify the partition table. +(the error is %s) + +Do you agree to lose all the partitions? +", $hd->{device}, formatError($err)))) { partition_table::raw::zero_MBR($hd); } else { #- using it readonly @@ -216,63 +179,54 @@ sub hds { use_proc_partitions($hd); } } + $hd or next; + member($_->{device}, @{$flags->{clear} || []}) and partition_table::remove($hd, $_) foreach partition_table::get_normal_parts($hd); } - # special case for Various type - $_->{pt_type} = typeOfPart($_->{device}) || 0x100 foreach grep { $_->{pt_type} == 0x100 } partition_table::get_normal_parts($hd); - - #- special case for type overloading (eg: reiserfs is 0x183) - foreach (grep { isExt2($_) || $_->{pt_type} == 0x7 || $_->{pt_type} == 0x17 } partition_table::get_normal_parts($hd)) { - my $wanted_pt_type = $_->{pt_type} == 0x17 ? 0x7 : $_->{pt_type}; - my $pt_type = typeOfPart($_->{device}); - $_->{pt_type} = $pt_type if ($pt_type & 0xff) == $wanted_pt_type || $pt_type && $hd->isa('partition_table::gpt'); + my @parts = partition_table::get_normal_parts($hd); + + # checking the magic of the filesystem, don't rely on pt_type + foreach (grep { member($_->{fs_type}, 'vfat', 'ntfs', 'ext2') || $_->{pt_type} == 0x100 } @parts) { + if (my $type = fs::type::type_subpart_from_magic($_)) { + if ($type->{fs_type}) { + #- keep {pt_type} + $_->{fs_type} = $type->{fs_type}; + } else { + put_in_hash($_, $type); + } + } else { + $_->{bad_fs_type_magic} = 1; + } } - foreach (partition_table::get_normal_parts($hd)) { + foreach (@parts) { my $label = - member(type2fs($_), qw(ext2 ext3)) ? + member($_->{fs_type}, qw(ext2 ext3)) ? c::get_ext2_label(devices::make($_->{device})) : ''; $_->{device_LABEL} = $label if $label; } + if ($hd->{usb_media_type}) { + $_->{is_removable} = 1 foreach @parts; + } + push @hds, $hd; } #- detect raids before LVM allowing LVM on raid my $raids = raids(\@hds); - my $all_hds = { %{ empty_all_hds() }, hds => \@hds, raw_hds => \@raw_hds, lvms => [], raids => $raids }; + my $all_hds = { %{ fs::get::empty_all_hds() }, hds => \@hds, raw_hds => \@raw_hds, lvms => [], raids => $raids }; $all_hds->{lvms} = [ lvms($all_hds) ]; - fs::get_major_minor(get_all_fstab($all_hds)); + fs::get_major_minor(fs::get::fstab($all_hds)); $all_hds; } -sub get_hds { - #- $in is optional - my ($flags, $o_in) = @_; - - if ($o_in) { - catch_cdie { hds($flags, sub { - my ($dev, $err) = @_; - $o_in->ask_yesorno(N("Error"), -N("I can't read the partition table of device %s, it's too corrupted for me :( -I can try to go on, erasing over bad partitions (ALL DATA will be lost!). -The other solution is to not allow DrakX to modify the partition table. -(the error is %s) - -Do you agree to lose all the partitions? -", $dev, formatError($err))); - }) } sub { $o_in->ask_okcancel('', formatError($@)) }; - } else { - catch_cdie { hds($flags) } sub { 1 } - } -} - sub read_proc_partitions { my ($hds) = @_; @@ -296,31 +250,21 @@ sub read_proc_partitions { } else { $dev = $part->{dev}; if (my $hd = find { $part->{dev} =~ /^$_->{device}./ } @$hds) { - $part->{rootDevice} = $hd->{device}; + put_in_hash($part, partition_table::hd2minimal_part($hd)); } } undef $prev_part if $prev_part && ($prev_part->{rootDevice} || '') ne ($part->{rootDevice} || ''); $part->{device} = $dev; $part->{size} *= 2; # from KB to sectors - $part->{pt_type} = typeOfPart($dev); $part->{start} = $prev_part ? $prev_part->{start} + $prev_part->{size} : 0; + put_in_hash($part, fs::type::type_subpart_from_magic($part)); $prev_part = $part; delete $part->{dev}; # cleanup } @$parts; } -sub all_hds { - my ($all_hds) = @_; - (@{$all_hds->{hds}}, @{$all_hds->{lvms}}); -} -sub part2hd { - my ($part, $all_hds) = @_; - my $hd = find { $part->{rootDevice} eq ($_->{device} || $_->{VG_name}) } all_hds($all_hds); - $hd; -} - sub is_same_hd { my ($hd1, $hd2) = @_; if ($hd1->{major} && $hd2->{major}) { @@ -338,96 +282,18 @@ sub is_same_hd { #- are_same_partitions() do not look at the device name since things may have changed sub are_same_partitions { my ($part1, $part2) = @_; - foreach ('start', 'size', 'pt_type', 'rootDevice') { - $part1->{$_} eq $part2->{$_} or return; + foreach ('start', 'size', 'pt_type', 'fs_type', 'rootDevice') { + $part1->{$_} eq $part2->{$_} or return 0; } 1; } -#- get all normal partition including special ones as found on sparc. -sub get_fstab { - map { partition_table::get_normal_parts($_) } @_; -} - -#- get normal partition that should be visible for working on. -sub get_visible_fstab { - grep { $_ && !partition_table::isWholedisk($_) && !partition_table::isHiddenMacPart($_) } - map { partition_table::get_normal_parts($_) } @_; -} - -sub get_fstab_and_holes { - map { - if (isLVM($_)) { - my @parts = partition_table::get_normal_parts($_); - my $free = $_->{totalsectors} - sum map { $_->{size} } @parts; - 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 get_holes { - grep { $_->{pt_type} == 0 } get_fstab_and_holes(@_); -} - -sub get_all_fstab { - my ($all_hds) = @_; - my @parts = map { partition_table::get_normal_parts($_) } all_hds($all_hds); - my @raids = grep { $_ } @{$all_hds->{raids}}; - @parts, @raids, @{$all_hds->{loopbacks}}; -} -sub get_really_all_fstab { - my ($all_hds) = @_; - my @parts = map { partition_table::get_normal_parts($_) } all_hds($all_hds); - my @raids = grep { $_ } @{$all_hds->{raids}}; - @parts, @raids, @{$all_hds->{loopbacks}}, @{$all_hds->{raw_hds}}, @{$all_hds->{nfss}}, @{$all_hds->{smbs}}, @{$all_hds->{davs}}; -} -sub get_all_fstab_and_holes { - my ($all_hds) = @_; - my @raids = grep { $_ } @{$all_hds->{raids}}; - get_fstab_and_holes(all_hds($all_hds)), @raids, @{$all_hds->{loopbacks}}; -} -sub get_all_holes { - my ($all_hds) = @_; - grep { $_->{pt_type} == 0 } get_all_fstab_and_holes($all_hds); -} - -sub all_free_space { - my ($all_hds) = @_; - sum map { $_->{size} } get_all_holes($all_hds); -} -sub free_space { - sum map { $_->{size} } get_holes(@_); -} - sub is_one_big_fat_or_NT { my ($hds) = @_; - @$hds == 1 or return; - - my @l = get_fstab(@$hds); - @l == 1 && isFat_or_NTFS($l[0]) && free_space(@$hds) < 10 << 11; -} + @$hds == 1 or return 0; -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 { loopback::carryRootLoopback($_) } @$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); + my @l = fs::get::hds_fstab(@$hds); + @l == 1 && isFat_or_NTFS($l[0]) && fs::get::hds_free_space(@$hds) < 10 << 11; } @@ -436,7 +302,7 @@ sub computeSize { my $max = $part->{maxsize} || $part->{size}; return min($max, $best->{size}) unless $best->{ratio}; - my $free_space = all_free_space($all_hds); + my $free_space = fs::get::free_space($all_hds); my @l = my @L = grep { if ($free_space >= $_->{size}) { $free_space -= $_->{size}; @@ -458,7 +324,7 @@ sub computeSize { return min($max, $best->{maxsize}) if $best->{mntpoint} eq $_->{mntpoint}; $free_space -= $_->{maxsize} - $_->{size}; if (!$cylinder_size_maxsize_adjusted++) { - eval { $free_space += part2hd($part, $all_hds)->cylinder_size - 1 }; + eval { $free_space += fs::get::part2hd($part, $all_hds)->cylinder_size - 1 }; } 0; } else { @@ -475,23 +341,28 @@ sub suggest_part { my ($part, $all_hds, $o_suggestions) = @_; my $suggestions = $o_suggestions || $suggestions{server} || $suggestions{simple}; - my $has_swap = any { isSwap($_) } get_all_fstab($all_hds); + #- suggestions now use {fs_type}, but still keep compatibility + foreach (@$suggestions) { + fs::type::set_pt_type($_, $_->{pt_type}) if !exists $_->{fs_type}; + } + + my $has_swap = any { isSwap($_) } fs::get::fstab($all_hds); my @local_suggestions = - grep { !has_mntpoint($_->{mntpoint}, $all_hds) || isSwap($_) && !$has_swap } + grep { !fs::get::has_mntpoint($_->{mntpoint}, $all_hds) || isSwap($_) && !$has_swap } grep { !$_->{hd} || $_->{hd} eq $part->{rootDevice} } @$suggestions; my ($best) = grep { !$_->{maxsize} || $part->{size} <= $_->{maxsize} } grep { $_->{size} <= ($part->{maxsize} || $part->{size}) } - grep { !$part->{pt_type} || $part->{pt_type} == $_->{pt_type} || isTrueFS($part) && isTrueFS($_) } + grep { !$part->{fs_type} || $part->{fs_type} eq $_->{fs_type} || isTrueFS($part) && isTrueFS($_) } @local_suggestions; - defined $best or return; #- sorry no suggestion :( + defined $best or return 0; #- sorry no suggestion :( $part->{mntpoint} = $best->{mntpoint}; - $part->{pt_type} = $best->{pt_type} if !(isTrueFS($best) && isTrueFS($part)); + fs::type::set_type_subpart($part, $best) if !isTrueFS($best) || !isTrueFS($part); $part->{size} = computeSize($part, $best, $all_hds, \@local_suggestions); foreach ('options', 'lv_name', 'encrypt_key') { $part->{$_} = $best->{$_} if $best->{$_}; @@ -501,59 +372,28 @@ sub suggest_part { sub suggestions_mntpoint { my ($all_hds) = @_; - sort grep { !/swap/ && !has_mntpoint($_, $all_hds) } + sort grep { !/swap/ && !fs::get::has_mntpoint($_, $all_hds) } (@suggestions_mntpoints, map { $_->{mntpoint} } @{$suggestions{server} || $suggestions{simple}}); } -sub mntpoint2part { - my ($mntpoint, $fstab) = @_; - find { $mntpoint eq $_->{mntpoint} } @$fstab; -} -sub has_mntpoint { - my ($mntpoint, $all_hds) = @_; - mntpoint2part($mntpoint, [ get_really_all_fstab($all_hds) ]); -} -sub get_root_ { - my ($fstab, $o_boot) = @_; - $o_boot && mntpoint2part("/boot", $fstab) || mntpoint2part("/", $fstab); -} -sub get_root { &get_root_ || {} } - -#- do this before modifying $part->{pt_type} -sub check_pt_type { - my ($pt_type, $_hd, $part) = @_; - isThisFs("jfs", { pt_type => $pt_type }) && $part->{size} < 16 << 11 and die N("You can't use JFS for partitions smaller than 16MB"); - isThisFs("reiserfs", { pt_type => $pt_type }) && $part->{size} < 32 << 11 and die N("You can't use ReiserFS for partitions smaller than 32MB"); -} - -sub package_needed_for_partition_type { - my ($part) = @_; - my %l = ( - reiserfs => 'reiserfsprogs', - xfs => 'xfsprogs', - jfs => 'jfsprogs', - ); - $l{type2fs($part)}; -} - #- you can do this before modifying $part->{mntpoint} #- so $part->{mntpoint} should not be used here, use $mntpoint instead sub check_mntpoint { my ($mntpoint, $hd, $part, $all_hds) = @_; - $mntpoint eq '' || isSwap($part) || isNonMountable($part) and return; + $mntpoint eq '' || isSwap($part) || isNonMountable($part) and return 0; $mntpoint =~ m|^/| or die N("Mount points must begin with a leading /"); $mntpoint =~ m|[\x7f-\xff]| and cdie N("Mount points should contain only alphanumerical characters"); - mntpoint2part($mntpoint, [ grep { $_ ne $part } get_really_all_fstab($all_hds) ]) and die N("There is already a partition with mount point %s\n", $mntpoint); + fs::get::mntpoint2part($mntpoint, [ grep { $_ ne $part } fs::get::really_all_fstab($all_hds) ]) and die N("There is already a partition with mount point %s\n", $mntpoint); cdie N("You've selected a software RAID partition as root (/). No bootloader is able to handle this without a /boot partition. -Please be sure to add a /boot partition") if $mntpoint eq "/" && isRAID($part) && !has_mntpoint("/boot", $all_hds); +Please be sure to add a /boot partition") if $mntpoint eq "/" && isRAID($part) && !fs::get::has_mntpoint("/boot", $all_hds); die N("You can't use a LVM Logical Volume for mount point %s", $mntpoint) if $mntpoint eq '/boot' && isLVM($hd); cdie N("You've selected a LVM Logical Volume as root (/). The bootloader is not able to handle this without a /boot partition. -Please be sure to add a /boot partition") if $mntpoint eq "/" && isLVM($part) && !has_mntpoint("/boot", $all_hds); +Please be sure to add a /boot partition") if $mntpoint eq "/" && isLVM($part) && !fs::get::has_mntpoint("/boot", $all_hds); cdie N("You may not be able to install lilo (since lilo doesn't handle a LV on multiple PVs)") if 0; # arch() =~ /i.86/ && $mntpoint eq '/' && isLVM($hd) && @{$hd->{disks} || []} > 1; @@ -591,12 +431,12 @@ sub add { sub allocatePartitions { my ($all_hds, $to_add) = @_; - foreach my $part_ (get_all_holes($all_hds)) { + foreach my $part_ (fs::get::holes($all_hds)) { my ($start, $size, $dev) = @$part_{"start", "size", "rootDevice"}; my $part; while (suggest_part($part = { start => $start, size => 0, maxsize => $size, rootDevice => $dev }, $all_hds, $to_add)) { - my $hd = part2hd($part, $all_hds); + my $hd = fs::get::part2hd($part, $all_hds); add($hd, $part, $all_hds, {}); $size -= $part->{size} + $part->{start} - $start; $start = $part->{start} + $part->{size}; @@ -606,7 +446,7 @@ sub allocatePartitions { sub auto_allocate { my ($all_hds, $o_suggestions) = @_; - my $before = listlength(get_all_fstab($all_hds)); + my $before = listlength(fs::get::fstab($all_hds)); my $suggestions = $o_suggestions || $suggestions{simple}; allocatePartitions($all_hds, $suggestions); @@ -623,9 +463,9 @@ sub auto_allocate { partition_table::assign_device_numbers($_) foreach @{$all_hds->{hds}}; - if ($before == listlength(get_all_fstab($all_hds))) { + if ($before == listlength(fs::get::fstab($all_hds))) { # find out why auto_allocate failed - if (any { !has_mntpoint($_->{mntpoint}, $all_hds) } @$suggestions) { + if (any { !fs::get::has_mntpoint($_->{mntpoint}, $all_hds) } @$suggestions) { die N("Not enough free space for auto-allocating"); } else { die N("Nothing to do"); @@ -636,31 +476,33 @@ sub auto_allocate { sub auto_allocate_raids { my ($all_hds, $suggestions) = @_; - my @raids = grep { isRawRAID($_) } get_all_fstab($all_hds) or return; + my @raids = grep { isRawRAID($_) } fs::get::fstab($all_hds) or return; require raid; my @mds = grep { $_->{hd} =~ /md/ } @$suggestions; foreach my $md (@mds) { my @raids_ = grep { !$md->{parts} || $md->{parts} =~ /\Q$_->{mntpoint}/ } @raids; @raids = difference2(\@raids, \@raids_); - my $nb = raid::new($all_hds->{raids}, @raids_); - my $part = $all_hds->{raids}[$nb]; my %h = %$md; - delete @h{'hd', 'parts'}; - put_in_hash($part, \%h); # mntpoint, level, chunk-size, pt_type + delete @h{'hd', 'parts'}; # keeping mntpoint, level, chunk-size, fs_type/pt_type + $h{disks} = \@raids_; + + my $part = raid::new($all_hds->{raids}, %h); + raid::updateSize($part); + push @raids, $part; #- we can build raid over raid } } sub auto_allocate_vgs { my ($all_hds, $suggestions) = @_; - my @pvs = grep { isRawLVM($_) } get_all_fstab($all_hds) or return; + my @pvs = grep { isRawLVM($_) } fs::get::fstab($all_hds) or return 0; - my @vgs = grep { $_->{VG_name} } @$suggestions or return; + my @vgs = grep { $_->{VG_name} } @$suggestions or return 0; - partition_table::write(@{$all_hds->{hds}}); + partition_table::write($_) foreach @{$all_hds->{hds}}; require lvm; @@ -762,17 +604,16 @@ sub move { } } -sub change_pt_type { - my ($pt_type, $hd, $part) = @_; - $pt_type != $part->{pt_type} or return; - check_pt_type($pt_type, $hd, $part); +sub change_type { + my ($type, $hd, $part) = @_; + $type->{pt_type} != $part->{pt_type} || $type->{fs_type} ne $part->{fs_type} or return; + fs::type::check($type->{fs_type}, $hd, $part); $hd->{isDirty} = 1; $part->{mntpoint} = '' if isSwap($part) && $part->{mntpoint} eq "swap"; - $part->{mntpoint} = '' if isRawLVM({ pt_type => $pt_type }) || isRawRAID({ pt_type => $pt_type }); - $part->{pt_type} = $pt_type; - $part->{notFormatted} = 1; - $part->{isFormatted} = 0; - fs::rationalize_options($part); + $part->{mntpoint} = '' if isRawLVM($type) || isRawRAID($type); + set_isFormatted($part, 0); + fs::type::set_type_subpart($part, $type); + fs::mount_options::rationalize($part); 1; } @@ -785,7 +626,8 @@ sub rescuept($) { local $_; while (<$F>) { my ($st, $si, $id) = /start=\s*(\d+),\s*size=\s*(\d+),\s*Id=\s*(\d+)/ or next; - my $part = { start => $st, size => $si, pt_type => hex($id) }; + my $part = { start => $st, size => $si }; + fs::type::set_pt_type($part, hex($id)); if (isExtended($part)) { $ext = $part; } else { |
