From fb99b425049ff55d76b863c9357d58d5925a3c3d Mon Sep 17 00:00:00 2001 From: Pascal Rigaux Date: Fri, 17 Aug 2001 17:09:25 +0000 Subject: a hell lot of cleanup/rewrite: * diskdrake_interactive created, diskdrake is now interactive aware * added some documentation about the structure used for partitioning * all_hds now contain the various hds, lvm, raid * cleanup the isLVM, isRAID and alike functions * field {type} in detect_devices is now {media_type} * detect_devices::floppies is now floppies_dev * removed old function prototypes --- perl-install/any.pm | 13 +- perl-install/bootloader.pm | 10 +- perl-install/bootlook.pm | 10 +- perl-install/detect_devices.pm | 51 ++--- perl-install/fs.pm | 51 +++-- perl-install/fsedit.pm | 292 +++++++++++++++++++---------- perl-install/install2.pm | 3 +- perl-install/install_any.pm | 21 +-- perl-install/install_interactive.pm | 35 ++-- perl-install/install_steps.pm | 32 ++-- perl-install/install_steps_auto_install.pm | 2 +- perl-install/install_steps_interactive.pm | 25 +-- perl-install/loopback.pm | 42 +++-- perl-install/partition_table.pm | 108 ++++++----- perl-install/partition_table_raw.pm | 12 -- perl-install/raid.pm | 87 +++++---- perl-install/standalone/diskdrake | 22 +-- 17 files changed, 471 insertions(+), 345 deletions(-) (limited to 'perl-install') diff --git a/perl-install/any.pm b/perl-install/any.pm index 8f0ee44ea..ffcc309a8 100644 --- a/perl-install/any.pm +++ b/perl-install/any.pm @@ -88,7 +88,8 @@ sub enableMD5Shadow { #- NO MORE USED } sub setupBootloader { - my ($in, $b, $hds, $fstab, $security, $prefix, $more) = @_; + my ($in, $b, $all_hds, $fstab, $security, $prefix, $more) = @_; + my $hds = $all_hds->{hds}; $more++ if $b->{bootUnsafe}; $more = 2 if arch() =~ /ppc/; #- no auto for PPC yet @@ -150,7 +151,7 @@ sub setupBootloader { arch() =~ /sparc/ ? ( { label => _("Bootloader installation"), val => \$silo_install_lang, list => \@silo_install_lang }, ) : if_(arch() !~ /ia64/, -{ label => _("Boot device"), val => \$b->{boot}, list => [ map { "/dev/$_" } (map { $_->{device} } (@$hds, grep { !isFat($_) } @$fstab)), detect_devices::floppies() ], not_edit => !$::expert }, +{ label => _("Boot device"), val => \$b->{boot}, list => [ map { "/dev/$_" } (map { $_->{device} } (@$hds, grep { !isFat($_) } @$fstab)), detect_devices::floppies_dev() ], not_edit => !$::expert }, { label => _("LBA (doesn't work on old BIOSes)"), val => \$b->{lba32}, type => "bool", text => "lba", advanced => 1 }, { label => _("Compact"), val => \$b->{compact}, type => "bool", text => _("compact"), advanced => 1 }, { label => _("Video mode"), val => \$b->{vga}, list => [ keys %bootloader::vga_modes ], not_edit => !$::expert, advanced => 1 }, @@ -308,14 +309,6 @@ if (arch() !~ /ppc/) { 1; } -sub partitions_suggestions { - my ($in) = @_; - my $t = $::expert ? - $in->ask_from_list_('', _("What type of partitioning?"), [ keys %fsedit::suggestions ]) : - 'simple'; - $fsedit::suggestions{$t}; -} - my @etc_pass_fields = qw(name pw uid gid realname home shell); sub unpack_passwd { my ($l) = @_; diff --git a/perl-install/bootloader.pm b/perl-install/bootloader.pm index 453b7c7c6..2cd02125e 100644 --- a/perl-install/bootloader.pm +++ b/perl-install/bootloader.pm @@ -117,7 +117,7 @@ sub read($$) { \%b; } -sub suggest_onmbr ($) { +sub suggest_onmbr { my ($hds) = @_; my $type = partition_table_raw::typeOfMBR($hds->[0]{device}); @@ -395,7 +395,7 @@ wait %d seconds for default boot. yaboot => to_bool(arch() =~ /ppc/), silo => to_bool(arch() =~ /sparc/), lilo => to_bool(arch() !~ /sparc|ppc/) && !isLoopback(fsedit::get_root($fstab)), - grub => to_bool(arch() !~ /sparc|ppc/ && availableRamMB() < 800), #- don't use grub if more than 800MB + grub => to_bool(arch() !~ /sparc|ppc/ && !isRAID(fsedit::get_root($fstab)) && availableRamMB() < 800), #- don't use grub if more than 800MB loadlin => to_bool(arch() !~ /sparc|ppc/) && -e "/initrd/loopfs/lnx4win", ); unless ($lilo->{methods}) { @@ -764,7 +764,7 @@ sub dev2grub { sub write_grub_config { my ($prefix, $lilo, $fstab, $hds) = @_; my %dev2bios = ( - (map_index { $_ => "fd$::i" } detect_devices::floppies()), + (map_index { $_ => "fd$::i" } detect_devices::floppies_dev()), (map_index { $_ => "hd$::i" } dev2bios($hds, $lilo->{boot})), ); @@ -984,10 +984,10 @@ sub install { } $lilo->{keytable} = keytable($prefix, $lilo->{keytable}); - if (arch() =~ /i.86/) { + if (exists $lilo->{methods}{grub}) { #- when lilo is selected, we don't try to install grub. #- just create the config file in case it may be useful - write_grub_config($prefix, $lilo, $fstab, $hds); + eval { write_grub_config($prefix, $lilo, $fstab, $hds) }; } my %l = grep_each { $::b } %{$lilo->{methods}}; diff --git a/perl-install/bootlook.pm b/perl-install/bootlook.pm index ce756e6b7..a9cac7b0f 100644 --- a/perl-install/bootlook.pm +++ b/perl-install/bootlook.pm @@ -331,15 +331,15 @@ sub lilo_choice local ($_) = `detectloader`; $bootloader->{methods} = { lilo => 1, grub => !!/grub/i }; - my ($hds) = catch_cdie { fsedit::hds([ detect_devices::hds() ], {}) } sub { 1 }; - my $fstab = [ fsedit::get_fstab(@$hds) ]; - fs::get_mntpoints_from_fstab($fstab); + my ($all_hds) = catch_cdie { fsedit::hds([ detect_devices::hds() ], {}) } sub { 1 }; + my $fstab = [ fsedit::get_all_fstab($all_hds) ]; + fs::get_all_mntpoints_from_fstab($all_hds); $::expert=1; ask: local $::isEmbedded = 0; - any::setupBootloader($in, $bootloader, $hds, $fstab, $ENV{SECURE_LEVEL}) or return; - eval { bootloader::install('', $bootloader, $fstab, $hds) }; + any::setupBootloader($in, $bootloader, $all_hds->{hds}, $fstab, $ENV{SECURE_LEVEL}) or return; + eval { bootloader::install('', $bootloader, $fstab, $all_hds->{hds}) }; if ($@) { $in->ask_warn('', [ _("Installation of LILO failed. The following error occured:"), diff --git a/perl-install/detect_devices.pm b/perl-install/detect_devices.pm index 36a171072..6fcbc2aad 100644 --- a/perl-install/detect_devices.pm +++ b/perl-install/detect_devices.pm @@ -30,13 +30,13 @@ sub get { getIDE(), getSCSI(), getDAC960(), getCompaqSmartArray(); } -sub hds() { grep { $_->{type} eq 'hd' && ($::isStandalone || !isRemovableDrive($_)) } get(); } -sub zips() { grep { $_->{type} =~ /.d/ && isZipDrive($_) } get(); } -sub ide_zips() { grep { $_->{type} =~ /.d/ && isZipDrive($_) } getIDE(); } -#-sub jazzs() { grep { $_->{type} =~ /.d/ && isJazDrive($_) } get(); } -sub ls120s() { grep { $_->{type} =~ /.d/ && isLS120Drive($_) } get(); } +sub hds() { grep { $_->{media_type} eq 'hd' && ($::isStandalone || !isRemovableDrive($_)) } get(); } +sub zips() { grep { $_->{media_type} =~ /.d/ && isZipDrive($_) } get(); } +sub ide_zips() { grep { $_->{media_type} =~ /.d/ && isZipDrive($_) } getIDE(); } +#-sub jazzs() { grep { $_->{media_type} =~ /.d/ && isJazDrive($_) } get(); } +sub ls120s() { grep { $_->{media_type} =~ /.d/ && isLS120Drive($_) } get(); } sub cdroms() { - my @l = grep { $_->{type} eq 'cdrom' } get(); + my @l = grep { $_->{media_type} eq 'cdrom' } get(); if (my @l2 = IDEburners()) { require modules; modules::add_alias('scsi_hostadapter', 'ide-scsi'); @@ -49,9 +49,9 @@ sub cdroms() { } @l; } -sub burners { grep { $_->{type} eq 'cdrom' && isBurner($_) } get() } -sub IDEburners { grep { $_->{type} eq 'cdrom' && isBurner($_) } getIDE() } -sub dvdroms { grep { $_->{type} eq 'cdrom' && isDvdDrive($_) } get() } +sub burners { grep { $_->{media_type} eq 'cdrom' && isBurner($_) } get() } +sub IDEburners { grep { $_->{media_type} eq 'cdrom' && isBurner($_) } getIDE() } +sub dvdroms { grep { $_->{media_type} eq 'cdrom' && isDvdDrive($_) } get() } sub get_mac_model() { my $mac_model = cat_("/proc/device-tree/model") || die "Can't open /proc/device-tree/model"; @@ -76,12 +76,13 @@ sub get_mac_generation() { sub floppies() { require modules; eval { modules::load("floppy") }; - my @fds = grep { tryOpen($_) } qw(fd0 fd1); + my @fds = map {; { device => $_, media_type => 'fd' } } grep { tryOpen($_) } qw(fd0 fd1); my @ide = ls120s() and modules::load("ide-floppy"); - my @scsi = grep { $_->{type} eq 'fd' } getSCSI(); - (map { $_->{device} } @ide, @scsi), @fds; + my @scsi = grep { $_->{media_type} eq 'fd' } getSCSI(); + @ide, @scsi, @fds; } -sub floppy { first(floppies()) } +sub floppies_dev() { map { $_->{device} } floppies() } +sub floppy { first(floppies_dev()) } #- example ls120, model = "LS-120 SLIM 02 UHD Floppy" sub isBurner { @@ -101,7 +102,7 @@ sub isDvdDrive { sub isZipDrive { $_[0]->{info} =~ /ZIP\s+\d+/ } #- accept ZIP 100, untested for bigger ZIP drive. #-sub isJazzDrive { $_[0]->{info} =~ /JAZZ?\s+/ } #- untested. sub isLS120Drive { $_[0]->{info} =~ /LS-?120|144MB/ } -sub isRemovableDrive { &isZipDrive || &isLS120Drive || $_[0]->{type} eq 'fd' } #-or &isJazzDrive } +sub isRemovableDrive { &isZipDrive || &isLS120Drive || $_[0]->{media_type} eq 'fd' } #-or &isJazzDrive } sub isFloppyOrHD { my ($dev) = @_; @@ -134,7 +135,7 @@ sub getSCSI() { $device = "scd" . $cdromNum++; $type = 'cdrom'; } - $device and push @drives, { device => $device, type => $type, info => "$vendor $model", id => $id, bus => 0 }; + $device and push @drives, { device => $device, media_type => $type, info => "$vendor $model", id => $id, bus => 0 }; } @drives; } @@ -152,7 +153,7 @@ sub getIDE() { my $info = chomp_(cat_("$d/model")) || "(none)"; my $num = ord (($d =~ /(.)$/)[0]) - ord 'a'; - push @idi, { type => $type, device => basename($d), info => $info, bus => $num/2, id => $num%2 }; + push @idi, { media_type => $type, device => basename($d), info => $info, bus => $num/2, id => $num%2 }; } @idi; } @@ -168,7 +169,7 @@ sub getCompaqSmartArray() { for (my $i = 0; -r ($f = "${prefix}$i"); $i++) { foreach (cat_($f)) { if (m|^\s*($name/.*?):|) { - push @idi, { device => $1, info => "Compaq RAID logical disk", type => 'hd' }; + push @idi, { device => $1, info => "Compaq RAID logical disk", media_type => 'hd' }; } } } @@ -183,7 +184,7 @@ sub getDAC960() { #- /dev/rd/c0d0: RAID-7, Online, 17928192 blocks, Write Thru0123456790123456789012 foreach (syslog()) { my ($device, $info) = m|/dev/(rd/.*?): (.*?),| or next; - $idi{$device} = { info => $info, type => 'hd', device => $device }; + $idi{$device} = { info => $info, media_type => 'hd', device => $device }; log::l("DAC960: $device ($info)"); } values %idi; @@ -210,7 +211,7 @@ sub pci_probe { my ($probe_type) = @_; map { my %l; - @l{qw(vendor id subvendor subid pci_bus pci_device pci_function type driver description)} = split "\t"; + @l{qw(vendor id subvendor subid pci_bus pci_device pci_function media_type driver description)} = split "\t"; $l{$_} = hex $l{$_} foreach qw(vendor id subvendor subid); $l{bus} = 'PCI'; \%l @@ -222,7 +223,7 @@ sub usb_probe { map { my %l; - @l{qw(vendor id type driver description)} = split "\t"; + @l{qw(vendor id media_type driver description)} = split "\t"; $l{$_} = hex $l{$_} foreach qw(vendor id); $l{bus} = 'USB'; \%l @@ -247,7 +248,7 @@ sub stringlist { sprintf("%-16s: %s%s%s", $_->{driver} ? $_->{driver} : 'unknown', $_->{description} eq '(null)' ? sprintf("Vendor=0x%04x Device=0x%04x", $_->{vendor}, $_->{id}) : $_->{description}, - $_->{type} ? sprintf(" [%s]", $_->{type}) : '', + $_->{media_type} ? sprintf(" [%s]", $_->{media_type}) : '', $_->{subid} && $_->{subid} != 0xffff ? sprintf(" SubVendor=0x%04x SubDevice=0x%04x", $_->{subvendor}, $_->{subid}) : '', ); } probeall(1); @@ -318,14 +319,14 @@ sub whatParport() { @res; } -sub usbMice { grep { $_->{type} =~ /\|Mouse/ && $_->{driver} !~ /Tablet:wacom/} usb_probe() } +sub usbMice { grep { $_->{media_type} =~ /\|Mouse/ && $_->{driver} !~ /Tablet:wacom/} usb_probe() } sub usbWacom { grep { $_->{driver} =~ /Tablet:wacom/ } usb_probe() } -sub usbKeyboards { grep { $_->{type} =~ /\|Keyboard/ } usb_probe() } -sub usbZips { grep { $_->{type} =~ /Mass Storage\|/ } usb_probe() } +sub usbKeyboards { grep { $_->{media_type} =~ /\|Keyboard/ } usb_probe() } +sub usbZips { grep { $_->{media_type} =~ /Mass Storage\|/ } usb_probe() } sub whatUsbport() { my ($i, $elem, @res) = (0, {}); - foreach (grep { $_->{type} =~ /Printer/ } usb_probe()) { + foreach (grep { $_->{media_type} =~ /Printer/ } usb_probe()) { my ($manufacturer, $model) = split '\|', $_->{description}; $_->{description} =~ s/Hewlett[-\s_]Packard/HP/; push @res, { port => "/dev/usb/lp$i", val => { CLASS => 'PRINTER', diff --git a/perl-install/fs.pm b/perl-install/fs.pm index 9973c5780..ed23f77e4 100644 --- a/perl-install/fs.pm +++ b/perl-install/fs.pm @@ -24,6 +24,11 @@ sub add_options(\$@) { $$option = join(',', keys %l) || "defaults"; } +sub raw_hds { + detect_devices::floppies(), detect_devices::cdroms(), + (map { $_->{device} .= '4'; $_ } detect_devices::zips()); +} + sub read_fstab($) { my ($file) = @_; @@ -61,22 +66,28 @@ sub check_mounted($) { } sub get_mntpoints_from_fstab { - my ($fstab, $prefix, $uniq) = @_; - + my ($l, $prefix, $uniq) = @_; log::l("reading fstab"); foreach (read_fstab("$prefix/etc/fstab")) { - next if $uniq && fsedit::mntpoint2part($_->{mntpoint}, $fstab); + next if $uniq && fsedit::mntpoint2part($_->{mntpoint}, $l); + ($_->{device} = expand_symlinks(($_->{device} =~ m|^/| ? '' : '/dev/') . $_->{device})) =~ s|^/dev/||; - foreach my $p (@$fstab) { + foreach my $p (@$l) { $p->{device} eq $_->{device} or next; $_->{type} ne 'auto' && $_->{type} ne type2fs($p->{type}) and log::l("err, fstab and partition table do not agree for $_->{device} type: " . (type2fs($p->{type}) || type2name($p->{type})) . " vs $_->{type}"), next; delete $p->{unsafeMntpoint} || !$p->{mntpoint} or next; + $p->{type} ||= $_->{type}; $p->{mntpoint} = $_->{mntpoint}; $p->{options} = $_->{options}; } } } +sub get_all_mntpoints_from_fstab { + my ($all_hds, $prefix, $uniq) = @_; + my @l = (fsedit::get_all_fstab($all_hds), @{$all_hds->{raw_hds}}); + get_mntpoints_from_fstab(\@l, $prefix, $uniq); +} #- mke2fs -b (1024|2048|4096) -c -i(1024 > 262144) -N (1 > 100000000) -m (0-100%) -L volume-label #- tune2fs @@ -161,10 +172,10 @@ sub real_format_part { $part->{isFormatted} = 1; } sub format_part { - my ($raid, $part, $prefix) = @_; - if (isMDRAID($part)) { + my ($raids, $part, $prefix) = @_; + if (isRAID($part)) { require raid; - raid::format_part($raid, $part); + raid::format_part($raids, $part); } elsif (isLoopback($part)) { loopback::format_part($part, $prefix); } else { @@ -173,25 +184,25 @@ sub format_part { } sub formatMount_part { - my ($part, $raid, $fstab, $prefix, $callback) = @_; + my ($part, $raids, $fstab, $prefix, $callback) = @_; if (isLoopback($part)) { - formatMount_part($part->{device}, $raid, $fstab, $prefix, $callback); + formatMount_part($part->{loopback_device}, $raids, $fstab, $prefix, $callback); } if (my $p = up_mount_point($part->{mntpoint}, $fstab)) { - formatMount_part($p, $raid, $fstab, $prefix, $callback) unless loopback::carryRootLoopback($part); + formatMount_part($p, $raids, $fstab, $prefix, $callback) unless loopback::carryRootLoopback($part); } if ($part->{toFormat}) { $callback->($part) if $callback; - format_part($raid, $part, $prefix); + format_part($raids, $part, $prefix); } mount_part($part, $prefix); } sub formatMount_all { - my ($raid, $fstab, $prefix, $callback) = @_; - formatMount_part($_, $raid, $fstab, $prefix, $callback) + my ($raids, $fstab, $prefix, $callback) = @_; + formatMount_part($_, $raids, $fstab, $prefix, $callback) foreach sort { isLoopback($a) ? 1 : isSwap($a) ? -1 : 0 } grep { $_->{mntpoint} } @$fstab; #- ensure the link is there @@ -206,7 +217,7 @@ sub formatMount_all { }; } -sub mount($$$;$) { +sub mount { my ($dev, $where, $fs, $rdonly) = @_; log::l("mounting $dev on $where as type $fs"); @@ -252,7 +263,7 @@ sub mount($$$;$) { } #- takes the mount point to umount (can also be the device) -sub umount($) { +sub umount { my ($mntpoint) = @_; $mntpoint =~ s|/$||; log::l("calling umount($mntpoint)"); @@ -261,7 +272,7 @@ sub umount($) { substInFile { $_ = '' if /(^|\s)$mntpoint\s/ } '/etc/mtab'; #- don't care about error, if we can't read, we won't manage to write... (and mess mtab) } -sub mount_part($;$$) { +sub mount_part { my ($part, $prefix, $rdonly) = @_; #- root carrier's link can't be mounted @@ -271,7 +282,7 @@ sub mount_part($;$$) { unless ($::testing) { if (isSwap($part)) { - swap::swapon(isLoopback($part) ? $prefix . loopback::file($part) : $part->{device}); + swap::swapon($part->{device}); } else { $part->{mntpoint} or die "missing mount point"; @@ -279,7 +290,7 @@ sub mount_part($;$$) { my $mntpoint = ($prefix || '') . $part->{mntpoint}; if (isLoopback($part)) { eval { modules::load('loop') }; - $dev = $part->{real_device} = devices::set_loop($prefix . loopback::file($part)) || die; + $dev = $part->{real_device} = devices::set_loop($part->{device}) || die; } elsif (loopback::carryRootLoopback($part)) { $mntpoint = "/initrd/loopfs"; } @@ -290,7 +301,7 @@ sub mount_part($;$$) { $part->{isMounted} = $part->{isFormatted} = 1; #- assume that if mount works, partition is formatted } -sub umount_part($;$) { +sub umount_part { my ($part, $prefix) = @_; $part->{isMounted} or return; @@ -420,7 +431,7 @@ sub write_fstab($;$$@) { #isThisFs("reiserfs", $_) && $_ == fsedit::get_root($fstab, 'boot') and add_options($options, "notail"); my $dev = isLoopback($_) ? - ($_->{mntpoint} eq '/' ? "/initrd/loopfs$_->{loopback_file}" : loopback::file($_)) : + ($_->{mntpoint} eq '/' ? "/initrd/loopfs$_->{loopback_file}" : $_->{device}) : ($_->{device} =~ /^\// ? $_->{device} : "$dir$_->{device}"); local $_->{mntpoint} = do { diff --git a/perl-install/fsedit.pm b/perl-install/fsedit.pm index 365873234..69c2925e5 100644 --- a/perl-install/fsedit.pm +++ b/perl-install/fsedit.pm @@ -74,9 +74,18 @@ sub typeOfPart { #-###################################################################################### #- Functions #-###################################################################################### +sub empty_all_hds { + { hds => [], lvms => [], raids => [], loopbacks => [], raw_hds => [] }; +} +sub recompute_loopbacks { + my ($all_hds) = @_; + my @fstab = get_all_fstab($all_hds); + $all_hds->{loopbacks} = [ map { isPartOfLoopback($_) ? @{$_->{loopback}} : () } @fstab ]; +} + sub hds { my ($drives, $flags) = @_; - my (@hds, @lvms, @raid); + my (@hds, @lvms, @raids); my $rc; foreach (@$drives) { @@ -103,7 +112,7 @@ sub hds { } push @hds, $hd; } - if (my @pvs = grep { isLVM($_) } map { partition_table::get_normal_parts($_) } @hds) { + if (my @pvs = grep { isRawLVM($_) } map { partition_table::get_normal_parts($_) } @hds) { #- otherwise vgscan won't find them devices::make($_->{device}) foreach @pvs; require lvm; @@ -111,7 +120,7 @@ sub hds { my $name = lvm::get_vg($_) or next; my ($lvm) = grep { $_->{LVMname} eq $name } (@hds, @lvms); if (!$lvm) { - $lvm = bless { disks => [], LVMname => $name, level => 'linear' }, 'lvm'; + $lvm = bless { disks => [], LVMname => $name }, 'lvm'; lvm::update_size($lvm); lvm::get_lvs($lvm); push @lvms, $lvm; @@ -120,7 +129,7 @@ sub hds { push @{$lvm->{disks}}, $_; } } - if ((my @parts = grep { isRAID($_) } map { partition_table::get_normal_parts($_) } @hds) && detect_devices::raidAutoStart()) { + if ((my @parts = grep { isRawRAID($_) } map { partition_table::get_normal_parts($_) } @hds) && detect_devices::raidAutoStart()) { my @mdstat = cat_("/proc/mdstat"); for (my $i=0 ; $i<@mdstat ; $i++) { next if $mdstat[$i] !~ /^md(.).* ([^ \[\]]+) ([^ ]+\[[^ \]]+\])(.*)$/; @@ -148,43 +157,134 @@ sub hds { $type = 0x83; $notformat = 1; } - $raid[$nb] = { 'chunk-size' => $chunks, type => $type, disks => \@disks, + $raids[$nb] = { 'chunk-size' => $chunks, type => $type, disks => \@disks, device => "md$nb", notFormatted => $notformat, level => $level }; } require raid; - raid::update(@raid); + raid::update(@raids); } - \@hds, \@lvms, \@raid; + + my $l = { %{ empty_all_hds() }, hds => \@hds, lvms => \@lvms, raids => \@raids }; + $l; +} + + +sub read_partitions() { + my (undef, undef, @all) = cat_("/proc/partitions"); + grep { + $_->{size} != 1 && # skip main extended partition + $_->{size} != 0x3fffffff # skip cdroms (otherwise stops cd-audios) + } map { + my %l; + @l{qw(major minor size dev)} = split; + \%l; + } @all; } sub readProcPartitions { my ($hds) = @_; - my @parts; - foreach (cat_("/proc/partitions")) { - my (undef, undef, $size, $device) = split; - next if $size eq "1"; #- extended partitions - foreach (@$hds) { - push @parts, { start => 0, size => $size * 2, device => $device, - type => typeOfPart($device), rootDevice => $_->{device} - } if $device =~ /^$_->{device}./; + + my @all = read_partitions(); + my @parts = grep { $_->{dev} =~ /\d$/ } @all; + my @disks = grep { $_->{dev} !~ /\d$/ } @all; + + my $devfs_like = grep { $_->{dev} =~ m|/disc$| } @disks; + + my %devfs2normal = map { + my (undef, $major, $minor) = devices::entry($_->{device}); + my ($disk) = grep { $_->{major} == $major && $_->{minor} == $minor } @disks; + $disk->{dev} => $_->{device}; + } @$hds; + + foreach my $part (@parts) { + my $dev; + if ($devfs_like) { + $dev = -e "/dev/$part->{dev}" ? $part->{dev} : sprintf("%x%02x", $part->{major}, $part->{minor}); + $part->{rootDevice} = $devfs2normal{dirname($part->{dev}) . '/disc'}; + } else { + $dev = $part->{dev}; + foreach my $hd (@$hds) { + $part->{rootDevice} = $hd->{device} if $part->{dev} =~ /^$hd->{device}./; + } } + $part->{device} = $dev; + $part->{start} = 0; # unknown, but we don't care + $part->{size} *= 2; # from KB to sectors + $part->{type} = typeOfPart($dev); + + delete @$part{'major', 'minor', 'dev'}; # cleanup } @parts; } +sub all_hds { + my ($all_hds) = @_; + (@{$all_hds->{hds}}, @{$all_hds->{lvms}}); +} +sub part2hd { + my ($part, $all_hds) = @_; + my ($hd) = grep { $part->{rootDevice} eq $_->{device} } all_hds($all_hds); + $hd; +} + +sub is_same_part { + my ($part1, $part2) = @_; + foreach ('start', 'size', 'type', 'rootDevice') { + $part1->{$_} eq $part2->{$_} or return; + } + 1; +} + #- get all normal partition including special ones as found on sparc. sub get_fstab { - loopback::loopbacks(@_), map { partition_table::get_normal_parts($_) } @_ + 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($_) } @_; + 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, type => 0, rootDevice => $_->{device} }; + @parts, if_($free >= $_->cylinder_size, $free_part); + } else { + partition_table::get_normal_parts_and_holes($_); + } + } @_; +} +sub get_holes { + grep { $_->{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_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 { $_->{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} } map { partition_table::get_holes($_) } @_; + sum map { $_->{size} } get_holes(@_); } sub is_one_big_fat { @@ -218,13 +318,13 @@ sub file2part { sub computeSize { - my ($part, $best, $hds, $suggestions) = @_; + my ($part, $best, $all_hds, $suggestions) = @_; my $max = $part->{maxsize} || $part->{size}; return min($max, $best->{size}) unless $best->{ratio}; - my $free_space = free_space(@$hds); + my $free_space = all_free_space($all_hds); my @l = my @L = grep { - if (!has_mntpoint($_->{mntpoint}, $hds) && $free_space >= $_->{size}) { + if (!has_mntpoint($_->{mntpoint}, $all_hds) && $free_space >= $_->{size}) { $free_space -= $_->{size}; 1; } else { 0 } } @$suggestions; @@ -254,15 +354,15 @@ sub computeSize { } sub suggest_part { - my ($part, $hds, $suggestions) = @_; + my ($part, $all_hds, $suggestions) = @_; $suggestions ||= $suggestions{server}; - my $has_swap = grep { isSwap($_) } get_fstab(@$hds); + my $has_swap = grep { isSwap($_) } get_all_fstab($all_hds); my ($best, $second) = grep { !$_->{maxsize} || $part->{size} <= $_->{maxsize} } grep { $_->{size} <= ($part->{maxsize} || $part->{size}) } - grep { !has_mntpoint($_->{mntpoint}, $hds) || isSwap($_) && !$has_swap } + grep { !has_mntpoint($_->{mntpoint}, $all_hds) || isSwap($_) && !$has_swap } grep { !$_->{hd} || $_->{hd} eq $part->{rootDevice} } grep { !$part->{type} || $part->{type} == $_->{type} || isTrueFS($part) && isTrueFS($_) } @$suggestions or return; @@ -277,13 +377,13 @@ sub suggest_part { $part->{mntpoint} = $best->{mntpoint}; $part->{type} = $best->{type}; - $part->{size} = computeSize($part, $best, $hds, $suggestions); + $part->{size} = computeSize($part, $best, $all_hds, $suggestions); 1; } sub suggestions_mntpoint { - my ($hds) = @_; - sort grep { !/swap/ && !has_mntpoint($_, $hds) } + my ($all_hds) = @_; + sort grep { !/swap/ && !has_mntpoint($_, $all_hds) } (@suggestions_mntpoints, map { $_->{mntpoint} } @{$suggestions{server}}); } @@ -312,8 +412,8 @@ sub mntpoint2part { first(grep { $mntpoint eq $_->{mntpoint} } @$fstab); } sub has_mntpoint { - my ($mntpoint, $hds) = @_; - mntpoint2part($mntpoint, [ get_fstab(@$hds) ]); + my ($mntpoint, $all_hds) = @_; + mntpoint2part($mntpoint, [ get_all_fstab($all_hds) ]); } sub get_root_ { my ($fstab, $boot) = @_; @@ -321,102 +421,97 @@ sub get_root_ { } sub get_root { &get_root_ || {} } +#- do this before modifying $part->{type} +sub check_type { + my ($type, $hd, $part) = @_; + isThisFs("jfs", { type => name2type($type) }) && $part->{size} < 16 << 11 and die _("You can't use JFS for partitions smaller than 16MB"); + isThisFs("reiserfs", { type => name2type($type) }) && $part->{size} < 32 << 11 and die _("You can't use ReiserFS for partitions smaller than 32MB"); +} + #- do this before modifying $part->{mntpoint} #- $part->{mntpoint} should not be used here, use $mntpoint instead sub check_mntpoint { - my ($mntpoint, $hd, $part, $hds, $loopbackDevice) = @_; - - ref $loopbackDevice or undef $loopbackDevice; + my ($mntpoint, $hd, $part, $all_hds) = @_; $mntpoint eq '' || isSwap($part) || isNonMountable($part) and return; + $mntpoint =~ m|^/| or die _("Mount points must begin with a leading /"); + has_mntpoint($mntpoint, $all_hds) and die _("There is already a partition with mount point %s\n", $mntpoint); + + die "raid / with no /boot" + if $mntpoint eq "/" && isRAID($part) && !has_mntpoint("/boot", $all_hds); + die _("You can't use a LVM Logical Volume for mount point %s", $mntpoint) + if ($mntpoint eq '/' || $mntpoint eq '/boot') && isLVM($hd); + die _("This directory should remain within the root filesystem") + if member($mntpoint, qw(/bin /dev /etc /lib /sbin)); + die _("You need a true filesystem (ext2, reiserfs) for this mount point\n") + if !isTrueFS($part) && member($mntpoint, qw(/ /home /tmp /usr /var)); + + local $part->{mntpoint} = $mntpoint; + loopback::check_circular_mounts($hd, $part, $all_hds); +} - local $_ = $mntpoint; - m|^/| or die _("Mount points must begin with a leading /"); -#- m|(.)/$| and die "The mount point $_ is illegal.\nMount points may not end with a /"; - - has_mntpoint($mntpoint, $hds) and die _("There is already a partition with mount point %s\n", $mntpoint); - - my $fake_part = { mntpoint => $mntpoint, device => $loopbackDevice }; - $fake_part->{loopback_file} = 1 if $loopbackDevice; - my $fstab = [ get_fstab(@$hds), $fake_part ]; - my $check; $check = sub { - my ($p, @seen) = @_; - push @seen, $p->{mntpoint} || return; - @seen > 1 && $p->{mntpoint} eq $mntpoint and die _("Circular mounts %s\n", join(", ", @seen)); - if (my $part = fs::up_mount_point($p->{mntpoint}, $fstab)) { - #- '/' carrier is a special case, it will be mounted first - $check->($part, @seen) unless loopback::carryRootLoopback($p); - } - if (isLoopback($p)) { - $check->($p->{device}, @seen); - } - }; - $check->($fake_part) unless $mntpoint eq '/' && $loopbackDevice; #- '/' is a special case, no loop check - - die "raid / with no /boot" if $mntpoint eq "/" && isMDRAID($part) && !has_mntpoint("/boot", $hds); - die _("You can't use a LVM Logical Volume for mount point %s", $mntpoint) if ($mntpoint eq '/' || $mntpoint eq '/boot') && isLVMBased($hd); - die _("This directory should remain within the root filesystem") if member($mntpoint, qw(/bin /dev /etc /lib /sbin)); - die _("You need a true filesystem (ext2, reiserfs) for this mount point\n") if !isTrueFS($part) && member($mntpoint, qw(/ /home /tmp /usr /var)); -#- if ($part->{start} + $part->{size} > 1024 * $hd->cylinder_size() && arch() =~ /i.86/) { -#- die "/boot ending on cylinder > 1024" if $mntpoint eq "/boot"; -#- die "/ ending on cylinder > 1024" if $mntpoint eq "/" && !has_mntpoint("/boot", $hds); -#- } +sub check { + my ($hd, $part, $all_hds) = @_; + check_mntpoint($part->{mntpoint}, $hd, $part, $all_hds); + check_type($part->{type}, $hd, $part); } -sub add($$$;$) { - my ($hd, $part, $hds, $options) = @_; +sub add { + my ($hd, $part, $all_hds, $options) = @_; isSwap($part) ? ($part->{mntpoint} = 'swap') : - $options->{force} || check_mntpoint($part->{mntpoint}, $hd, $part, $hds); + $options->{force} || check_mntpoint($part->{mntpoint}, $hd, $part, $all_hds); delete $part->{maxsize}; - if (isLVMBased($hd)) { + if (isLVM($hd)) { lvm::lv_create($hd, $part); } else { partition_table::add($hd, $part, $options->{primaryOrExtended}); } } -sub allocatePartitions($$) { - my ($hds, $to_add) = @_; - - foreach my $hd (@$hds) { - foreach (partition_table::get_holes($hd)) { - my ($start, $size) = @$_{"start", "size"}; - my $part; - while (suggest_part($part = { start => $start, size => 0, maxsize => $size, rootDevice => $hd->{device} }, - $hds, $to_add)) { - add($hd, $part, $hds); - $size -= $part->{size} + $part->{start} - $start; - $start = $part->{start} + $part->{size}; - } +sub allocatePartitions { + my ($all_hds, $to_add) = @_; + + foreach my $part (get_all_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) = fsedit::part2hd($part, $all_hds); + add($hd, $part, $all_hds); + $size -= $part->{size} + $part->{start} - $start; + $start = $part->{start} + $part->{size}; } } } sub auto_allocate { - my ($hds, $suggestions, $raid) = @_; - allocatePartitions($hds, $suggestions || $suggestions{simple}); + my ($all_hds, $suggestions) = @_; + my $before = listlength(fsedit::get_all_fstab($all_hds)); + + allocatePartitions($all_hds, $suggestions || $suggestions{simple}); + auto_allocate_raids($all_hds, $suggestions) if $suggestions; - auto_allocate_raids($hds, $suggestions, $raid) if $raid && $suggestions; + partition_table::assign_device_numbers($_) foreach @{$all_hds->{hds}}; - map { partition_table::assign_device_numbers($_) } @$hds; + $before != listlength(fsedit::get_all_fstab($all_hds)); } sub auto_allocate_raids { - my ($hds, $suggestions, $raid) = @_; + my ($all_hds, $suggestions) = @_; - my @raids = grep { isRAID($_) } get_fstab(@$hds) or return; + my @raids = grep { isRawRAID($_) } get_all_fstab($all_hds) or return; if (@raids) { 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($raid, @raids_); - my $part = $raid->[$nb]; + my $nb = raid::new($all_hds->{raids}, @raids_); + my $part = $all_hds->{raids}[$nb]; my %h = %$md; delete @h{'hd', 'parts'}; @@ -425,28 +520,30 @@ sub auto_allocate_raids { } } -sub undo_prepare($) { - my ($hds) = @_; +sub undo_prepare { + my ($all_hds) = @_; require Data::Dumper; $Data::Dumper::Purity = 1; - foreach (@$hds) { + foreach (@{$all_hds->{hds}}) { my @h = @{$_}{@partition_table::fields2save}; push @{$_->{undo}}, Data::Dumper->Dump([\@h], ['$h']); } } -sub undo($) { - my ($hds) = @_; - foreach (@$hds) { +sub undo { + my ($all_hds) = @_; + foreach (@{$all_hds->{hds}}) { my $h; eval pop @{$_->{undo}} || next; @{$_}{@partition_table::fields2save} = @$h; $_->{isDirty} = $_->{needKernelReread} = 1 if $_->{hasBeenDirty}; } + } sub move { my ($hd, $part, $hd2, $sector2) = @_; + die 'TODO'; # doesn't work for the moment my $part1 = { %$part }; my $part2 = { %$part }; $part2->{start} = $sector2; @@ -499,12 +596,13 @@ sub move { } } -sub change_type($$$) { - my ($hd, $part, $type) = @_; +sub change_type { + my ($type, $hd, $part) = @_; $type != $part->{type} or return; + check_type($type, $hd, $part); $hd->{isDirty} = 1; $part->{mntpoint} = '' if isSwap($part) && $part->{mntpoint} eq "swap"; - $part->{mntpoint} = '' if isLVM({ type => $type }) || isRAID({ type => $type }); + $part->{mntpoint} = '' if isRawLVM({ type => $type }) || isRawRAID({ type => $type }); $part->{type} = $type; $part->{notFormatted} = 1; $part->{isFormatted} = 0; diff --git a/perl-install/install2.pm b/perl-install/install2.pm index 392ad4c3b..3ceedd2b8 100644 --- a/perl-install/install2.pm +++ b/perl-install/install2.pm @@ -180,7 +180,7 @@ sub formatPartitions { any::rotate_logs($o->{prefix}); require raid; - raid::prepare_prefixed($o->{raid}, $o->{prefix}); + raid::prepare_prefixed($o->{all_hds}{raids}, $o->{prefix}); my $d = "/initrd/loopfs/lnx4win"; if (-d $d) { @@ -609,6 +609,7 @@ sub main { common::sync(); common::sync(); log::l("installation complete, leaving"); + log::l("files still open by install2: ", readlink($_)) foreach glob_("/proc/$$/fd/*"); print "\n" x 80; } diff --git a/perl-install/install_any.pm b/perl-install/install_any.pm index 74d629553..41ec2cf19 100644 --- a/perl-install/install_any.pm +++ b/perl-install/install_any.pm @@ -330,8 +330,8 @@ sub setPackages { push @{$o->{default_packages}}, "kernel22-secure" if $o->{security} > 3; push @{$o->{default_packages}}, "kernel-smp" if detect_devices::hasSMP(); push @{$o->{default_packages}}, "kernel-pcmcia-cs" if $o->{pcmcia}; - push @{$o->{default_packages}}, "raidtools" if $o->{raid} && !is_empty_array_ref($o->{raid}{raid}); - push @{$o->{default_packages}}, "lvm" if -e '/etc/lvmtab'; + push @{$o->{default_packages}}, "raidtools" if !is_empty_array_ref($o->{all_hds}{raids}); + push @{$o->{default_packages}}, "lvm" if !is_empty_array_ref($o->{all_hds}{lvms}); push @{$o->{default_packages}}, "usbd" if modules::get_alias("usb-interface"); push @{$o->{default_packages}}, "reiserfsprogs" if grep { isThisFs("reiserfs", $_) } @{$o->{fstab}}; push @{$o->{default_packages}}, "xfsprogs" if grep { isThisFs("xfs", $_) } @{$o->{fstab}}; @@ -476,9 +476,9 @@ sub unlockCdrom(;$) { } sub ejectCdrom(;$) { my ($cdrom) = @_; + getFile("XXX"); #- close still opened filehandle $cdrom or cat_("/proc/mounts") =~ m,(/(?:dev|tmp)/\S+)\s+(?:/mnt/cdrom|/tmp/image), and $cdrom = $1; my $f = eval { $cdrom && detect_devices::tryOpen($cdrom) } or return; - getFile("XXX"); #- close still opened filehandle eval { fs::umount("/tmp/image") }; ioctl $f, c::CDROMEJECT(), 1; } @@ -495,7 +495,7 @@ sub setupFB { $e->{vga} = $vga; } } - bootloader::install($o->{prefix}, $o->{bootloader}, $o->{fstab}, $o->{hds}); + bootloader::install($o->{prefix}, $o->{bootloader}, $o->{fstab}, $o->{all_hds}{hds}); 1; } @@ -897,13 +897,14 @@ sub getHds { # add2hash_($o->{partitioning}, { readonly => 1 }) if partition_table_raw::typeOfMBR($drives[0]{device}) eq 'system_commander'; getHds: - my ($hds, $lvms, $raids) = catch_cdie { fsedit::hds(\@drives, $flags) } + my $all_hds = catch_cdie { fsedit::hds(\@drives, $flags) } sub { $ok = 0; my $err = $@; $err =~ s/ at (.*?)$//; log::l("error reading partition table: $err"); !$flags->{readonly} && $f_err and $f_err->($err); }; + my $hds = $all_hds->{hds}; if (is_empty_array_ref($hds) && $try_scsi) { $try_scsi = 0; @@ -913,15 +914,13 @@ sub getHds { $::testing or partition_table_raw::test_for_bad_drives($_) foreach @$hds; $ok = fsedit::verifyHds($hds, $flags->{readonly}, $ok) - unless $flags->{clearall} || $flags->{clear}; + if !($flags->{clearall} || $flags->{clear}); #- try to figure out if the same number of hds is available, use them if ok. - $ok && $hds && @$hds > 0 && @{$o->{hds} || []} == @$hds and return $ok; + $ok && $hds && @$hds > 0 && @{$o->{all_hds}{hds} || []} == @$hds and return $ok; - $o->{hds} = $hds; - $o->{lvms} = $lvms; - $o->{raid}->{raid} = $raids; - $o->{fstab} = [ fsedit::get_fstab(@$hds, @$lvms) ]; + $o->{all_hds} = $all_hds; + $o->{fstab} = [ fsedit::get_all_fstab($all_hds) ]; fs::check_mounted($o->{fstab}); fs::merge_fstabs($o->{fstab}, $o->{manualFstab}); diff --git a/perl-install/install_interactive.pm b/perl-install/install_interactive.pm index 24064d9ea..214b8546f 100644 --- a/perl-install/install_interactive.pm +++ b/perl-install/install_interactive.pm @@ -25,16 +25,16 @@ You can find some information about them at: %s", join(", ", @l))) if @l; } sub partition_with_diskdrake { - my ($o, $hds, $nowizard) = @_; + my ($o, $all_hds, $nowizard) = @_; my $ok; $o->set_help('partition_with_diskdrake'); do { $ok = 1; require diskdrake; - diskdrake::main($hds, $o->{lvms}, $o->{raid}, interactive_gtk->new, $nowizard); + diskdrake::main(interactive_gtk->new, $all_hds, $nowizard); delete $o->{wizard} and return partitionWizard($o, 'nodiskdrake'); - my @fstab = fsedit::get_fstab(@$hds, @{$o->{lvms}}, $o->{raid}); + my @fstab = fsedit::get_all_fstab($all_hds); unless (fsedit::get_root_(\@fstab)) { $ok = 0; @@ -46,7 +46,7 @@ Then choose action ``Mount point'' and set it to `/'"), 1) or return; $o->ask_warn('', _("You must have a swap partition")), $ok=0 if !$::expert; $ok &&= $::expert || $o->ask_okcancel('', _("You don't have a swap partition\n\nContinue anyway?")); } - if (arch() =~ /ia64/ && !fsedit::has_mntpoint("/boot/efi", $hds)) { + if (arch() =~ /ia64/ && !fsedit::has_mntpoint("/boot/efi", $all_hds)) { $o->ask_warn('', _("You must have a FAT partition mounted in /boot/efi")); $ok = ''; } @@ -55,7 +55,8 @@ Then choose action ``Mount point'' and set it to `/'"), 1) or return; } sub partitionWizardSolutions { - my ($o, $hds, $fstab, $readonly) = @_; + my ($o, $all_hds, $fstab, $readonly) = @_; + my $hds = $all_hds->{hds}; my @wizlog; my (@solutions, %solutions); @@ -69,7 +70,7 @@ sub partitionWizardSolutions { my @good_hds = grep { partition_table::can_raw_add($_) } @$hds; if (fsedit::free_space(@good_hds) > $min_linux and !$readonly) { - $solutions{free_space} = [ 20, _("Use free space"), sub { fsedit::auto_allocate($hds); 1 } ] + $solutions{free_space} = [ 20, _("Use free space"), sub { fsedit::auto_allocate($all_hds); 1 } ] } else { push @wizlog, _("Not enough free space to allocate new partitions") . ": " . (@good_hds ? @@ -91,7 +92,7 @@ sub partitionWizardSolutions { [ -10 - @fats, _("Use the Windows partition for loopback"), sub { my ($s_root, $s_swap); - my $part = $o->ask_from_listf('', _("Which partition do you want to use for Linux4Win?"), \&partition_table_raw::description, \@ok_forloopback) or return; + my $part = $o->ask_from_listf('', _("Which partition do you want to use for Linux4Win?"), \&partition_table::description, \@ok_forloopback) or return; $max_swap = $min_swap + 1 if $part->{free} - $max_swap < $min_linux; $o->ask_from_entries_refH('', _("Choose the sizes"), [ { label => _("Root partition size in MB: "), val => \$s_root, min => $min_linux >> 11, max => min($part->{free} - $max_swap, $max_linux) >> 11, type => 'range' }, @@ -106,7 +107,7 @@ sub partitionWizardSolutions { [ 6 - @fats, _("Use the free space on the Windows partition"), sub { $o->set_help('resizeFATChoose'); - my $part = $o->ask_from_listf('', _("Which partition do you want to resize?"), \&partition_table_raw::description, \@ok_forloopback) or return; + my $part = $o->ask_from_listf('', _("Which partition do you want to resize?"), \&partition_table::description, \@ok_forloopback) or return; $o->set_help('resizeFATWait'); my $w = $o->wait_message(_("Resizing"), _("Computing Windows filesystem bounds")); require resize_fat::main; @@ -125,7 +126,7 @@ When sure, press Ok.")) or return; my $size = $part->{size}; $o->ask_from_entries_refH('', _("Which size do you want to keep for windows on"), [ - { label => _("partition %s", partition_table_raw::description($part)), val => \$size, min => $min_win >> 11, max => ($part->{size} - $min_linux - $min_swap) >> 11, type => 'range' }, + { label => _("partition %s", partition_table::description($part)), val => \$size, min => $min_win >> 11, max => ($part->{size} - $min_linux - $min_swap) >> 11, type => 'range' }, ]) or return; $size <<= 11; @@ -136,13 +137,13 @@ When sure, press Ok.")) or return; $part->{size} = $size; $part->{isFormatted} = 1; - my ($hd) = grep { $_->{device} eq $part->{rootDevice} } @$hds; + my ($hd) = fsedit::part2hd($part, $all_hds); $hd->{isDirty} = $hd->{needKernelReread} = 1; $hd->adjustEnd($part); partition_table::adjust_local_extended($hd, $part); partition_table::adjust_main_extended($hd); - fsedit::auto_allocate($hds); + fsedit::auto_allocate($all_hds); 1; } ] if !$readonly; } else { @@ -156,17 +157,17 @@ When sure, press Ok.")) or return; sub { $o->set_help('takeOverHdChoose'); my $hd = $o->ask_from_listf('', _("You have more than one hard drive, which one do you install linux on?"), - \&partition_table_raw::description, $hds) or return; + \&partition_table::description, $hds) or return; $o->set_help('takeOverHdConfirm'); - $o->ask_okcancel('', _("ALL existing partitions and their data will be lost on drive %s", partition_table_raw::description($hd))) or return; + $o->ask_okcancel('', _("ALL existing partitions and their data will be lost on drive %s", partition_table::description($hd))) or return; partition_table_raw::zero_MBR($hd); - fsedit::auto_allocate($hds); + fsedit::auto_allocate($all_hds); 1; } ]; } if (!$readonly && $o->isa('interactive_gtk')) { #- diskdrake only available in gtk for now - $solutions{diskdrake} = [ 0, _("Custom disk partitioning"), sub { partition_with_diskdrake($o, $hds, 'nowizard') } ]; + $solutions{diskdrake} = [ 0, _("Custom disk partitioning"), sub { partition_with_diskdrake($o, $all_hds, 'nowizard') } ]; } $solutions{fdisk} = @@ -174,7 +175,7 @@ When sure, press Ok.")) or return; $o->enter_console; foreach (@$hds) { print "\n" x 10, _("You can now partition %s. -When you are done, don't forget to save using `w'", partition_table_raw::description($_)); +When you are done, don't forget to save using `w'", partition_table::description($_)); print "\n\n"; my $pid = 0; if (arch() =~ /ppc/) { @@ -197,7 +198,7 @@ sub partitionWizard { $o->set_help('doPartitionDisks'); - my %solutions = partitionWizardSolutions($o, $o->{hds}, $o->{fstab}, $o->{partitioning}{readonly}); + my %solutions = partitionWizardSolutions($o, $o->{all_hds}, $o->{fstab}, $o->{partitioning}{readonly}); if ($o->{lnx4win}) { if ($solutions{loopback}) { %solutions = (loopback => $solutions{loopback}); diff --git a/perl-install/install_steps.pm b/perl-install/install_steps.pm index 0fff20890..3975d676b 100644 --- a/perl-install/install_steps.pm +++ b/perl-install/install_steps.pm @@ -137,32 +137,31 @@ sub doPartitionDisksBefore { eval { fs::umount_all($o->{fstab}, $o->{prefix}) }; eval { sleep 1; fs::umount_all($o->{fstab}, $o->{prefix}) } if $@; #- HACK } if $o->{fstab} && !$::testing && !$::live; - - $o->{raid} ||= {}; } #------------------------------------------------------------------------------ sub doPartitionDisksAfter { my ($o) = @_; - unless ($::testing) { - partition_table::write($_) foreach @{$o->{hds}}; - $_->{rebootNeeded} and $o->rebootNeeded foreach @{$o->{hds}}; + if (!$::testing) { + my $hds = $o->{all_hds}{hds}; + partition_table::write($_) foreach @$hds; + $_->{rebootNeeded} and $o->rebootNeeded foreach @$hds; } - $o->{fstab} = [ fsedit::get_fstab(@{$o->{hds}}, @{$o->{lvms}}, $o->{raid}) ]; + $o->{fstab} = [ fsedit::get_all_fstab($o->{all_hds}) ]; fsedit::get_root_($o->{fstab}) or die "Oops, no root partition"; if (arch() =~ /ppc/ && detect_devices::get_mac_generation =~ /NewWorld/) { die "Need bootstrap partition to boot system!" if !(defined $partition_table_mac::bootstrap_part); } - if (arch() =~ /ia64/ && !fsedit::has_mntpoint("/boot/efi", $o->{hds})) { + if (arch() =~ /ia64/ && !fsedit::has_mntpoint("/boot/efi", $o->{all_hds})) { die _("You must have a FAT partition mounted in /boot/efi"); } if ($o->{partitioning}{use_existing_root}) { #- ensure those partitions are mounted so that they are not proposed in choosePartitionsToFormat - fs::mount_part($_, $o->{prefix}) foreach grep { $_->{mntpoint} && !$_->{notFormatted} } @{$o->{fstab}}; + fs::mount_part($_, $o->{prefix}) foreach grep { $_->{mntpoint} && maybeFormatted($_) } @{$o->{fstab}}; } if (my $s = delete $o->{stage1_hd}) { @@ -192,7 +191,7 @@ sub doPartitionDisks { install_any::use_root_part($o->{fstab}, $p, $o->{prefix}); } if ($o->{partitioning}{auto_allocate}) { - fsedit::auto_allocate($o->{hds}, $o->{partitions}, $o->{raid}{raid}); + fsedit::auto_allocate($o->{all_hds}, $o->{partitions}); } } @@ -233,9 +232,7 @@ sub choosePartitionsToFormat($$) { add2hash_($_, { toFormat => $_->{notFormatted} }); if (!$_->{toFormat}) { - my $t = isLoopback($_) ? - eval { fsedit::typeOfPart($o->{prefix} . loopback::file($_)) } : - fsedit::typeOfPart($_->{device}); + my $t = fsedit::typeOfPart($_->{device}); $_->{toFormatUnsure} = member($_->{mntpoint}, '/', '/usr') || #- if detected dos/win, it's not precise enough to just compare the types (too many of them) (!$t || isOtherAvailableFS({ type => $t }) ? !isOtherAvailableFS($_) : $t != $_->{type}); @@ -245,7 +242,7 @@ sub choosePartitionsToFormat($$) { sub formatMountPartitions { my ($o) = @_; - fs::formatMount_all($o->{raid}, $o->{fstab}, $o->{prefix}); + fs::formatMount_all($o->{all_hds}{raids}, $o->{fstab}, $o->{prefix}); } #------------------------------------------------------------------------------ @@ -494,7 +491,7 @@ GridHeight=70 } if ($o->{blank} || $o->{updatemodules}) { - my @l = detect_devices::floppies(); + my @l = detect_devices::floppies_dev(); foreach (qw(blank updatemodules)) { $o->{$_} eq "1" and $o->{$_} = $l[0] || die _("No floppy drive available"); @@ -668,6 +665,7 @@ sub addUser { any::write_passwd_user($p, $_, $o->{authentication}{md5}) foreach @$users; + local *F; open F, ">> $p/etc/group" or die "can't append to group file: $!"; print F "$_->{name}:x:$_->{gid}:\n" foreach grep { ! getgrgid($_->{gid}) } @$users; @@ -700,7 +698,7 @@ sub createBootdisk($) { my ($o) = @_; my $dev = $o->{mkbootdisk} or return; - my @l = detect_devices::floppies(); + my @l = detect_devices::floppies_dev(); $dev = shift @l || die _("No floppy drive available") if $dev eq "1"; #- special case meaning autochoose @@ -760,7 +758,7 @@ sub setupBootloaderBefore { my $p = pkgs::packageByName($o->{packages}, 'Aurora'); $p && pkgs::packageFlagInstalled($p); }; - bootloader::suggest($o->{prefix}, $o->{bootloader}, $o->{hds}, $o->{fstab}, install_any::kernelVersion($o), + bootloader::suggest($o->{prefix}, $o->{bootloader}, $o->{all_hds}{hds}, $o->{fstab}, install_any::kernelVersion($o), $has_aurora && $vga); bootloader::suggest_floppy($o->{bootloader}) if $o->{security} <= 3 && arch() !~ /ppc/; @@ -797,7 +795,7 @@ sub setupBootloader($) { # map { /$o->{prefix}(.*)/ } eval { glob_("$o->{prefix}/boot/vmlinux*") }; } else { require bootloader; - bootloader::install($o->{prefix}, $o->{bootloader}, $o->{fstab}, $o->{hds}); + bootloader::install($o->{prefix}, $o->{bootloader}, $o->{fstab}, $o->{all_hds}{hds}); } } diff --git a/perl-install/install_steps_auto_install.pm b/perl-install/install_steps_auto_install.pm index 50757224b..817d85619 100644 --- a/perl-install/install_steps_auto_install.pm +++ b/perl-install/install_steps_auto_install.pm @@ -44,7 +44,7 @@ sub exitInstall { return if $o->{autoExitInstall}; if ($o->{interactive}) { - (bless $o, "install_steps_$o->{interactive}")->exitInstall($alldone); + $o->SUPER::exitInstall($alldone); } else { install_steps::exitInstall($o); print "\a"; diff --git a/perl-install/install_steps_interactive.pm b/perl-install/install_steps_interactive.pm index 7f3f2daca..263a5c3ec 100644 --- a/perl-install/install_steps_interactive.pm +++ b/perl-install/install_steps_interactive.pm @@ -305,8 +305,8 @@ sub ask_mntpoint_s { } else { $o->ask_from_entries_refH('', _("Choose the mount points"), - [ map { { label => partition_table_raw::description($_), - val => \$_->{mntpoint}, not_edit => 0, list => [ '', fsedit::suggestions_mntpoint([]) ] } + [ map { { label => partition_table::description($_), + val => \$_->{mntpoint}, not_edit => 0, list => [ '', fsedit::suggestions_mntpoint(fsedit::empty_all_hds()) ] } } @fstab ]) or return; } $o->SUPER::ask_mntpoint_s($fstab); @@ -347,7 +347,7 @@ Continue at your own risk!")); log::l("creating bootstrap partition on drive /dev/$hd->{device}, block $partition_table_mac::freepart_start"); $partition_table_mac::bootstrap_part = $partition_table_mac::freepart_part; log::l("bootstrap now at $partition_table_mac::bootstrap_part"); - fsedit::add($hd, { start => $partition_table_mac::freepart_start, size => 1 << 11, type => 0x401, mntpoint => '' }, $o->{hds}, { force => 1, primaryOrExtended => 'Primary' }); + fsedit::add($hd, { start => $partition_table_mac::freepart_start, size => 1 << 11, type => 0x401, mntpoint => '' }, $o->{all_hds}, { force => 1, primaryOrExtended => 'Primary' }); $new_bootstrap = 1; } else { $o->ask_warn('',_("No free space for 1MB bootstrap! Install will continue, but to boot your system, you'll need to create the bootstrap partition in DiskDrake")); @@ -362,11 +362,11 @@ Continue at your own risk!")); my @l = install_any::find_root_parts($o->{fstab}, $o->{prefix}) or die _("No root partition found to perform an upgrade"); $p = $o->ask_from_listf(_("Root Partition"), _("What is the root partition (/) of your system?"), - \&partition_table_raw::description, \@l) or die "setstep exitInstall\n"; + \&partition_table::description, \@l) or die "setstep exitInstall\n"; } install_any::use_root_part($o->{fstab}, $p, $o->{prefix}); } elsif ($::expert && $o->isa('interactive_gtk')) { - install_interactive::partition_with_diskdrake($o, $o->{hds}); + install_interactive::partition_with_diskdrake($o, $o->{all_hds}); } else { install_interactive::partitionWizard($o); } @@ -394,8 +394,9 @@ sub choosePartitionsToFormat { return if @l == 0 || !$::expert && 0 == grep { ! $_->{toFormat} } @l; my $name2label = sub { - sprintf("%s %s", isSwap($_) ? type2name($_->{type}) : $_->{mntpoint}, - isLoopback($_) ? $::expert && loopback::file($_) : partition_table_raw::description($_)); + sprintf("%s %s", + isSwap($_) ? type2name($_->{type}) : $_->{mntpoint}, + partition_table::description($_)); }; #- keep it temporary until the guy has accepted @@ -424,11 +425,11 @@ sub choosePartitionsToFormat { sub formatMountPartitions { my ($o, $fstab) = @_; my $w; - fs::formatMount_all($o->{raid}, $o->{fstab}, $o->{prefix}, sub { + fs::formatMount_all($o->{all_hds}{raids}, $o->{fstab}, $o->{prefix}, sub { my ($part) = @_; $w ||= $o->wait_message('', _("Formatting partitions")); $w->set(isLoopback($part) ? - _("Creating and formatting file %s", loopback::file($part)) : + _("Creating and formatting file %s", $part->{device}) : _("Formatting partition %s", $part->{device})); }); die _("Not enough swap to fulfill installation, please add some") if availableMemory < 40 * 1024; @@ -1012,11 +1013,11 @@ failures. If you want to create a bootdisk for your system, insert a floppy in the first drive and press \"Ok\"."), $o->{mkbootdisk}) or return $o->{mkbootdisk} = ''; - my @l = detect_devices::floppies(); + my @l = detect_devices::floppies_dev(); $o->{mkbootdisk} = $l[0] if !$o->{mkbootdisk} || $o->{mkbootdisk} eq "1"; $o->{mkbootdisk} or return; } else { - my @l = detect_devices::floppies(); + my @l = detect_devices::floppies_dev(); my %l = ( 'fd0' => _("First floppy drive"), 'fd1' => _("Second floppy drive"), @@ -1075,7 +1076,7 @@ _("Error installing aboot, try to force installation even if that destroys the first partition?")); }; } else { - any::setupBootloader($o, $o->{bootloader}, $o->{hds}, $o->{fstab}, $o->{security}, $o->{prefix}, $more) or return; + any::setupBootloader($o, $o->{bootloader}, $o->{all_hds}{hds}, $o->{fstab}, $o->{security}, $o->{prefix}, $more) or return; eval { $o->SUPER::setupBootloader }; if ($@) { diff --git a/perl-install/loopback.pm b/perl-install/loopback.pm index 04c320ca3..89b0072b9 100644 --- a/perl-install/loopback.pm +++ b/perl-install/loopback.pm @@ -11,25 +11,37 @@ use common; use partition_table qw(:types); use commands; use fs; +use fsedit; use log; -sub file { - my ($part) = @_; - ($part->{device}{mntpoint} || die "loopback::file but loopback file has no associated mntpoint") . - $part->{loopback_file}; -} - -sub loopbacks { - map { map { @{$_->{loopback} || []} } partition_table::get_normal_parts($_) } @_; -} - sub carryRootLoopback { my ($part) = @_; $_->{mntpoint} eq '/' and return 1 foreach @{$part->{loopback} || []}; 0; } +sub check_circular_mounts { + my ($hd, $part, $all_hds) = @_; + + my $fstab = [ fsedit::get_all_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 _("Circular mounts %s\n", join(", ", @seen)); + if (my $part = fs::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) = @_; @@ -51,16 +63,15 @@ sub carryRootCreateSymlink { sub format_part { my ($part, $prefix) = @_; - fs::mount_part($part->{device}, $prefix); - my $f = create($part, $prefix); - local $part->{device} = $f; + fs::mount_part($part->{loopback_device}, $prefix); + create($part, $prefix); fs::real_format_part($part); } sub create { my ($part, $prefix) = @_; - my $f = "$prefix$part->{device}{mntpoint}$part->{loopback_file}"; - return $f if -e $f; + my $f = $part->{device} = "$prefix$part->{loopback_device}{mntpoint}$part->{loopback_file}"; + return if -e $f; eval { commands::mkdir_("-p", dirname($f)) }; @@ -70,7 +81,6 @@ sub create { sysopen F, $f, 2 | c::O_CREAT() or die "failed to create loopback file"; sysseek F, ($part->{size} << 9) - 1, 0 or die "failed to create loopback file"; syswrite F, "\0" or die "failed to create loopback file"; - $f; } sub getFree { diff --git a/perl-install/partition_table.pm b/perl-install/partition_table.pm index 687495fc5..6793b33a6 100644 --- a/perl-install/partition_table.pm +++ b/perl-install/partition_table.pm @@ -6,7 +6,7 @@ package partition_table; # $Id$ @ISA = qw(Exporter); %EXPORT_TAGS = ( - types => [ qw(type2name type2fs name2type fs2type isExtended isExt2 isThisFs isTrueFS isSwap isDos isWin isFat isSunOS isOtherAvailableFS isPrimary isNfs isSupermount isLVM isRAID isMDRAID isLVMBased isNT isMountableRW isNonMountable isApplePartMap isLoopback isApple isAppleBootstrap) ], + types => [ qw(type2name type2fs name2type fs2type isExtended isExt2 isThisFs isTrueFS isSwap isDos isWin isFat isSunOS isOtherAvailableFS isPrimary isNfs isSupermount isRawLVM isRawRAID isRAID isLVM isNT isMountableRW isNonMountable isPartOfLVM isPartOfRAID isPartOfLoopback isApplePartMap isLoopback isMounted isBusy isSpecial maybeFormatted isApple isAppleBootstrap) ], ); @EXPORT_OK = map { @$_ } values %EXPORT_TAGS; @@ -28,16 +28,16 @@ if (arch() =~ /ppc/) { my %types = ( 0x0 => 'Empty', -arch() =~ /^ppc/ ? ( +if_(arch() =~ /^ppc/, 0x401 => 'Apple Partition', 0x401 => 'Apple Bootstrap', 0x402 => 'Apple HFS Partition', -) : arch() =~ /^i.86/ ? ( +), if_(arch() =~ /^i.86/, 0x183 => 'Journalised FS: ReiserFS', # 0x283 => 'Journalised FS: XFS', 0x383 => 'Journalised FS: JFS', 0x483 => 'Journalised FS: ext3', -) : arch() =~ /^sparc/ ? ( +), if_(arch() =~ /^sparc/, 0x1 => 'SunOS boot', 0x2 => 'SunOS root', 0x3 => 'SunOS swap', @@ -46,7 +46,7 @@ arch() =~ /^ppc/ ? ( 0x6 => 'SunOS stand', 0x7 => 'SunOS var', 0x8 => 'SunOS home', -) : ( +), if_(arch() =~ /^i.86/, 0x1 => 'DOS 12-bit FAT', 0x2 => 'XENIX root', 0x3 => 'XENIX /usr', @@ -219,48 +219,72 @@ sub name2type($) { sub isWholedisk($) { arch() =~ /^sparc/ && $_[0]{type} == 5 } sub isExtended($) { arch() !~ /^sparc/ && ($_[0]{type} == 5 || $_[0]{type} == 0xf || $_[0]{type} == 0x85) } -sub isLVM($) { $_[0]{type} == 0x8e } -sub isRAID($) { $_[0]{type} == 0xfd } -sub isMDRAID { $_[0]{device} =~ /^md/ } -sub isLVMBased { $_[0]{LVMname} } +sub isRawLVM($) { $_[0]{type} == 0x8e } +sub isRawRAID($) { $_[0]{type} == 0xfd } sub isSwap($) { $type2fs{$_[0]{type}} eq 'swap' } sub isExt2($) { $type2fs{$_[0]{type}} eq 'ext2' } sub isDos($) { arch() !~ /^sparc/ && $ {{ 1=>1, 4=>1, 6=>1 }}{$_[0]{type}} } sub isWin($) { $ {{ 0xb=>1, 0xc=>1, 0xe=>1, 0x1b=>1, 0x1c=>1, 0x1e=>1 }}{$_[0]{type}} } sub isFat($) { isDos($_[0]) || isWin($_[0]) } sub isSunOS($) { arch() =~ /sparc/ && $ {{ 0x1=>1, 0x2=>1, 0x4=>1, 0x6=>1, 0x7=>1, 0x8=>1 }}{$_[0]{type}} } -sub isSolaris($) { 0; } #- hack to search for getting the difference ? TODO -sub isOtherAvailableFS($) { isFat($_[0]) || isSunOS($_[0]) || isThisFs('hfs', $_[0]) } #- other OS that linux can access its filesystem sub isNfs($) { $_[0]{type} eq 'nfs' } #- small hack sub isNT($) { arch() !~ /^sparc/ && $_[0]{type} == 0x7 } sub isSupermount($) { $_[0]{type} eq 'supermount' } sub isApple($) { $type2fs{$_[0]{type}} eq 'apple' && defined $_[0]{isDriver} } sub isAppleBootstrap($) { $type2fs{$_[0]{type}} eq 'apple' && defined $_[0]{isBoot} } sub isHiddenMacPart { defined $_[0]{isMap} } -sub isLoopback { defined $_[0]{loopback_file} } + sub isThisFs { $type2fs{$_[1]{type}} eq $_[0] } sub isTrueFS { member($type2fs{$_[0]{type}}, qw(ext2 reiserfs xfs jfs ext3)) } + +sub isOtherAvailableFS($) { isFat($_[0]) || isSunOS($_[0]) || isThisFs('hfs', $_[0]) } #- other OS that linux can access its filesystem sub isMountableRW { isTrueFS($_[0]) || isOtherAvailableFS($_[0]) } -sub isNonMountable { isRAID($_[0]) || isLVM($_[0]) } +sub isNonMountable { isRawRAID($_[0]) || isRawLVM($_[0]) } + +sub isPartOfLVM { defined $_[0]{lvm} } +sub isPartOfRAID { defined $_[0]{raid} } +sub isPartOfLoopback { defined $_[0]{loopback} } +sub isRAID { $_[0]{device} =~ /^md/ } +sub isLVM { $_[0]{LVMname} } +sub isLoopback { defined $_[0]{loopback_file} } +sub isMounted { $_[0]{isMounted} } +sub isBusy { isMounted($_[0]) || isPartOfRAID($_[0]) || isPartOfLVM($_[0]) || isPartOfLoopback($_[0]) } +sub isSpecial { isRAID($_[0]) || isLVM($_[0]) || isLoopback($_[0]) } +sub maybeFormatted { $_[0]{isFormatted} || !$_[0]{notFormatted} } -sub isPrimary($$) { + +#- works for both hard drives and partitions ;p +sub description { + my ($hd) = @_; + my $win = $hd->{device_windobe}; + + sprintf "%s%s (%s%s%s%s)", + $hd->{device}, + $win && " [$win:]", + formatXiB($hd->{totalsectors} || $hd->{size}, 512), + $hd->{info} && ", $hd->{info}", + $hd->{mntpoint} && ", " . $hd->{mntpoint}, + $hd->{type} && ", " . type2name($hd->{type}); +} + +sub isPrimary { my ($part, $hd) = @_; foreach (@{$hd->{primary}{raw}}) { $part eq $_ and return 1; } 0; } -sub adjustStartAndEnd($$) { +sub adjustStartAndEnd { my ($hd, $part) = @_; $hd->adjustStart($part); $hd->adjustEnd($part); } -sub verifyNotOverlap($$) { +sub verifyNotOverlap { my ($a, $b) = @_; $a->{start} + $a->{size} <= $b->{start} || $b->{start} + $b->{size} <= $a->{start}; } -sub verifyInside($$) { +sub verifyInside { my ($a, $b) = @_; $b->{start} <= $a->{start} && $a->{start} + $a->{size} <= $b->{start} + $b->{size}; } @@ -285,17 +309,17 @@ sub verifyParts_ { } } } -sub verifyParts($) { +sub verifyParts { my ($hd) = @_; verifyParts_(get_normal_parts($hd)); } -sub verifyPrimary($) { +sub verifyPrimary { my ($pt) = @_; $_->{start} > 0 || arch() =~ /^sparc/ || die "partition must NOT start at sector 0" foreach @{$pt->{normal}}; verifyParts_(@{$pt->{normal}}, $pt->{extended}); } -sub assign_device_numbers($) { +sub assign_device_numbers { my ($hd) = @_; my $i = 1; @@ -332,7 +356,7 @@ sub assign_device_numbers($) { $_->{device_windobe} = chr($i++) foreach @others; } -sub remove_empty_extended($) { +sub remove_empty_extended { my ($hd) = @_; my $last = $hd->{primary}{extended} or return; @{$hd->{extended}} = grep { @@ -346,7 +370,7 @@ sub remove_empty_extended($) { adjust_main_extended($hd); } -sub adjust_main_extended($) { +sub adjust_main_extended { my ($hd) = @_; if (!is_empty_array_ref $hd->{extended}) { @@ -373,7 +397,7 @@ sub adjust_main_extended($) { verifyParts($hd); #- verify everything is all right } -sub adjust_local_extended($$) { +sub adjust_local_extended { my ($hd, $part) = @_; foreach (@{$hd->{extended} || []}) { @@ -383,28 +407,28 @@ sub adjust_local_extended($$) { } } -sub get_normal_parts($) { +sub get_normal_parts { my ($hd) = @_; - #- HACK !! - $hd->{raid} and return grep {$_} @{$hd->{raid}}; - $hd->{loopback} and return grep {$_} @{$hd->{loopback}}; - @{$hd->{primary}{normal} || []}, map { $_->{normal} } @{$hd->{extended} || []} } -sub get_holes($) { +sub get_normal_parts_and_holes { my ($hd) = @_; - my $start = arch() eq "alpha" ? 2048 : 1; - map { + ref($hd) or print("get_normal_parts_and_holes: bad hd" . backtrace(), "\n"); + + my @l = map { my $current = $start; $start = $_->{start} + $_->{size}; - { start => $current, size => $_->{start} - $current } - } sort { $a->{start} <=> $b->{start} } grep { !isWholedisk($_) } get_normal_parts($hd), { start => $hd->{totalsectors}, size => 0 }; -} + my $hole = { start => $current, size => $_->{start} - $current, type => 0, rootDevice => $hd->{device} }; + $hole, $_; + } sort { $a->{start} <=> $b->{start} } grep { !isWholedisk($_) } get_normal_parts($hd); + push @l, { start => $start, size => $hd->{totalsectors} - $start, type => 0, rootDevice => $hd->{device} }; + grep { $_->{size} >= $hd->cylinder_size } @l; +} sub read_one($$) { my ($hd, $sector) = @_; @@ -524,7 +548,7 @@ sub write($) { } } -sub active($$) { +sub active { my ($hd, $part) = @_; $_->{active} = 0 foreach @{$hd->{primary}{normal}}; @@ -534,7 +558,7 @@ sub active($$) { # remove a normal partition from hard drive hd -sub remove($$) { +sub remove { my ($hd, $part) = @_; my $i; @@ -567,7 +591,7 @@ sub remove($$) { } # create of partition at starting at `start', of size `size' and of type `type' (nice comment, uh?) -sub add_primary($$) { +sub add_primary { my ($hd, $part) = @_; { @@ -628,7 +652,7 @@ The only solution is to move your primary partitions to have the hole next to th adjust_main_extended($hd); } -sub add($$;$$) { +sub add { my ($hd, $part, $primaryOrExtended, $forceNoAdjust) = @_; get_normal_parts($hd) >= ($hd->{device} =~ /^rd/ ? 7 : $hd->{device} =~ /^(sd|ida|cciss)/ ? 15 : 63) and cdie "maximum number of partitions handled by linux reached"; @@ -657,7 +681,7 @@ sub add($$;$$) { } # search for the next partition -sub next($$) { +sub next { my ($hd, $part) = @_; first( @@ -666,7 +690,7 @@ sub next($$) { get_normal_parts($hd) ); } -sub next_start($$) { +sub next_start { my ($hd, $part) = @_; my $next = &next($hd, $part); $next ? $next->{start} : $hd->{totalsectors}; @@ -688,7 +712,7 @@ sub raw_add { die "raw_add: partition table already full"; } -sub load($$;$) { +sub load { my ($hd, $file, $force) = @_; local *F; @@ -716,7 +740,7 @@ sub load($$;$) { $hd->{isDirty} = $hd->{needKernelReread} = 1; } -sub save($$) { +sub save { my ($hd, $file) = @_; my @h = @{$hd}{@fields2save}; local *F; diff --git a/perl-install/partition_table_raw.pm b/perl-install/partition_table_raw.pm index dd6a4e4bd..733970a4e 100644 --- a/perl-install/partition_table_raw.pm +++ b/perl-install/partition_table_raw.pm @@ -95,18 +95,6 @@ sub get_geometry($) { { geom => \%geom, totalsectors => $geom{heads} * $geom{sectors} * $geom{cylinders} }; } -#- works for both hard drives and partitions ;p -sub description { - my ($hd) = @_; - my $win = $hd->{device_windobe}; - - sprintf "%s%s (%s%s)", - $hd->{device}, - $win && " [$win:]", - formatXiB($hd->{totalsectors} || $hd->{size}, 512), - $hd->{info} && ", $hd->{info}"; -} - sub openit($$;$) { sysopen $_[1], $_[0]{file}, $_[2] || 0; } # cause kernel to re-read partition table diff --git a/perl-install/raid.pm b/perl-install/raid.pm index eedd121a6..9ae8db8ce 100644 --- a/perl-install/raid.pm +++ b/perl-install/raid.pm @@ -14,15 +14,15 @@ use commands; use modules; use fs; -sub nb($) { +sub nb { my ($nb) = @_; first((ref $nb ? $nb->{device} : $nb) =~ /(\d+)/); } sub new { - my ($raid, @parts) = @_; - my $nb = @$raid; - $raid->[$nb] = { 'chunk-size' => "64k", type => 0x83, disks => [ @parts ], device => "md$nb", notFormatted => 1 }; + my ($raids, @parts) = @_; + my $nb = @$raids; + $raids->[$nb] = { 'chunk-size' => "64k", type => 0x83, disks => [ @parts ], device => "md$nb", notFormatted => 1 }; foreach my $part (@parts) { $part->{raid} = $nb; delete $part->{mntpoint}; @@ -30,42 +30,47 @@ sub new { $nb; } -sub add($$$) { - my ($raid, $part, $nb) = @_; $nb = nb($nb); - $raid->[$nb]{isMounted} and die _("Can't add a partition to _formatted_ RAID md%d", $nb); +sub add { + my ($raids, $part, $nb) = @_; $nb = nb($nb); + $raids->[$nb]{isMounted} and die _("Can't add a partition to _formatted_ RAID md%d", $nb); $part->{raid} = $nb; delete $part->{mntpoint}; - push @{$raid->[$nb]{disks}}, $part; + push @{$raids->[$nb]{disks}}, $part; } -sub delete($$) { - my ($raid, $nb) = @_; +sub delete { + my ($raids, $nb) = @_; $nb = nb($nb); - delete $_->{raid} foreach @{$raid->[$nb]{disks}}; - undef $raid->[$nb]; + delete $_->{raid} foreach @{$raids->[$nb]{disks}}; + undef $raids->[$nb]; } -sub changeNb($$$) { - my ($raid, $oldnb, $newnb) = @_; +sub changeNb { + my ($raids, $oldnb, $newnb) = @_; if ($oldnb != $newnb) { - ($raid->[$newnb], $raid->[$oldnb]) = ($raid->[$oldnb], undef); - $raid->[$newnb]{device} = "md$newnb"; - $_->{raid} = $newnb foreach @{$raid->[$newnb]{disks}}; + ($raids->[$newnb], $raids->[$oldnb]) = ($raids->[$oldnb], undef); + $raids->[$newnb]{device} = "md$newnb"; + $_->{raid} = $newnb foreach @{$raids->[$newnb]{disks}}; } $newnb; } -sub removeDisk($$) { - my ($raid, $part) = @_; +sub removeDisk { + my ($raids, $part) = @_; my $nb = nb($part->{raid}); run_program::run("raidstop", devices::make($part->{device})); delete $part->{raid}; - @{$raid->[$nb]{disks}} = grep { $_ != $part } @{$raid->[$nb]{disks}}; - update($raid->[$nb]); + my $disks = $raids->[$nb]{disks}; + @$disks = grep { $_ != $part } @$disks; + if (@$disks) { + update($raids->[$nb]); + } else { + undef $raids->[$nb]; + } } -sub updateSize($) { +sub updateSize { my ($part) = @_; local $_ = $part->{level}; my @l = map { $_->{size} } @{$part->{disks}}; @@ -77,7 +82,7 @@ sub updateSize($) { }; } -sub module($) { +sub module { my ($part) = @_; my $mod = $part->{level}; @@ -86,7 +91,7 @@ sub module($) { $mod; } -sub updateIsFormatted($) { +sub updateIsFormatted { my ($part) = @_; $part->{isFormatted} = and_ map { $_->{isFormatted} } @{$part->{disks}}; $part->{notFormatted} = and_ map { $_->{notFormatted} } @{$part->{disks}}; @@ -98,13 +103,13 @@ sub update { } } -sub write($) { - my ($raid, $file) = @_; +sub write { + my ($raids, $file) = @_; local *F; local $\ = "\n"; open F, ">$file" or die _("Can't write file $file"); - foreach (grep {$_} @$raid) { + foreach (grep {$_} @$raids) { print F <<"EOF"; raiddev /dev/$_->{device} raid-level $_->{level} @@ -120,39 +125,39 @@ EOF } sub make { - my ($raid, $part) = @_; - isMDRAID($_) and make($raid, $_) foreach @{$part->{disks}}; + my ($raids, $part) = @_; + isRAID($_) and make($raids, $_) foreach @{$part->{disks}}; my $dev = devices::make($part->{device}); eval { modules::load(module($part)) }; - &write($raid, "/etc/raidtab"); + &write($raids, "/etc/raidtab"); run_program::run("raidstop", $dev); run_program::run("mkraid", "--really-force", $dev) or die $::isStandalone ? _("mkraid failed (maybe raidtools are missing?)") : _("mkraid failed"); } -sub format_part($$) { - my ($raid, $part) = @_; +sub format_part { + my ($raids, $part) = @_; $part->{isFormatted} and return; - make($raid->{raid}, $part); + make($raids, $part); fs::real_format_part($part); $_->{isFormatted} = 1 foreach @{$part->{disks}}; } -sub verify($) { - my ($raid) = @_; - $raid && $raid->{raid} or return; - foreach (grep {$_} @{$raid->{raid}}) { +sub verify { + my ($raids) = @_; + $raids or return; + foreach (grep {$_} @$raids) { @{$_->{disks}} >= ($_->{level} =~ /4|5/ ? 3 : 2) or die _("Not enough partitions for RAID level %d\n", $_->{level}); } } -sub prepare_prefixed($$) { - my ($raid, $prefix) = @_; - $raid && $raid->{raid} or return; +sub prepare_prefixed { + my ($raids, $prefix) = @_; + $raids or return; eval { commands::cp("-f", "/etc/raidtab", "$prefix/etc/raidtab") }; - foreach (@{$raid->{raid}}) { + foreach (grep {$_} @$raids) { devices::make("$prefix/dev/$_->{device}") foreach @{$_->{disks}}; } } diff --git a/perl-install/standalone/diskdrake b/perl-install/standalone/diskdrake index 01c0ed294..6cee947b7 100755 --- a/perl-install/standalone/diskdrake +++ b/perl-install/standalone/diskdrake @@ -26,7 +26,7 @@ use lib qw(/usr/lib/libDrakX); use common; use diskdrake; use standalone; -use interactive_gtk; +use interactive; use detect_devices; use fsedit; use fs; @@ -51,14 +51,8 @@ if ($>) { } -#if ($ARGV[0] eq '-l') { -# $@ and print "Error\n"; -# $::expert = 1; -# print diskdrake::get_info($_, $hds->[0]) foreach fsedit::get_fstab($hds->[0]); -# exit !$@; -#} -my $in = interactive_gtk->new; -my ($hds, $lvms) = +my $in = 'interactive'->vnew('su'); +my ($all_hds) = catch_cdie { fsedit::hds([ detect_devices::hds() ], {}) } sub { my ($err) = $@ =~ /(.*) at /; @@ -69,10 +63,12 @@ I'll try to go on blanking bad partitions"), $err]); }; $SIG{__DIE__} = sub { my $m = chomp_($_[0]); log::l("ERROR: $m") }; -my $fstab = [ fsedit::get_fstab(@$hds, @$lvms) ]; - -fs::get_mntpoints_from_fstab($fstab); +my $fstab = [ fsedit::get_all_fstab($all_hds) ]; + +$all_hds->{raw_hds} = [ fs::raw_hds() ]; + +fs::get_all_mntpoints_from_fstab($all_hds); fs::check_mounted($fstab); -diskdrake::main($hds, $lvms, {}, $in); +diskdrake_interactive::main($in, $all_hds); $in->exit(0); -- cgit v1.2.1