diff options
Diffstat (limited to 'perl-install/fs')
| -rw-r--r-- | perl-install/fs/any.pm | 85 | ||||
| -rw-r--r-- | perl-install/fs/dmcrypt.pm | 89 | ||||
| -rw-r--r-- | perl-install/fs/dmraid.pm | 91 | ||||
| -rw-r--r-- | perl-install/fs/format.pm | 215 | ||||
| -rw-r--r-- | perl-install/fs/get.pm | 40 | ||||
| -rw-r--r-- | perl-install/fs/loopback.pm | 4 | ||||
| -rw-r--r-- | perl-install/fs/mount.pm | 16 | ||||
| -rw-r--r-- | perl-install/fs/mount_options.pm | 33 | ||||
| -rw-r--r-- | perl-install/fs/mount_point.pm | 31 | ||||
| -rw-r--r-- | perl-install/fs/partitioning.pm | 10 | ||||
| -rw-r--r-- | perl-install/fs/partitioning_wizard.pm | 276 | ||||
| -rw-r--r-- | perl-install/fs/proc_partitions.pm | 18 | ||||
| -rw-r--r-- | perl-install/fs/remote.pm | 2 | ||||
| -rw-r--r-- | perl-install/fs/remote/davfs.pm | 16 | ||||
| -rw-r--r-- | perl-install/fs/remote/nfs.pm | 45 | ||||
| -rw-r--r-- | perl-install/fs/remote/smb.pm | 2 | ||||
| -rw-r--r-- | perl-install/fs/type.pm | 166 | ||||
| -rw-r--r-- | perl-install/fs/wild_device.pm | 14 | 
18 files changed, 795 insertions, 358 deletions
| diff --git a/perl-install/fs/any.pm b/perl-install/fs/any.pm index 50d03b656..ce4de2ca3 100644 --- a/perl-install/fs/any.pm +++ b/perl-install/fs/any.pm @@ -1,11 +1,15 @@ -package fs::any; # $Id$ +package fs::any;  use diagnostics;  use strict; +use c;  use common;  use fsedit; +use fs::get;  use fs::mount_point; +use fs::type; +use run_program;  sub get_hds {      my ($all_hds, $fstab, $manual_fstab, $partitioning_flags, $skip_mtab, $o_in) = @_; @@ -58,21 +62,26 @@ sub set_cdrom_symlink {  	my $alias = basename($_->{mntpoint}) or next;  	log::l("using alias $alias for $_->{device}");  	$_->{device_alias} = $alias; -	symlink($_->{device}, "/dev/$alias") if $::prefix; # do create the symlink to have it during install (otherwise fs::wild_device::from_part will give a non accessible device) -	symlink($_->{device}, "$::prefix/dev/$alias"); +	symlink($_->{device}, "/dev/$alias");      }  }  sub check_hds_boot_and_root { -    my ($all_hds, $fstab) = @_; +    my ($all_hds, $fstab, $isUpgrade, $o_match_all_hardware) = @_;      fs::get::root_($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/ && !fs::get::has_mntpoint("/boot/efi", $all_hds)) { -	die N("You must have a FAT partition mounted in /boot/efi"); +    return if $o_match_all_hardware || $::local_install; + +    if (is_uefi()) { +	if (!fs::get::has_mntpoint("/boot/EFI", $all_hds)) { +	    die N("You must have a ESP FAT32 partition mounted in /boot/EFI"); +	} +    } else { +	# if we are doing an upgrade, the user may still be using a legacy bootloader +	return if $isUpgrade; +	if (is_boot_bios_part_needed($all_hds)) { +	    die N("You must have a BIOS boot partition for non-UEFI GPT-partitioned disks. Please create one before continuing."); +	}      }  } @@ -81,28 +90,24 @@ sub create_minimal_files() {        qw(dev etc etc/profile.d etc/rpm etc/sysconfig etc/sysconfig/console   	etc/sysconfig/network-scripts etc/sysconfig/console/consolefonts   	etc/sysconfig/console/consoletrans -	home mnt tmp var var/tmp var/lib var/lib/rpm var/lib/urpmi); +	home mnt run tmp var var/tmp var/lib var/lib/rpm var/lib/urpmi);      mkdir "$::prefix/$_", 0700 foreach qw(root root/tmp root/drakx); - -    devices::make("$::prefix/dev/null"); -    chmod 0666, "$::prefix/dev/null";  } -sub prepare_minimal_root { -    my ($all_hds) = @_; +sub prepare_minimal_root() { -    fs::any::create_minimal_files(); +    create_minimal_files(); +    # ensure we've all needed devices, for bootloader install and mkinitrd: +    run_program::run('mount', '--bind', '/dev', "$::prefix/dev"); +    run_program::run('mount', '--bind', '/run', "$::prefix/run");      eval { fs::mount::mount('none', "$::prefix/proc", 'proc') };      eval { fs::mount::mount('none', "$::prefix/sys", 'sysfs') }; -    eval { fs::mount::usbfs($::prefix) }; - -    # copy all needed devices, for bootloader install and mkinitrd -    cp_af("/dev", "$::prefix"); +    eval { fs::mount::sys_kernel_debug($::prefix) };  } -sub getAvailableSpace { -    my ($fstab, $o_skip_mounted) = @_; +sub getNeededMinSpace { +    my ($n) = @_;      #- make sure of this place to be available for installation, this could help a lot.      #- currently doing a very small install use 36Mb of postinstall-rpm, but installing @@ -110,9 +115,15 @@ sub getAvailableSpace {      #- 65mb may be a good choice to avoid almost all problem of insuficient space left...      my $minAvailableSize = 65 * sqr(1024); +    max(0.1 * $n, $minAvailableSize); +} + +sub getAvailableSpace { +    my ($fstab, $o_skip_mounted, $o_skip_min_space) = @_; +      my $n = !$::testing && !$o_skip_mounted && getAvailableSpace_mounted($::prefix) ||               getAvailableSpace_raw($fstab) * 512 / 1.07; -    $n - max(0.1 * $n, $minAvailableSize); +    $o_skip_min_space ? $n : $n - getNeededMinSpace($n);  }  sub getAvailableSpace_mounted { @@ -136,4 +147,30 @@ sub getAvailableSpace_raw {      die "missing root partition";  } +=head3 is_boot_bios_part_needed($all_hds) + +Returns whether a Boot BIOS Partition is needed + +Returns true if all of the following are true: +  - legacy boot (not UEFI) +  - all disks are (or will be) GPT +  - no disks have a BIOS boot partition + +=cut + +sub is_boot_bios_part_needed { +    my ($all_hds) = @_; +    # never needed for UEFI boot +    return if is_uefi(); +    # do we already have one? +    my @parts = map { partition_table::get_normal_parts($_) } fs::get::hds($all_hds); +    return if any { isBIOS_GRUB($_) } @parts; +    # do we have any non-GPT disks? +    foreach my $hd (@{$all_hds->{hds}}) { +	my $type = $hd->{pt_table_type} || partition_table::default_type($hd); +	return if $type ne 'gpt'; +    } +    1; +} +  1; diff --git a/perl-install/fs/dmcrypt.pm b/perl-install/fs/dmcrypt.pm index 0b9c58337..a78a495d1 100644 --- a/perl-install/fs/dmcrypt.pm +++ b/perl-install/fs/dmcrypt.pm @@ -1,4 +1,4 @@ -package fs::dmcrypt; # $Id: $ +package fs::dmcrypt;  use diagnostics;  use strict; @@ -11,12 +11,28 @@ use fs::type;  use fs::get;  use run_program; +=head1 SYNOPSYS + +Manage encrypted file systems using cryptsetup + +=head1 Functions + +=over + +=cut +  sub _crypttab() { "$::prefix/etc/crypttab" } +=item init() + +Load kernel modules and init device mapper. + +=cut +  sub init() {      whereis_binary('cryptsetup') or die "cryptsetup not installed"; -    eval { modules::load('dm-crypt', 'cbc', 'sha256_generic', if_(arch() =~ /i.86/, 'aes-i586'), if_( arch() =~ /x86_64/, 'aes-x86_64'), 'aes_generic') }; +    eval { modules::load('dm-crypt', list_modules::category2modules('various/crypto')) };      devices::init_device_mapper();      1;  } @@ -25,25 +41,38 @@ sub _ensure_initialized() {      $initialized++ or init();  } -sub read_crypttab { -    my ($all_hds) = @_; +sub read_crypttab_ { +    my ($all_hds, $crypttab) = @_; -    -e _crypttab() or return; +    -e $crypttab or return;      my @raw_parts = grep { fs::type::isRawLUKS($_) } fs::get::really_all_fstab($all_hds); -    foreach (cat_(_crypttab())) { +    foreach (cat_($crypttab)) { +	next if /^#/;  	my ($dm_name, $dev) = split;  	my $raw_part = fs::get::device2part($dev, \@raw_parts)  	  or log::l("crypttab: unknown device $dev for $dm_name"), next;  	$raw_part->{dm_name} = $dm_name; +	_get_existing_one_with_state($raw_part);      }  } -sub save_crypttab { +=item read_crypttab($all_hds) + +Read /etc/crypttab + +=cut + +sub read_crypttab {      my ($all_hds) = @_; +    read_crypttab_($all_hds, _crypttab()); +} + +sub save_crypttab_ { +    my ($all_hds, $crypttab) = @_;      my @raw_parts = grep { $_->{dm_name} } fs::get::really_all_fstab($all_hds) or return; @@ -57,7 +86,18 @@ sub save_crypttab {  	if (eof) {  	    $_ .= join('', map { "$_ $names{$_}\n" } sort keys %names);  	} -    } _crypttab(); +    } $crypttab; +} + +=item save_crypttab($all_hds) + +Save /etc/crypttab + +=cut + +sub save_crypttab { +    my ($all_hds) = @_; +    save_crypttab_($all_hds, _crypttab());  }  sub format_part { @@ -65,9 +105,9 @@ sub format_part {      my $tmp_key_file = "/tmp/.dmcrypt_key-$$";      common::with_private_tmp_file($tmp_key_file, $part->{dmcrypt_key}, sub { -	_run_or_die('luksFormat', '--batch-mode', devices::make($part->{device}), $_[0]); +	_run_or_die('--cipher=aes-xts-benbi', '--key-size=512', 'luksFormat', '--batch-mode', devices::make($part->{device}), $_[0]);      }); -    fs::format::after_formatting($part, 1); +    fs::format::after_formatting($part);  }  sub open_part { @@ -78,11 +118,17 @@ sub open_part {  	_run_or_die('luksOpen', devices::make($part->{device}),   				$part->{dm_name}, '--key-file', $_[0]);      }); -    run_program::run('udevadm', 'settle') unless $::isInstall; +    run_program::run('udevadm', 'settle'); + +    push @$dmcrypts, _get_existing_one_with_state($part); +} + +sub _get_existing_one_with_state { +    my ($part) = @_;      my $active_dmcrypt = _parse_dmsetup_table($part->{dm_name},   					      run_program::get_stdout('dmsetup', 'table', $part->{dm_name})); -    push @$dmcrypts, _get_existing_one([$part], $active_dmcrypt); +    _get_existing_one([$part], $active_dmcrypt);  }  sub close_part { @@ -90,7 +136,12 @@ sub close_part {      my $dm_part = fs::get::device2part("mapper/$part->{dm_name}", $dmcrypts);      _run_or_die('luksClose', devices::make($dm_part->{device}));      $part->{dm_active} = 0; -    @$dmcrypts = grep { $_ != $dm_part } @$dmcrypts;     +    @$dmcrypts = grep { $_ != $dm_part } @$dmcrypts; +    # remove partition from /etc/crypttab when deleted (mga#25891) +    substInFile { +	my ($name, $_dev) = split; +	undef $_ if $name eq $part->{dm_name}; +    } _crypttab();  }  sub _run_or_die { @@ -127,8 +178,10 @@ sub _get_existing_one {  	put_in_hash($part, $type);      }      fs::type::set_isFormatted($part, to_bool($part->{fs_type})); -     -    $part->{fs_type} or fs::type::set_fs_type($part, defaultFS()); + +    unless (fs::type::cannotBeMountable($part)) { +	$part->{fs_type} or fs::type::set_fs_type($part, defaultFS()); +    }      log::l("dmcrypt: found $part->{device} type $part->{fs_type} with rootDevice $part->{rootDevice}"); @@ -148,7 +201,7 @@ sub _parse_dmsetup_table {  }  sub active_dm() { -    run_program::run('udevadm', 'settle') unless $::isInstall; +    run_program::run('udevadm', 'settle');      map {  	my $name = s/(.*?):\s*// && $1; @@ -156,4 +209,8 @@ sub active_dm() {      } run_program::get_stdout('dmsetup', 'table');  } +=back + +=cut +  1; diff --git a/perl-install/fs/dmraid.pm b/perl-install/fs/dmraid.pm index 68dd98a16..7a279abc7 100644 --- a/perl-install/fs/dmraid.pm +++ b/perl-install/fs/dmraid.pm @@ -1,4 +1,4 @@ -package fs::dmraid; # $Id$ +package fs::dmraid;  use diagnostics;  use strict; @@ -14,23 +14,54 @@ use fs::wild_device;  use run_program; +=head1 SYNOPSYS + +Manage fake RAIDs using dmraid + +=head1 Functions + +=over + +=item init() + +Load kernel modules, init device mapper then scan for fake RAIDs. + +=cut +  sub init() {      whereis_binary('dmraid') or die "dmraid not installed";      eval { modules::load('dm-mirror', 'dm-zero') };      devices::init_device_mapper();      if ($::isInstall) { -	call_dmraid('-ay'); +        foreach my $name (call_dmraid('-s', '-c', '-i')) { +	    chomp($name); +	    log::l("got: $name"); +	    call_dmraid('-ay', '-i', '--rm_partitions', '-p', $name); +	    run_program::run('/sbin/kpartx', '-u', '-a', '/dev/mapper/' . $name); +        }      }      1;  } -#- call_dmraid is overloaded when debugging, see the end of this file +=item call_dmraid($option, @args) + +Runs dmraid with $option & @args. +It is overloaded when debugging, see the end of this file. + +=cut +  sub call_dmraid {      my ($option, @args) = @_;      run_program::get_stdout('dmraid', $option, @args);  } +=item check($in) + +Ensures dmraid is installed. If yes, calls init(). + +=cut +  sub check {      my ($in) = @_; @@ -39,29 +70,36 @@ sub check {      1;  } +=item _raid_devices_raw() + +Get the real VG names, needed for ddf1, and safer than begins_with for raid10 + +=cut +  sub _raid_devices_raw() { -    # get the real vg names, needed for ddf1, and safer than begins_with for raid10      log::l("_raid_devices_raw");      my %vgs;      my %pv2vg = map { +	chomp();  	log::l("got: $_");  	my %l; @l{qw(name size stride level status subsets devs spares)} = split(':');  	$vgs{$l{name}} = 1 if defined $l{spares}; -	if(/freeing device "(.*)", path "(.*)"/ && defined $vgs{$1}) { +	if (/freeing device "(.*)", path "(.*)"/ && defined $vgs{$1}) {  	    log::l("$2 => $1"); -	    { $2 => $1 }; +	    $2 => $1;          } -    } call_dmraid('-d', '-s', '-c', '-c'); +    } call_dmraid(qw(-d -s -c -c)); +      map {  	chomp;  	log::l("got: $_");  	my %l; @l{qw(pv format vg level status size)} = split(':'); -	if(defined $l{size} && defined $l{vg} && defined $pv2vg{$l{pv}} && !defined $vgs{$l{vg}}) { +	if (defined $l{size} && defined $l{vg} && defined $pv2vg{$l{pv}} && !defined $vgs{$l{vg}}) {  	    log::l("using $pv2vg{$l{pv}} instead of $l{vg}");  	    $l{vg} = $pv2vg{$l{pv}};  	}  	if_(defined $l{size}, \%l); -    } call_dmraid('-r', '-c', '-c'); +    } call_dmraid(qw(-r -c -c));  }  sub _raid_devices() { @@ -108,6 +146,12 @@ sub _sets() {      @sets;  } +=item vgs() + +Returns the list of VGs corresponding to dmraid + +=cut +  sub vgs() {      map {  	my $dev = "mapper/$_->{name}"; @@ -116,7 +160,12 @@ sub vgs() {  	#- device should exist, created by dmraid(8) using libdevmapper  	#- if it doesn't, we suppose it's not in use -	if_(-e "/dev/$dev", $vg);  +	if (-e "/dev/$dev") { +	    $vg;  +	} else { +	    log::l("ignoring $dev as /dev/$dev doesn't exist"); +	    (); +	}      } grep {   	if ($_->{status} eq 'ok') { @@ -128,11 +177,15 @@ sub vgs() {      } _sets();  } -# the goal is to handle migration from /dev/mapper/xxx1 to /dev/mapper/xxxp1, -# as used by initrd/nash. -# dmraid has been patched to follow xxxp1 device names. -# so until the box has rebooted on new initrd/dmraid, we must cope with /dev/mapper/xxx1 device names -# (cf #44182) +=item migrate_device_names ($vg) + +Handles migration from /dev/mapper/xxx1 to /dev/mapper/xxxp1, as used by initrd/nash. +dmraid has been patched to follow xxxp1 device names. +So until the box has rebooted on new initrd/dmraid, we must cope with /dev/mapper/xxx1 device names +(cf mdk#44182) + +=cut +  sub migrate_device_names {      my ($vg) = @_; @@ -148,6 +201,14 @@ sub migrate_device_names {      }  } +=back + +=head1 Debugging + +If $ENV{DRAKX_DEBUG_DMRAID} is set, debugging dmraid is done. +The C<call_dmraid()> function is overloaded and will spit out warnings. +=cut +  if ($ENV{DRAKX_DEBUG_DMRAID}) {      eval(<<'EOF');      my %debug_data = ( diff --git a/perl-install/fs/format.pm b/perl-install/fs/format.pm index 708c8ef8e..1fa90c29e 100644 --- a/perl-install/fs/format.pm +++ b/perl-install/fs/format.pm @@ -1,4 +1,4 @@ -package fs::format; # $Id$ +package fs::format;  use diagnostics;  use strict; @@ -10,30 +10,57 @@ use fs::type;  use fs::loopback;  use log; +=head1 SYNOPSYS + +B<fs::format> enables to format filesystems. + +=head1 Variables + +=over + +=item %cmds + +Commands to format filesystem: + +For each filesystem, list: [ package_name, command_to_use, options_to_use ] + +=cut +  my %cmds = (      ext2     => [ 'e2fsprogs', 'mkfs.ext2', '-F' ],      ext3     => [ 'e2fsprogs', 'mkfs.ext3', '-F' ],      ext4     => [ 'e2fsprogs', 'mkfs.ext4', '-F' ], +    f2fs     => [ 'f2fs-tools', 'mkfs.f2fs', '-f' ],      reiserfs => [ 'reiserfsprogs', 'mkfs.reiserfs', '-ff' ], -    reiser4  => [ 'reiser4progs', 'mkfs.reiser4', '-f', '-y' ],      xfs      => [ 'xfsprogs', 'mkfs.xfs', '-f', '-q' ],      jfs      => [ 'jfsutils', 'mkfs.jfs', '-f' ],      hfs      => [ 'hfsutils', 'hformat' ], -    dos      => [ 'dosfstools', 'mkdosfs' ], -    vfat     => [ 'dosfstools', 'mkdosfs', '-F', '32' ], -    swap     => [ 'util-linux-ng', 'mkswap' ], -    ntfs     => [ 'ntfsprogs', 'mkntfs', '--fast' ], -   'ntfs-3g' => [ 'ntfsprogs', 'mkntfs', '--fast' ], -    btrfs    => [ 'btrfs-progs', 'mkfs.btrfs' ], -    nilfs2   => [ 'nilfs-utils', 'mkfs.nilfs2' ], +    dos      => [ 'dosfstools', 'mkfs.fat' ], +    vfat     => [ 'dosfstools', 'mkfs.fat', '-F', '32' ], +    exfat    => [ 'exfatprogs', 'mkfs.exfat' ], +    swap     => [ 'util-linux', 'mkswap' ], +    ntfs     => [ 'ntfs-3g', 'mkfs.ntfs', '--fast' ], +   'ntfs-3g' => [ 'ntfs-3g', 'mkfs.ntfs', '--fast' ], +    btrfs    => [ 'btrfs-progs', 'mkfs.btrfs', '-f' ], +    nilfs2   => [ 'nilfs-utils', 'mkfs.nilfs2', '-f' ],  ); -my %LABELs = ( #- option, length, handled_by_mount + +=item %LABELs + +mkfs option to use in order to set the label + label specs. + +For each filesystem, list: [ option, max_length, handled_by_mount ] + +=cut + +my %LABELs = (      ext2     => [ '-L', 16, 1 ],      ext3     => [ '-L', 16, 1 ],      ext4     => [ '-L', 16, 1 ], +    exfat    => [ '-L', 16, 1 ], +    f2fs     => [ '-l', 16, 1 ],      reiserfs => [ '-l', 16, 1 ], -    reiser4  => [ '-L', 16, 1 ],      xfs      => [ '-L', 12, 1 ],      jfs      => [ '-L', 16, 1 ],      hfs      => [ '-l', 27, 0 ], @@ -43,29 +70,66 @@ my %LABELs = ( #- option, length, handled_by_mount      ntfs     => [ '-L', 128, 0 ],     'ntfs-3g' => [ '-L', 128, 0 ],      btrfs    => [ '-L', 256, 1 ], -    nilfs2   => [ '-L', 16, 1], +    nilfs2   => [ '-L', 16, 1 ],  ); -my %edit_LABEL = ( # package, command, option -# If option is defined, run <command> <option> <label> <device> -# If no option, run <command> <device> <label> +=item %edit_LABEL + +Commands to set the file system label. + +For each filesystem, list: [ package, command, option ] + +If option is defined, run <command> <option> <label> <device> + +If no option, run <command> <device> <label> + +=cut + +my %edit_LABEL = ( #       ext2     => [ 'e2fsprogs', 'tune2fs', '-L' ],      ext3     => [ 'e2fsprogs', 'tune2fs', '-L' ],      ext4     => [ 'e2fsprogs', 'tune2fs', '-L' ],      reiserfs => [ 'reiserfsprogs', 'reiserfstune', '-l' ], -#    reiser4      xfs      => [ 'xfsprogs', 'xfs_admin', '-L' ],      jfs      => [ 'jfsutils', 'jfs_tune', '-L' ],  #    hfs      dos      => [ 'mtools', 'mlabel', '-i' ], +    exfat    => [ 'exfatprogs', 'tune.exfat', '-L' ],      vfat     => [ 'mtools', 'mlabel', '-i' ], -#    swap     => [ 'util-linux-ng', 'mkswap' ], -    ntfs     => [ 'ntfsprogs', 'ntfslabel' ], -   'ntfs-3g' => [ 'ntfsprogs', 'ntfslabel' ], -#    btrfs -#    nilfs2 +    swap     => [ 'util-linux', 'swaplabel', '-L' ], +    ntfs     => [ 'ntfs-3g', 'ntfslabel' ], +   'ntfs-3g' => [ 'ntfs-3g', 'ntfslabel' ], +    btrfs    => [ 'btrfs-progs', 'btrfs', 'filesystem', 'label' ], +    nilfs2   => [ 'nilfs-utils', 'nilfs-tune', '-L' ],  ); +=item %preserve_UUID + +For each filesystem, list: [ option, max_length, handled_by_mount ] + +Those are used in order to preserve UUID on fs where we couldn't enforce it while formatting. + +=cut + +my %preserve_UUID = ( # package, command +    jfs      => [ 'jfsutils', 'jfs_tune', ], +    xfs      => [ 'xfsprogs', 'xfs_admin' ], +    nilfs2   => [ 'nilfs-utils', 'nilfs-tune' ], +); + + +=back + +=head1 Functions + +=over + +=item package_needed_for_partition_type($part) + +Return the package needed for that partition's type. + +=cut +  sub package_needed_for_partition_type {      my ($part) = @_;      my $l = $cmds{$part->{fs_type}} or return; @@ -81,14 +145,14 @@ sub check_package_is_installed_format {      my ($do_pkgs, $fs_type) = @_;      my ($pkg, $binary) = @{$cmds{$fs_type} || return}; -    whereis_binary($binary) || $do_pkgs->ensure_binary_is_installed($pkg, $binary); #- ensure_binary_is_installed checks binary chrooted, whereas we run the binary non-chrooted (pb for Mandriva One) +    whereis_binary($binary) || $do_pkgs->ensure_binary_is_installed($pkg, $binary); #- ensure_binary_is_installed checks binary chrooted, whereas we run the binary non-chrooted (pb for Mageia One)  }  sub check_package_is_installed_label {      my ($do_pkgs, $fs_type) = @_;      my ($pkg, $binary) = @{$edit_LABEL{$fs_type} || return}; -    whereis_binary($binary) || $do_pkgs->ensure_binary_is_installed($pkg, $binary); #- ensure_binary_is_installed checks binary chrooted, whereas we run the binary non-chrooted (pb for Mandriva One) +    whereis_binary($binary) || $do_pkgs->ensure_binary_is_installed($pkg, $binary); #- ensure_binary_is_installed checks binary chrooted, whereas we run the binary non-chrooted (pb for Mageia One)  }  sub canEditLabel { @@ -96,6 +160,12 @@ sub canEditLabel {      to_bool($edit_LABEL{$part->{fs_type}});  } +=item part($all_hds, $part, $wait_message) + +Frontend to part_raw() + +=cut +  sub part {      my ($all_hds, $part, $wait_message) = @_;      if (isRAID($part)) { @@ -109,8 +179,15 @@ sub part {  	$wait_message->(N("Formatting partition %s", $part->{device})) if $wait_message;  	part_raw($part, $wait_message);      } +    undef $part->{toFormat};  } +=item write_label($part) + +Set the label on the filesystem hold in $part. + +=cut +  sub write_label {      my ($part) = @_; @@ -126,6 +203,9 @@ sub write_label {      my @args;      if ($cmd eq 'mlabel') {        @args = ($cmd, @first_options, devices::make($dev), '::' . $part->{device_LABEL}); +    } elsif ($cmd eq 'btrfs') { +      # btrfs needs reverse ordering +      @args = ($cmd, @first_options, devices::make($dev), $part->{device_LABEL});      } elsif (defined $first_options[0]) {        @args = ($cmd, @first_options, $part->{device_LABEL}, devices::make($dev));      } else { @@ -135,6 +215,36 @@ sub write_label {      delete $part->{device_LABEL_changed};  } +sub write_btrfs_uuid { +    my ($UUID, $dev) = @_; +    $dev = devices::make($dev); +    my $status = system("echo y|btrfstune -U $UUID $dev") == 0; +    die "failed to set UUID to '$UUID' on $dev (status=$status)" if !$status; +} + +=item sub option_to_preserve_UUID_while_formating($part, $fs_type) + +Return the options needed to preserve UUID while formating + +=cut + +sub option_to_preserve_UUID_while_formating { +    my ($part, $fs_type) = @_; +    if (member($fs_type, qw(swap ext2 ext3 ext4))) { +	return '-U', $part->{device_UUID} if $part->{device_UUID}; +    } elsif ($fs_type eq 'reiserfs') { +	return '-u', $part->{device_UUID} if $part->{device_UUID}; +    } +    return (); +} + +=item part_raw($part, $wait_message) + +Actually format the $part partition disk. $wait_message is only used when formating ext3/4. +If not set, ext[3-4] will be formated without any progression bar, like other fses... + +=cut +  sub part_raw {      my ($part, $wait_message) = @_; @@ -161,13 +271,8 @@ sub part_raw {  	push @options, '-l', 'bootstrap';      } -    # Preserve UUID -    if (member($fs_type, 'swap', 'ext2', 'ext3', 'ext4')) { -	push @options, '-U', $part->{device_UUID} if $part->{device_UUID}; -    } elsif ($fs_type eq 'reiserfs') { -	push @options, '-u', $part->{device_UUID} if $part->{device_UUID}; -    } - +    push @options, option_to_preserve_UUID_while_formating($part, $fs_type); +          if ($part->{device_LABEL}) {  	push @options, @{$LABELs{$fs_type}}[0], $part->{device_LABEL};      } @@ -184,15 +289,8 @@ sub part_raw {      delete $part->{device_LABEL_changed}; -    # Preserve UUID on fs where we couldn't enforce it while formatting -    if ($fs_type eq 'jfs') { -	run_program::raw('jfs_tune', '-U', devices::make($dev)); -    } elsif ($fs_type eq 'xfs') { -	run_program::raw('xfs_admin', '-U', devices::make($dev)); -    } elsif ($fs_type eq 'btrfs') { -	#FIXME -    } -     +    preserve_UUID_after_format($dev, $part, $fs_type); +      if (member($fs_type, qw(ext3 ext4))) {  	disable_forced_fsck($dev);      } @@ -200,6 +298,28 @@ sub part_raw {      after_formatting($part);  } +=item preserve_UUID_after_format($dev, $part, $fs_type) + +Preserve UUID on fs where we couldn't enforce it while formatting + +=cut + +sub preserve_UUID_after_format { +    my ($dev, $part, $fs_type) = @_; +    if (my $uuid_cmd = $preserve_UUID{$fs_type}) { +	my (undef, $cmd) = @$uuid_cmd; +	run_program::raw({}, $cmd, '-U', $part->{device_UUID}, devices::make($dev)) if $cmd; +    } elsif ($fs_type eq 'btrfs' && $part->{device_UUID}) { +	write_btrfs_uuid($part->{device_UUID}, $dev); +    } +} + +=item after_formatting($part) + +Misc post formating tags (rereading UUID & setting state) + +=cut +  sub after_formatting {      my ($part) = @_; @@ -209,6 +329,12 @@ sub after_formatting {      set_isFormatted($part, 1);  } +=item mkfs_ext3($wait_message, @args) + +Display a progression bar whike formating ext3/4 + +=cut +  sub mkfs_ext3 {      my ($wait_message, @args) = @_; @@ -225,6 +351,12 @@ sub mkfs_ext3 {      return close($F);  } +=item disable_forced_fsck($dev) + +Disable automatic fsck on extX (infinite number of mounts & duration between 2 fsck runs) + +=cut +  sub disable_forced_fsck {      my ($dev) = @_;      run_program::run("tune2fs", "-c0", "-i0", devices::make($dev)); @@ -235,7 +367,7 @@ sub clean_label {      if ($part->{device_LABEL}) {  	my $fs_type = $part->{fs_type};  	if ($LABELs{$fs_type}) { -	    my ($option, $length, $handled_by_mount) = @{$LABELs{$fs_type}}; +	    my ($_option, $length, $handled_by_mount) = @{$LABELs{$fs_type}};  	    if (length $part->{device_LABEL} > $length) {  		my $short = substr($part->{device_LABEL}, 0, $length);  		log::l("shortening LABEL $part->{device_LABEL} to $short"); @@ -296,5 +428,8 @@ sub formatMount_all {      };  } +=back + +=cut  1; diff --git a/perl-install/fs/get.pm b/perl-install/fs/get.pm index d98ccb2c7..00c807738 100644 --- a/perl-install/fs/get.pm +++ b/perl-install/fs/get.pm @@ -1,4 +1,4 @@ -package fs::get; # $Id$ +package fs::get;  use diagnostics;  use strict; @@ -11,6 +11,17 @@ use fs;  use common;  use log; + +=head1 SYNOPSYS + +B<fs::get>  + +=head1 Functions + +=over + +=cut +  sub empty_all_hds() {      { hds => [], lvms => [], raids => [], dmcrypts => [], loopbacks => [], raw_hds => [], nfss => [], smbs => [], davs => [], special => [] };  } @@ -22,7 +33,7 @@ sub fstab {  sub really_all_fstab {      my ($all_hds) = @_;      my @l = fstab($all_hds); -    @l, @{$all_hds->{raw_hds}}, @{$all_hds->{nfss}}, @{$all_hds->{smbs}}, @{$all_hds->{davs}}; +    @l, (grep { !$_->{is_removable} } @{$all_hds->{raw_hds}}), @{$all_hds->{nfss}}, @{$all_hds->{smbs}}, @{$all_hds->{davs}};  }  sub fstab_and_holes { @@ -51,7 +62,12 @@ sub hds {      (@{$all_hds->{hds}}, @{$all_hds->{lvms}});  } -#- get all normal partition including special ones as found on sparc. +=item hds_fstab(@hds) + +Get all normal partition. + +=cut +  sub hds_fstab {      map { partition_table::get_normal_parts($_) } @_;  } @@ -119,6 +135,15 @@ sub has_mntpoint {      my ($mntpoint, $all_hds) = @_;      mntpoint2part($mntpoint, [ really_all_fstab($all_hds) ]);  } + +sub root_from_mounted() { +    foreach (`df -P`) { +        next if m!^[^/]!; # ignore tootfs +        my ($fs, undef, undef, undef, undef, $mntpnt) = split(/\s+/); +        return $fs if $mntpnt eq '/'; +    } +} +  sub root_ {      my ($fstab, $o_boot) = @_;      $o_boot && mntpoint2part("/boot", $fstab) || mntpoint2part("/", $fstab); @@ -144,7 +169,10 @@ sub is_same_hd {      } else {  	$hd1->{device_LABEL} && $hd2->{device_LABEL} && $hd1->{device_LABEL} eq $hd2->{device_LABEL}  	  || $hd1->{device_UUID} && $hd2->{device_UUID} && $hd1->{device_UUID} eq $hd2->{device_UUID} -	  || $hd1->{device} && $hd2->{device} && $hd1->{device} eq $hd2->{device}; +	  || $hd1->{device} && $hd2->{device} && $hd1->{device} eq $hd2->{device} +	  || $hd1->{device} && $hd2->{device_alias} && $hd1->{device} eq $hd2->{device_alias} +	  || $hd1->{device_alias} && $hd2->{device} && $hd1->{device_alias} eq $hd2->{device} +	  || $hd1->{device_alias} && $hd2->{device_alias} && $hd1->{device_alias} eq $hd2->{device_alias};      }  } @@ -153,4 +181,8 @@ sub mntpoint_prefixed {      $::prefix . $part->{mntpoint};  } +=back + +=cut +  1; diff --git a/perl-install/fs/loopback.pm b/perl-install/fs/loopback.pm index 572c79f67..8d0c729ec 100644 --- a/perl-install/fs/loopback.pm +++ b/perl-install/fs/loopback.pm @@ -1,4 +1,4 @@ -package fs::loopback; # $Id$ +package fs::loopback;  use diagnostics;  use strict; @@ -86,7 +86,7 @@ sub getFree {  }  #- returns the size of the loopback file if it already exists -#- returns -1 is the loopback file can not be used +#- returns -1 is the loopback file cannot be used  sub verifFile {      my ($dir, $file, $part) = @_;      -e "$dir$file" and return -s "$dir$file"; diff --git a/perl-install/fs/mount.pm b/perl-install/fs/mount.pm index 63db0470a..6afaa9260 100644 --- a/perl-install/fs/mount.pm +++ b/perl-install/fs/mount.pm @@ -1,4 +1,4 @@ -package fs::mount; # $Id$ +package fs::mount;  use diagnostics;  use strict; @@ -35,8 +35,8 @@ sub mount {      $fs or log::l("not mounting $dev partition"), return;      { -	my @fs_modules = qw(btrfs ext3 ext4 hfs jfs nilfs2 nfs ntfs romfs reiserfs ufs xfs vfat); -	my @types = (qw(ext2 proc sysfs usbfs usbdevfs iso9660 devfs devpts auto ntfs-3g), @fs_modules); +	my @fs_modules = qw(btrfs ext3 ext4 f2fs hfs jfs nilfs2 nfs ntfs romfs reiserfs ufs xfs vfat); +	my @types = (qw(ext2 proc sysfs iso9660 devpts auto ntfs-3g), @fs_modules);  	push @types, 'smb', 'cifs', 'davfs2' if !$::isInstall; @@ -83,6 +83,7 @@ sub mount {      push @mount_opt, 'ro' if $b_rdonly;      $o_wait_message->(N("Mounting partition %s", $dev)) if $o_wait_message; +    modules::load("fuse") if $::isInstall && $fs eq 'ntfs-3g' && ! -e '/dev/fuse';      run_program::run('mount', '-t', $fs, $dev, $where, if_(@mount_opt, '-o', join(',', @mount_opt))) or die N("mounting partition %s in directory %s failed", $dev, $where);  } @@ -125,7 +126,7 @@ sub umount {  	run_program::run('umount', '2>', \$err, $mntpoint) or die N("error unmounting %s: %s", $mntpoint, common::to_utf8($err));      }; -    substInFile { $_ = '' if /(^|\s)$mntpoint\s/ } '/etc/mtab'; #- do not care about error, if we can not read, we will not manage to write... (and mess mtab) +    substInFile { $_ = '' if /(^|\s)$mntpoint\s/ } '/etc/mtab'; #- do not care about error, if we cannot read, we will not manage to write... (and mess mtab)  }  sub part { @@ -160,8 +161,6 @@ sub part {  		set_loop($part);  		$options = join(',', grep { !/^(encryption=|encrypted$|loop$)/ } split(',', $options)); #- we take care of this, don't let it mount see it  	    } elsif (isLoopback($part)) { -		#- mount will take care, but we must help it -		devices::make("loop$_") foreach 0 .. 7;  		$options = join(',', uniq('loop', split(',', $options))); #- ensure the loop options is used  	    } elsif ($part->{options} =~ /encrypted/) {  		log::l("skip mounting $part->{device} since we do not have the encrypt_key"); @@ -227,11 +226,10 @@ sub umount_all {      }  } -sub usbfs { +sub sys_kernel_debug {      my ($prefix) = @_; -    my $fs = cat_('/proc/filesystems') =~ /usbfs/ ? 'usbfs' : 'usbdevfs'; -    mount('none', "$prefix/proc/bus/usb", $fs); +    mount('none', "$prefix/sys/kernel/debug/usb", 'debugfs');  }  1; diff --git a/perl-install/fs/mount_options.pm b/perl-install/fs/mount_options.pm index 291f7d350..0b63f7260 100644 --- a/perl-install/fs/mount_options.pm +++ b/perl-install/fs/mount_options.pm @@ -1,4 +1,4 @@ -package fs::mount_options; # $Id$ +package fs::mount_options;  use diagnostics;  use strict; @@ -12,7 +12,7 @@ sub list() {      my %non_defaults = (  			sync => 'async', noatime => 'atime', noauto => 'auto', ro => 'rw',   			user => 'nouser', nodev => 'dev', noexec => 'exec', nosuid => 'suid', -			user_xattr => 'nouser_xattr', acl => 'noacl', +			user_xattr => 'nouser_xattr',  		       );      my @user_implies = qw(noexec nodev nosuid);      \%non_defaults, \@user_implies; @@ -35,9 +35,10 @@ sub unpack {  		  reiserfs => [ 'notail' ],  		 );      push @{$per_fs{$_}}, 'usrquota', 'grpquota' foreach 'ext2', 'ext3', 'ext4', 'xfs'; +    push @{$per_fs{$_}}, 'acl' foreach 'ext2', 'ext3', 'ext4', 'reiserfs';      while (my ($fs, $l) = each %per_fs) { -	$part->{fs_type} eq $fs || $part->{fs_type} eq 'auto' && member($fs, @auto_fs) or next; +	member($part->{fs_type}, $fs, 'auto') && member($fs, @auto_fs) or next;  	$non_defaults->{$_} = 1 foreach @$l;      } @@ -102,6 +103,7 @@ sub pack_ {  }  sub pack {      my ($part, $options, $unknown) = @_; +    $unknown =~ s/ /,/g;      $part->{options} = pack_($part, $options, $unknown) || 'defaults';      noreturn();  } @@ -109,38 +111,38 @@ sub pack {  # update me on each util-linux new release:  sub help() {      ( -	'acl' => N("Enable Posix Access Control Lists"), +	'acl' => N("Enable POSIX Access Control Lists"),  	'flush' => N("Flush write cache on file close"),  	'grpquota' => N("Enable group disk quota accounting and optionally enforce limits"), -	'noatime' => N("Do not update inode access times on this file system +	'noatime' => N("Do not update inode access times on this filesystem  (e.g, for faster access on the news spool to speed up news servers)."),  	'relatime' => N("Update inode access times on this filesystem in a more efficient way  (e.g, for faster access on the news spool to speed up news servers)."),  	'noauto' => N("Can only be mounted explicitly (i.e., -the -a option will not cause the file system to be mounted)."), +the -a option will not cause the filesystem to be mounted)."), -	'nodev' => N("Do not interpret character or block special devices on the file system."), +	'nodev' => N("Do not interpret character or block special devices on the filesystem."),  	'noexec' => N("Do not allow execution of any binaries on the mounted -file system. This option might be useful for a server that has file systems +filesystem. This option might be useful for a server that has filesystems  containing binaries for architectures other than its own."),  	'nosuid' => N("Do not allow set-user-identifier or set-group-identifier  bits to take effect. (This seems safe, but is in fact rather unsafe if you  have suidperl(1) installed.)"), -	'ro' => N("Mount the file system read-only."), +	'ro' => N("Mount the filesystem read-only."), -	'sync' => N("All I/O to the file system should be done synchronously."), +	'sync' => N("All I/O to the filesystem should be done synchronously."), -	'users' => N("Allow every user to mount and umount the file system."),          +	'users' => N("Allow every user to mount and umount the filesystem."),          -	'user' => N("Allow an ordinary user to mount the file system."),          +	'user' => N("Allow an ordinary user to mount the filesystem."),           	'usrquota' => N("Enable user disk quota accounting, and optionally enforce limits"), @@ -185,7 +187,6 @@ sub set_default {      if (!$opts{ignore_is_removable} && $part->{is_removable}   	  && !member($part->{mntpoint}, fs::type::directories_needed_to_boot())   	  && (!$part->{fs_type} || $part->{fs_type} eq 'auto' || $part->{fs_type} =~ /:/)) { -	$options->{supermount} = 0; #- always disable supermount  	$part->{fs_type} = 'auto';  	$options->{flush} = 1 if $part->{media_type} ne 'cdrom';      } @@ -203,10 +204,10 @@ sub set_default {  	#- noatime on laptops (do not wake up the hd)  	#- otherwise relatime (wake up the hd less often / better performances)  	#- Do  not  update  inode  access times on this -	#- file system (e.g, for faster access  on  the +	#- filesystem (e.g, for faster access  on  the  	#- news spool to speed up news servers).  	$options->{relatime} = $options->{noatime} = 0; -	$options->{detect_devices::isLaptop() ? 'noatime': 'relatime'} = 1 if !$opts{force_atime}; +	$options->{ detect_devices::isLaptop() ? 'noatime' : 'relatime' } = 1 if !$opts{force_atime};      }      if ($part->{fs_type} eq 'nfs') {  	put_in_hash($options, {  @@ -223,7 +224,7 @@ sub set_default {  			      }) if $part->{is_removable};  	put_in_hash($options, { -			       'umask=0' => $opts{security} <= 1, +			       'umask=0' => $opts{security} <= 1 && !isESP($part),  			       'iocharset=' => $opts{iocharset}, 'codepage=' => $opts{codepage},  			      });      } diff --git a/perl-install/fs/mount_point.pm b/perl-install/fs/mount_point.pm index 2e7f01b67..56f2405e9 100644 --- a/perl-install/fs/mount_point.pm +++ b/perl-install/fs/mount_point.pm @@ -1,4 +1,4 @@ -package fs::mount_point; # $Id$ +package fs::mount_point;  use diagnostics;  use strict; @@ -13,6 +13,8 @@ sub guess_mount_point {      my %l = (  	     '/'     => 'etc/fstab',  	     '/boot' => 'vmlinuz', +	     '/boot' => 'vmlinux', +	     '/boot' => 'uImage',  	     '/tmp'  => '.X11-unix',  	     '/usr'  => 'src',  	     '/var'  => 'spool', @@ -22,7 +24,10 @@ sub guess_mount_point {      my $d = $handle->{dir};      my $mnt = find { -e "$d/$l{$_}" } keys %l;      $mnt ||= (stat("$d/.bashrc"))[4] ? '/root' : '/home/user' . ++$$user if -e "$d/.bashrc"; -    $mnt ||= (any { -d $_ && (stat($_))[4] >= 500 && -e "$_/.bashrc" } glob_($d)) ? '/home' : ''; +    $mnt ||= (any { -d $_ && (stat($_))[4] >= 1000 && -e "$_/.bashrc" } glob_($d)) ? '/home' : ''; +    # Keep uid 500 here for guesswork, but base it on .bash_history to increase +    # changes it's a real user. +    $mnt ||= (any { -d $_ && (stat($_))[4] >= 500 && -e "$_/.bash_history" } glob_($d)) ? '/home' : '';      ($mnt, $handle);  } @@ -41,30 +46,32 @@ sub suggest_mount_points {  	#- try to find other mount points via fstab  	fs::merge_info_from_fstab($fstab, $handle->{dir}, $uniq, 'loose') if $mnt eq '/';      } +    # reuse existing ESP under UEFI: +    my @ESP = if_(is_uefi(), grep { isESP($_) } @$fstab); +    if (@ESP) { +	$ESP[0]{mntpoint} = '/boot/EFI'; +	delete $ESP[0]{unsafeMntpoint}; +    }      $_->{mntpoint} and log::l("suggest_mount_points: $_->{device} -> $_->{mntpoint}") foreach @$fstab;  }  sub suggest_mount_points_always {      my ($fstab) = @_; -    my @win = grep { isFat_or_NTFS($_) && !$_->{isMounted} && maybeFormatted($_) && !$_->{is_removable} && $_->{pt_type} != 0x12 && !isRecovery($_)} @$fstab; +    my @ESP = if_(is_uefi(), grep { isESP($_) && maybeFormatted($_) && !$_->{is_removable} } @$fstab); +    if (@ESP) { +	$ESP[0]{mntpoint} = "/boot/EFI"; +    } +    my @win = grep { isnormal_Fat_or_NTFS($_) && !$_->{isMounted} && maybeFormatted($_) && !$_->{is_removable} } @$fstab;      log::l("win parts: ", join ",", map { $_->{device} } @win) if @win;      if (@win == 1) { -	#- Suggest /boot/efi on ia64. -	$win[0]{mntpoint} = arch() =~ /ia64/ ? "/boot/efi" : "/media/windows"; +	$win[0]{mntpoint} = "/media/windows";      } else {  	my %w; foreach (@win) {  	    my $v = $w{$_->{device_windobe}}++;  	    $_->{mntpoint} = $_->{unsafeMntpoint} = "/media/win_" . lc($_->{device_windobe}) . ($v ? $v+1 : ''); #- lc cuz of StartOffice(!) cf dadou  	}      } - -    my @sunos = grep { $_->{pt_type} == 2 } @$fstab; #- take only into account root partitions. -    if (@sunos) { -	my $v = ''; -	map { $_->{mntpoint} = $_->{unsafeMntpoint} = "/mnt/sunos" . ($v && ++$v) } @sunos; -    } -    #- a good job is to mount SunOS root partition, and to use mount point described here in /etc/vfstab.  }  sub validate_mount_points { diff --git a/perl-install/fs/partitioning.pm b/perl-install/fs/partitioning.pm index ab2b6733a..18fa7e114 100644 --- a/perl-install/fs/partitioning.pm +++ b/perl-install/fs/partitioning.pm @@ -1,16 +1,18 @@ -package fs::partitioning; # $Id$ +package fs::partitioning;  use diagnostics;  use strict;  use common;  use fs::format; +use fs::get;  use fs::type;  sub guess_partitions_to_format {      my ($fstab) = @_; +    my $root_part = fs::get::root($fstab);      foreach (@$fstab) { -	$_->{mntpoint} = "swap" if isSwap($_); +	$_->{mntpoint} = "swap" if isSwap($_) && ($_->{rootDevice} eq $root_part->{rootDevice} || !$_->{is_removable} && !$root_part->{is_removable});  	$_->{mntpoint} or next;  	add2hash_($_, { toFormat => $_->{notFormatted} }) if $_->{fs_type}; #- eg: do not set toFormat for isRawRAID (0xfd) @@ -45,14 +47,14 @@ sub choose_partitions_to_format {      $in->ask_from_(          { messages => N("Choose the partitions you want to format"),  	  interactive_help_id => 'formatPartitions', -          advanced_messages => N("Check bad blocks?"), +          advanced_messages => N("Check for bad blocks?"),          },          [ map {   	    my $e = $_;  	    ({  	      text => partition_table::description($e), type => 'bool',  	      val => \$e->{toFormatTmp} -	     }, if_(!isLoopback($_) && !member($_->{fs_type}, 'reiserfs', 'xfs', 'jfs'), { +	     }, if_(!isLoopback($_) && isBlockCheckable($_), {  	      text => partition_table::description($e), type => 'bool', advanced => 1,   	      disabled => sub { !$e->{toFormatTmp} },  	      val => \$e->{toFormatCheck} diff --git a/perl-install/fs/partitioning_wizard.pm b/perl-install/fs/partitioning_wizard.pm index 7ae3ba2de..6e77f3eff 100644 --- a/perl-install/fs/partitioning_wizard.pm +++ b/perl-install/fs/partitioning_wizard.pm @@ -1,4 +1,4 @@ -package fs::partitioning_wizard; # $Id$ +package fs::partitioning_wizard;  use diagnostics;  use strict; @@ -14,12 +14,26 @@ use partition_table::raw;  use partition_table::dos;  use POSIX qw(ceil); -#- unit of $mb is mega bytes, min and max are in sectors, this -#- function is used to convert back to sectors count the size of -#- a partition ($mb) given from the interface (on Resize or Create). -#- modified to take into account a true bounding with min and max. + +=head1 SYNOPSYS + +B<fs::partitioning_wizard> implements the partitioning wizard. + +=head1 Functions + +=over + +=item from_Mb($mb, $min, $max) + +This function is used to convert back to sectors count the size of +a partition ($mb) given from the interface (on Resize or Create). +modified to take into account a true bounding with min and max. +Unit of $mb is mega bytes, min and max are in sectors. + +=cut +  sub from_Mb { -    my ($mb, $min, $max) = @_; +    emy ($mb, $min, $max) = @_;      $mb <= to_Mb($min) and return $min;      $mb >= to_Mb($max) and return $max;      MB($mb); @@ -30,15 +44,28 @@ sub to_Mb {  }  sub partition_with_diskdrake { -    my ($in, $all_hds, $fstab, $manual_fstab, $partitions, $partitioning_flags, $skip_mtab) = @_; +    my ($in, $all_hds, $fstab, $manual_fstab, $_partitions, $partitioning_flags, $skip_mtab) = @_;      my $ok; +    # The classic installer sets $skip_mtab to either undef or 1. The live +    # installer sets it to 'skip_mtab'. If $skip_mtab is not set, this has +    # already been done by fs::any::get_hds. +    if ($skip_mtab eq 'skip_mtab') { +        fs::mount_point::suggest_mount_points_always($fstab); +    } +      do {  	$ok = 1;  	my $do_force_reload = sub { +            require File::Temp; +            require fs::dmcrypt; +            my (undef, $tmp_file) = File::Temp::mkstemp('/tmp/crypttab.XXXXXXX'); +            fs::dmcrypt::save_crypttab_($all_hds, $tmp_file);              my $new_hds = fs::get::empty_all_hds();              fs::any::get_hds($new_hds, $fstab, $manual_fstab, $partitioning_flags, $skip_mtab, $in);              %$all_hds = %$new_hds; +            fs::dmcrypt::read_crypttab_($all_hds, $tmp_file); +            rm_rf($tmp_file);              $all_hds;  	};  	require diskdrake::interactive; @@ -48,32 +75,40 @@ sub partition_with_diskdrake {  	}  	my @fstab = fs::get::fstab($all_hds); -	unless ($root = fs::get::root_(\@fstab)) { +	unless (fs::get::root_(\@fstab)) {  	    $ok = 0;  	    $in->ask_okcancel(N("Partitioning"), N("You must have a root partition. -For this, create a partition (or click on an existing one). +To accomplish this, create a partition (or click on an existing one).  Then choose action ``Mount point'' and set it to `/'"), 1) or return;  	}  	if (!any { isSwap($_) } @fstab) {  	    $ok &&= $in->ask_okcancel('', N("You do not have a swap partition.\n\nContinue anyway?"));  	} -	if (arch() =~ /ia64/ && !fs::get::has_mntpoint("/boot/efi", $all_hds)) { -	    $in->ask_warn('', N("You must have a FAT partition mounted in /boot/efi")); +	if (is_uefi()) { +	  my $part = fs::get::has_mntpoint("/boot/EFI", $all_hds); +	  if (!$part || !isESP($part)) { +	    $in->ask_warn('', N("You must have a ESP FAT32 partition mounted in /boot/EFI"));  	    $ok = ''; +	  } +	} else { +	    if (fs::any::is_boot_bios_part_needed($all_hds)) { +		$in->ask_warn('', N("You must have a BIOS boot partition for non-UEFI GPT-partitioned disks. Please create one before continuing.")); +		$ok = ''; +	    }  	}      } until $ok;      1;  }  sub partitionWizardSolutions { -    my ($in, $all_hds, $all_fstab, $manual_fstab, $partitions, $partitioning_flags, $skip_mtab, $target) = @_; +    my ($in, $all_hds, $all_fstab, $manual_fstab, $partitions, $partitioning_flags, $skip_mtab, $o_target) = @_;      my $hds = $all_hds->{hds};      my $fstab;      my $full_fstab = [ fs::get::fstab($all_hds) ]; -    if ($target) { -        $hds = [ $target ]; -        $fstab = [ grep { $_->{rootDevice} eq $target->{device} } fs::get::fstab($all_hds) ]; +    if ($o_target) { +        $hds = [ $o_target ]; +        $fstab = [ grep { $_->{rootDevice} eq $o_target->{device} } fs::get::fstab($all_hds) ];      } else {          $fstab = $full_fstab;      } @@ -84,13 +119,14 @@ sub partitionWizardSolutions {      my $min_linux = MB(600);      my $min_swap = MB(50);      my $min_freewin = MB(100); +    fsedit::init_mntpnt_suggestions($all_hds, $o_target);      # each solution is a [ score, text, function ], where the function retunrs true if succeeded      my @hds_rw = grep { !$_->{readonly} } @$hds;      my @hds_can_add = grep { $_->{type} ne 'hd' || $_->can_add } @hds_rw;      if (fs::get::hds_free_space(@hds_can_add) > $min_linux) { -	$solutions{free_space} = [ 30, N("Use free space"), sub { fsedit::auto_allocate($all_hds, $partitions); 1 } ]; +	$solutions{free_space} = [ 30, N("Use free space"), sub { fsedit::auto_allocate($all_hds, $partitions, $o_target); 1 } ];      } else {   	push @wizlog, N("Not enough free space to allocate new partitions") . ": " .  	  (@hds_can_add ?  @@ -105,8 +141,8 @@ sub partitionWizardSolutions {  	push @wizlog, N("There is no existing partition to use");      } -    if (my @ok_for_resize_fat = grep { isFat_or_NTFS($_) && !fs::get::part2hd($_, $all_hds)->{readonly} -					 && !isRecovery($_) && $_->{size} > $min_linux + $min_swap + $min_freewin } @$fstab) { +    if (my @ok_for_resize_fat = grep { isnormal_Fat_or_NTFS($_) && !fs::get::part2hd($_, $all_hds)->{readonly} +					 && $_->{size} > $min_linux + $min_swap + $min_freewin } @$fstab) {          @ok_for_resize_fat = map {              my $part = $_;              my $hd = fs::get::part2hd($part, $all_hds); @@ -139,19 +175,19 @@ sub partitionWizardSolutions {                      $min_win += partition_table::raw::cylinder_size($hd);                      if ($part->{size} <= $min_linux_all + $min_win) { -#                die N("Your Microsoft Windows® partition is too fragmented. Please reboot your computer under Microsoft Windows®, run the ``defrag'' utility, then restart the Mandriva Linux installation."); +#                die N("Your Microsoft Windows® partition is too fragmented. Please reboot your computer under Microsoft Windows®, run the ``defrag'' utility, then restart the %s installation.", N("Mageia"));                          undef $part;                      } else {                          $part->{resize_fat} = $resize_fat;                          $part->{min_win} = $min_win;                          $part->{min_linux} = $min_linux_all;                          #- try to keep at least 1GB free for Windows -                        #- try to use from 6GB to 10% free space for Linux +                        #- try to use from 20GB to 20% free space for Linux                          my $suggested_size = max(                              $part->{min_win} + 1 * MB(1024),                              min( -                                $part->{size} - int(0.1 * ($part->{size} - $part->{min_win})), -                                $part->{size} - 6 * MB(1024), +                                $part->{size} - int(0.2 * ($part->{size} - $part->{min_win})), +                                $part->{size} - 20 * MB(1024),                              ),                          );                          $part->{req_size} = max(min($suggested_size, $part->{size} - $part->{min_linux}), $part->{min_win}); @@ -169,9 +205,15 @@ sub partitionWizardSolutions {                            $part = $in->ask_from_listf_raw({ messages => N("Which partition do you want to resize?"),                                                                 interactive_help_id => 'resizeFATChoose',                                                               }, \&partition_table::description, \@ok_for_resize_fat) or return; -                          $part->{size} > $part->{min_linux} + $part->{min_win} or die N("Your Microsoft Windows® partition is too fragmented. Please reboot your computer under Microsoft Windows®, run the ``defrag'' utility, then restart the Mandriva Linux installation."); +                          $part->{size} > $part->{min_linux} + $part->{min_win} or die N("Your Microsoft Windows® partition is too fragmented. Please reboot your computer under Microsoft Windows®, run the ``defrag'' utility, then restart the %s installation.", N("Mageia"));                        } else { -                          $part = top(grep { $_->{req_size} } @ok_for_resize_fat); +                          my @selected = grep { +                              $_->{selected_for_resize} && +                              $o_target->{device} eq $_->{rootDevice}; # Not needed but let's be safe +                          } @ok_for_resize_fat; +                          my $nb_parts = @selected; +                          die N("Failed to find the partition to resize (%d choices)", $nb_parts) unless $nb_parts == 1; +                          $part = $selected[0];                        }                        my $resize_fat = $part->{resize_fat};                        my $hd = fs::get::part2hd($part, $all_hds); @@ -218,7 +260,7 @@ filesystem checks will be run on your next boot into Microsoft Windows®")) if $                        partition_table::adjust_local_extended($hd, $part);                        partition_table::adjust_main_extended($hd); -                      fsedit::auto_allocate($all_hds, $partitions); +                      fsedit::auto_allocate($all_hds, $partitions, $hd);                        1;                    }, \@ok_for_resize_fat ];          } @@ -232,19 +274,22 @@ filesystem checks will be run on your next boot into Microsoft Windows®")) if $  	    sub {                  my $hd;                  if (!$in->isa('interactive::gtk')) { -                    $hd = $in->ask_from_listf_raw({ messages => N("You have more than one hard drive, which one do you install linux on?"), +                    $hd = $in->ask_from_listf_raw({ messages => N("You have more than one hard disk drive, which one do you want the installer to use?"),                                                         title => N("Partitioning"),                                                         interactive_help_id => 'takeOverHdChoose',                                                       },                                                       \&partition_table::description, \@hds_rw) or return;                  } else { -                    $hd = $target; +                    $hd = $o_target;                  }  		$in->ask_okcancel_({ messages => N("ALL existing partitions and their data will be lost on drive %s", partition_table::description($hd)),  				    title => N("Partitioning"),  				    interactive_help_id => 'takeOverHdConfirm' }) or return;  		fsedit::partition_table_clear_and_initialize($all_hds->{lvms}, $hd, $in); -		fsedit::auto_allocate($all_hds, $partitions); +		# FIXME: reread all_hds: +		# re add suggestions if needed (as we might just have erased eg Boot BIOS partition): +		fsedit::init_mntpnt_suggestions($all_hds, $hd, 1); +		fsedit::auto_allocate($all_hds, $partitions, $hd);  		1;  	    } ];      } @@ -263,11 +308,7 @@ filesystem checks will be run on your next boot into Microsoft Windows®")) if $  When you are done, do not forget to save using `w'", partition_table::description($_));  		print "\n\n";  		my $pid = 0; -		if (arch() =~ /ppc/) { -			$pid = fork() or exec "pdisk", devices::make($_->{device}); -		} else { -			$pid = fork() or exec "fdisk", devices::make($_->{device}); -		} +		$pid = fork() or exec "fdisk", devices::make($_->{device});  		waitpid($pid, 0);  	    }  	    $in->leave_console; @@ -280,40 +321,53 @@ When you are done, do not forget to save using `w'", partition_table::descriptio  sub warn_reboot_needed {      my ($in) = @_; -    $in->ask_warn(N("Partitioning"), N("You need to reboot for the partition table modifications to take place")); +    $in->ask_warn(N("Partitioning"), N("You need to reboot for the partition table modifications to take effect"));  }  sub create_display_box {      my ($kind, $resize, $fill_empty, $button) = @_; -    my @parts = fs::get::hds_fstab_and_holes($kind->{val}); -    my $totalsectors = $kind->{val}{totalsectors}; +    # Hide empty space < 2MB, wehave such holes due to alignment +    my @parts = grep { $_->{size} > MB(2) || !isEmpty($_) } diskdrake::hd_gtk::kind2parts($kind); + +    my $totalsectors = diskdrake::hd_gtk::kind2sectors($kind, @parts); -    my $width = 540; +    my $width = 520;      my $minwidth = 40; -    my $display_box = ugtk2::gtkset_size_request(Gtk2::HBox->new(0,0), -1, 26); +    my $display_box = ugtk3::gtkset_size_request(Gtk3::HBox->new(0,0), -1, 26); +    $display_box->set_spacing(1);      my $sep_count = @parts - 1;      #- ratio used to compute initial partition pixel width (each partition should be > min_width) -    #- though, the pixel/sectors ratio can not be the same for all the partitions +    #- though, the pixel/sectors ratio cannot be the same for all the partitions      my $initial_ratio = $totalsectors ? ($width - @parts * $minwidth - $sep_count) / $totalsectors : 1; -    my $vbox = Gtk2::VBox->new; +    my $vbox = Gtk3::VBox->new; -    my $part_sep;      my $desc; -    my $last = $resize && $resize->[-1]; +    if ($resize) { +	my %resizable_parts; +	foreach my $entry (@$resize) { +	    # selected_for_resize may have been set on another disk, clear it +	    $entry->{selected_for_resize} = 0; +	    $resizable_parts{$entry->{device}} = $entry; +	} +	# find resizable parts on this disk +	my @choices = grep { $resizable_parts{$_->{device}} } @parts; +	my @sorted_resize = sort { +		$a->{size} - $a->{req_size} <=> $b->{size} - $b->{req_size}; +	    } @choices; +	$sorted_resize[-1]{selected_for_resize} = 1; +    }      foreach my $entry (@parts) { -	my $part_info = Gtk2::Label->new($entry->{device_LABEL}); +	my $part_info = Gtk3::Label->new($entry->{device_LABEL});  	my @colorized_fs_types = qw(ext2 ext3 ext4 xfs swap vfat ntfs ntfs-3g); -        my $part_widget = Gtk2::EventBox->new; +        my $part_widget = Gtk3::EventBox->new;          $entry->{width} = int($entry->{size} * $initial_ratio) + $minwidth; -        if ($last && $last->{device} eq $entry->{device}) { -            #- entry is the last resizable partition - +        if ($resize && $entry->{selected_for_resize}) {              my $ratio;              my $update_ratio = sub { $ratio = $entry->{width} / $entry->{size} };              $update_ratio->(); @@ -321,38 +375,36 @@ sub create_display_box {              $part_widget->set_name("PART_vfat");              $part_info->set_size_request(ceil($ratio * $entry->{min_win}), 0); -            my $mdv_widget = gtkadd(gtkset_name(Gtk2::EventBox->new, "PART_new"), +            my $mdv_widget = gtkadd(gtkset_name(Gtk3::EventBox->new, "PART_new"),                                      gtkset_size_request(gtknew("Image", file => "small-logo"),                                                          $ratio * MB(600), 0)); -            my $hpane = Gtk2::HPaned->new; -            $hpane->add1($part_widget); -            $hpane->child1_shrink(0); -            $hpane->add2($mdv_widget); -            $hpane->child2_shrink(0); +            my $hpane = Gtk3::HPaned->new; +            $hpane->pack1($part_widget, 1, 0); +            $hpane->pack2($mdv_widget, 1, 0);              $hpane->set_position(ceil($ratio * $entry->{req_size})); -            ugtk2::gtkset_size_request($hpane, $entry->{width}, 0); -            ugtk2::gtkpack__($display_box, $hpane); +            ugtk3::gtkset_size_request($hpane, $entry->{width}, 0); +            ugtk3::gtkpack__($display_box, $hpane);              my $add_part_size_info = sub {                  my ($name, $label) = @_; -                ugtk2::gtkpack__($desc, -                                 gtkadd(gtkset_name(Gtk2::EventBox->new, $name), -                                        Gtk2::Label->new(" " x 4)), +                ugtk3::gtkpack__($desc, +                                 gtkadd(gtkset_name(Gtk3::EventBox->new, $name), +                                        Gtk3::Label->new(" " x 4)),                                   gtkset_size_request(gtkset_alignment($label, 0, 0.5),                                                       150, 20));              }; -            $desc = Gtk2::HBox->new(0,0); +            $desc = Gtk3::HBox->new(0,0); -            my $win_size_label = Gtk2::Label->new; +            my $win_size_label = Gtk3::Label->new;              $add_part_size_info->("PART_vfat", $win_size_label); -            my $mdv_size_label = Gtk2::Label->new; +            my $mdv_size_label = Gtk3::Label->new;              $add_part_size_info->("PART_new", $mdv_size_label);              my $update_size_labels = sub {                  $win_size_label->set_label(" Windows (" . formatXiB($entry->{req_size}, 512) . ")"); -                $mdv_size_label->set_label(" Mandriva (" . formatXiB($entry->{size} - $entry->{req_size}, 512) . ")"); +                $mdv_size_label->set_label(" Mageia (" . formatXiB($entry->{size} - $entry->{req_size}, 512) . ")");                  0;              };              my $update_req_size = sub { @@ -365,7 +417,7 @@ sub create_display_box {              };              $hpane->signal_connect('size-allocate' => sub {                  my (undef, $alloc) = @_; -                $entry->{width} = $alloc->width; +                $entry->{width} = $alloc->{width};                  $update_ratio->();                  0;              }); @@ -388,24 +440,19 @@ sub create_display_box {                                           'other'));              }              $part_widget->set_size_request($entry->{width}, 0); -            ugtk2::gtkpack($display_box, $part_widget); +            ugtk3::gtkpack($display_box, $part_widget);          }  	$part_widget->add($part_info); - -	$part_sep = gtkadd(Gtk2::EventBox->new, -                     gtkset_size_request(Gtk2::Label->new("."), 1, 0)); -	gtkpack__($display_box, $part_sep);      } -    $display_box->remove($part_sep) if $part_sep;      unless ($resize || $fill_empty) { -        my @types = (N_("Ext2/3/4"), N_("XFS"), N_("Swap"), arch() =~ /sparc/ ? N_("SunOS") : arch() eq "ppc" ? N_("HFS") : N_("Windows"), +        my @types = (N_("Ext2/3/4"), N_("XFS"), N_("Swap"), N_("Windows"),                      N_("Other"), N_("Empty"));          my %name2fs_type = ('Ext2/3/4' => 'ext3', 'XFS' => 'xfs', Swap => 'swap', Other => 'other', "Windows" => 'vfat', HFS => 'hfs'); -        $desc = ugtk2::gtkpack(Gtk2::HBox->new, +        $desc = ugtk3::gtkpack(Gtk3::HBox->new,                  map {                       my $t = $name2fs_type{$_}; -                     my $ev = Gtk2::EventBox->new; -		     my $w = Gtk2::Label->new(translate($_)); +                     my $ev = Gtk3::EventBox->new; +		     my $w = Gtk3::Label->new(translate($_));  	             $ev->add($w);  		     $ev->set_name('PART_' . ($t || 'empty'));                       $ev; @@ -423,20 +470,20 @@ sub display_choices {      my @solutions = sort { $solutions{$b}[0] <=> $solutions{$a}[0] } keys %solutions;      my @sol = grep { $solutions{$_}[0] >= 0 } @solutions; -    log::l(''  . "solutions found: " . join('', map { $solutions{$_}[1] } @sol) . -           " (all solutions found: " . join('', map { $solutions{$_}[1] } @solutions) . ")"); +    log::l(''  . "solutions found: " . join(', ', map { $solutions{$_}[1] } @sol) . +           " (all solutions found: " . join(', ', map { $solutions{$_}[1] } @solutions) . ")");      @solutions = @sol if @sol > 1;      log::l("solutions: ", int @solutions); -    @solutions or $o->ask_warn(N("Partitioning"), N("I can not find any room for installing")), die 'already displayed'; +    @solutions or $o->ask_warn(N("Partitioning"), N("I cannot find any room for installing")), die 'already displayed';      log::l('HERE: ', join(',', map { $solutions{$_}[1] } @solutions));      $contentbox->foreach(sub { $contentbox->remove($_[0]) });      $mainw->{kind}{display_box} ||= create_display_box($mainw->{kind}); -    ugtk2::gtkpack2__($contentbox, $mainw->{kind}{display_box}); -    ugtk2::gtkpack__($contentbox, gtknew('Label', +    ugtk3::gtkpack2__($contentbox, $mainw->{kind}{display_box}); +    ugtk3::gtkpack__($contentbox, gtknew('Label',                                           text => N("The DrakX Partitioning wizard found the following solutions:"),                                           alignment => [0, 0])); @@ -453,30 +500,30 @@ sub display_choices {              $item = create_display_box($mainw->{kind}, $solutions{$s}[3], undef, $button);          } elsif ($s eq 'existing_part') {          } elsif ($s eq 'wipe_drive') { -            $item = Gtk2::EventBox->new; +            $item = Gtk3::EventBox->new;              my $b2 = gtknew("Image", file => "small-logo");              $item->add($b2); -            $item->set_size_request(540,26); +            $item->set_size_request(520,26);              $item->set_name("PART_new");          } elsif ($s eq 'diskdrake') {          } else {              log::l($s);              next;          } -        ugtk2::gtkpack($vbox,  +        ugtk3::gtkpack($vbox,                          gtknew('Label',                                text => $solutions{$s}[1],                                alignment => [0, 0])); -        ugtk2::gtkpack($vbox, $item) if defined($item); -        $button->set_group($oldbutton->get_group) if $oldbutton; +        ugtk3::gtkpack($vbox, $item) if defined($item); +        $button->join_group($oldbutton) if $oldbutton;          $oldbutton = $button;          $button->signal_connect('toggled', sub { $mainw->{sol} = $solutions{$s} if $_[0]->get_active }); -        ugtk2::gtkpack2__($choicesbox, $button); +        ugtk3::gtkpack2__($choicesbox, $button);          $sep = gtknew('HSeparator'); -        ugtk2::gtkpack2__($choicesbox, $sep); +        ugtk3::gtkpack2__($choicesbox, $sep);      }      $choicesbox->remove($sep); -    ugtk2::gtkadd($contentbox, $choicesbox); +    ugtk3::gtkadd($contentbox, $choicesbox);      $mainw->{sol} = $solutions{@solutions[0]};  } @@ -486,30 +533,30 @@ sub main {      my $sol;      if ($o->isa('interactive::gtk')) { -        require mygtk2; -        mygtk2->import(qw(gtknew)); -        require ugtk2; -        ugtk2->import(qw(:wrappers)); +        require mygtk3; +        mygtk3->import(qw(gtknew)); +        require ugtk3; +        ugtk3->import(qw(:wrappers)); -        my $mainw = ugtk2->new(N("Partitioning"), %$o, if__($::main_window, transient => $::main_window)); +        my $mainw = ugtk3->new(N("Partitioning"), %$o, if__($::main_window, transient => $::main_window));          $mainw->{box_allow_grow} = 1; -        mygtk2::set_main_window_size($mainw->{rwindow}); +        mygtk3::set_main_window_size($mainw->{rwindow});          require diskdrake::hd_gtk;          diskdrake::hd_gtk::load_theme(); -        my $mainbox = Gtk2::VBox->new; +        my $mainbox = Gtk3::VBox->new; -        my @kinds = map { diskdrake::hd_gtk::hd2kind($_) } sort { $a->{is_removable} <=> $b->{is_removable} } @{$all_hds->{hds} }; -        push @kinds, map { diskdrake::hd_gtk::raid2kind($_) } @{$all_hds->{raids}}; +        my @kinds = map { diskdrake::hd_gtk::hd2kind($_) } sort { $a->{is_removable} <=> $b->{is_removable} } @{ $all_hds->{hds} }; +        #push @kinds, diskdrake::hd_gtk::raid2real_kind($_) foreach @{$all_hds->{raids}};          push @kinds, map { diskdrake::hd_gtk::lvm2kind($_) } @{$all_hds->{lvms}}; -        my $hdchoice = Gtk2::HBox->new; +        my $hdchoice = Gtk3::HBox->new; -        my $hdchoicelabel = Gtk2::Label->new(N("Here is the content of your disk drive ")); +        my $hdchoicelabel = Gtk3::Label->new(N("Here is the content of your disk drive ")); -        my $combobox = Gtk2::ComboBox->new_text; +        my $combobox = Gtk3::ComboBoxText->new;          foreach (@kinds) {              my $info = $_->{val}{info} || $_->{val}{device};              $info =~ s|^(?:.*/)?(.{24}).*|$1|; @@ -518,29 +565,31 @@ sub main {          }          $combobox->set_active(0); -        ugtk2::gtkpack2__($hdchoice, $hdchoicelabel); +        ugtk3::gtkpack2__($hdchoice, $hdchoicelabel);          $hdchoice->add($combobox); -        ugtk2::gtkpack2__($mainbox, $hdchoice); +        ugtk3::gtkpack2__($mainbox, $hdchoice); -        my $contentbox = Gtk2::VBox->new(0, 12); +        my $contentbox = Gtk3::VBox->new(0, 12); -        my $scroll = Gtk2::ScrolledWindow->new; -        $scroll->set_policy('never', 'automatic'), -        my $vp = Gtk2::Viewport->new; +        my $scroll = Gtk3::ScrolledWindow->new; +        $scroll->set_policy('automatic', 'automatic'), +        my $vp = Gtk3::Viewport->new;          $vp->set_shadow_type('none');          $vp->add($contentbox);          $scroll->add($vp);          $mainbox->add($scroll); -        my $kind = @kinds[$combobox->get_active]; +        my $kind = $kinds[$combobox->get_active];          my %solutions = partitionWizardSolutions($o, $all_hds, $fstab, $manual_fstab, $partitions, $partitioning_flags, $skip_mtab, diskdrake::hd_gtk::kind2hd($kind));          delete $solutions{diskdrake} if $b_nodiskdrake;          $mainw->{kind} = $kind;          display_choices($o, $contentbox, $mainw, %solutions);          $combobox->signal_connect("changed", sub {         -            $mainw->{kind} = @kinds[$combobox->get_active]; +            my $curr = $kinds[$combobox->get_active]; +            return if !$curr; +            $mainw->{kind} = $curr;              my %solutions = partitionWizardSolutions($o, $all_hds, $fstab, $manual_fstab, $partitions, $partitioning_flags, $skip_mtab, diskdrake::hd_gtk::kind2hd($mainw->{kind}));              delete $solutions{diskdrake} if $b_nodiskdrake;              display_choices($o, $contentbox, $mainw, %solutions); @@ -551,12 +600,12 @@ sub main {              if_($::isInstall,               [ gtknew('Install_Button',                       text => N("Help"), -                     clicked => sub { interactive::gtk::display_help($o, {interactive_help_id => 'doPartitionDisks' }, $mainw) }), +                     clicked => sub { interactive::gtk::display_help($o, {interactive_help_id => 'doPartitionDisks' }) }),                undef, 1 ]),              );          my $buttons_pack = $mainw->create_okcancel(N("Next"), undef, '', @more_buttons);          $mainbox->pack_end($buttons_pack, 0, 0, 0); -        ugtk2::gtkadd($mainw->{window}, $mainbox); +        ugtk3::gtkadd($mainw->{window}, $mainbox);          $mainw->{window}->show_all;          $mainw->main; @@ -570,11 +619,11 @@ sub main {          my @solutions = sort { $b->[0] <=> $a->[0] } values %solutions;          my @sol = grep { $_->[0] >= 0 } @solutions; -        log::l(''  . "solutions found: " . join('', map { $_->[1] } @sol) .  -               " (all solutions found: " . join('', map { $_->[1] } @solutions) . ")"); +        log::l(''  . "solutions found: " . join(', ', map { $_->[1] } @sol) .  +               " (all solutions found: " . join(', ', map { $_->[1] } @solutions) . ")");          @solutions = @sol if @sol > 1;          log::l("solutions: ", int @solutions); -        @solutions or $o->ask_warn(N("Partitioning"), N("I can not find any room for installing")), die 'already displayed'; +        @solutions or $o->ask_warn(N("Partitioning"), N("I cannot find any room for installing")), die 'already displayed';          log::l('HERE: ', join(',', map { $_->[1] } @solutions));          $o->ask_from_({               title => N("Partitioning"), @@ -591,6 +640,7 @@ sub main {          if ($err =~ /wizcancel/) {              $_->destroy foreach $::WizardTable->get_children;          } else { +            log::l("Partitioning failed: $err");              $o->ask_warn('', N("Partitioning failed: %s", formatError($err)));          }      } @@ -598,4 +648,8 @@ sub main {      1;  } +=back + +=cut +  1; diff --git a/perl-install/fs/proc_partitions.pm b/perl-install/fs/proc_partitions.pm index 566f9ee70..ea714ca5b 100644 --- a/perl-install/fs/proc_partitions.pm +++ b/perl-install/fs/proc_partitions.pm @@ -1,4 +1,4 @@ -package fs::proc_partitions; # $Id$ +package fs::proc_partitions;  use common; @@ -6,8 +6,12 @@ use common;  sub read_raw() {      my (undef, undef, @all) = cat_("/proc/partitions");      grep { -	$_->{size} != 1 &&	  # skip main extended partition -	$_->{size} != 0x3fffffff; # skip cdroms (otherwise stops cd-audios) +	$_->{size} != 1 &&	      # skip main extended partition +	$_->{size} != 0x3fffffff &&   # skip cdroms (otherwise stops cd-audios) +	$_->{dev} !~ /mmcblk\d+[^p]/; # only keep partitions like mmcblk0p0 +	                              # not mmcblk0rpmb or mmcblk0boot0 as they +				      # are not in the partition table and +				      # things will break (mga#15759)      } map {   	my %l;   	@l{qw(major minor size dev)} = split;  @@ -16,7 +20,7 @@ sub read_raw() {  }  sub read { -    my ($hds) = @_; +    my ($hds, $o_ignore_fstype) = @_;      my @all = read_raw();      my ($parts, $_disks) = partition { $_->{dev} =~ /\d$/ && $_->{dev} !~ /^(sr|scd)/ } @all; @@ -36,7 +40,7 @@ sub read {  	$part->{size} *= 2;	# from KB to sectors  	$part->{start} = $prev_part ? $prev_part->{start} + $prev_part->{size} : 0;  	require fs::type; -	put_in_hash($part, fs::type::type_subpart_from_magic($part)); +	put_in_hash($part, fs::type::type_subpart_from_magic($part)) if !$o_ignore_fstype;  	$prev_part = $part;  	delete $part->{dev}; # cleanup      } @@ -50,7 +54,7 @@ sub compare {      my @l1 = partition_table::get_normal_parts($hd); -    my @l2 = grep { $_->{rootDevice} eq $hd->{device} } &read([$hd]); +    my @l2 = grep { $_->{rootDevice} eq $hd->{device} } &read([$hd], 1);      #- /proc/partitions includes partition with type "empty" and a non-null size      #- so add them for comparison @@ -61,7 +65,7 @@ sub compare {  	    log::l("not using /proc/partitions because of the presence of solaris extended partition"); #- cf #33866  	} else {  	    die sprintf( -		    "/proc/partitions does not agree with drakx %d != %d:\n%s\n", $len1, $len2, +		    "/proc/partitions does not agree with drakx %d != %d for %s:\n%s\n", $len1, $len2, $hd->{device},  		    "/proc/partitions: " . join(", ", map { "$_->{device} ($_->{rootDevice})" } @l2));  	}      } diff --git a/perl-install/fs/remote.pm b/perl-install/fs/remote.pm index ea22a04af..ea5944a25 100644 --- a/perl-install/fs/remote.pm +++ b/perl-install/fs/remote.pm @@ -1,4 +1,4 @@ -package fs::remote; # $Id$ +package fs::remote;  use strict;  use diagnostics; diff --git a/perl-install/fs/remote/davfs.pm b/perl-install/fs/remote/davfs.pm index 5df0fe771..890530cb9 100644 --- a/perl-install/fs/remote/davfs.pm +++ b/perl-install/fs/remote/davfs.pm @@ -1,4 +1,4 @@ -package fs::remote::davfs; # $Id: smb.pm 231184 2007-10-24 14:36:29Z pixel $ +package fs::remote::davfs;  use strict;  use diagnostics; @@ -6,7 +6,7 @@ use diagnostics;  use common;  use fs::mount_options; -sub secrets_file { "$::prefix/etc/davfs2/secrets" } +sub secrets_file() { "$::prefix/etc/davfs2/secrets" }  sub fstab_entry_to_credentials {      my ($part) = @_;     @@ -14,7 +14,7 @@ sub fstab_entry_to_credentials {      my ($options, $unknown) = fs::mount_options::unpack($part);      my %h = map { $_ => delete $options->{"$_="} } qw(username password);      foreach (qw(username password)) { -        $h{$_} = 'nobody' if !$h{$_}; +        $h{$_} ||= 'nobody';      }      $h{mntpoint} = $part->{mntpoint} or return;      fs::mount_options::pack_($part, $options, $unknown), \%h; @@ -25,7 +25,7 @@ sub save_credentials {      @$credentials or return;      output_with_perm(secrets_file(), 0600,  -		     map { to_double_quoted($_->{mntpoint}, $_->{username}, $_->{password}, $_->{comment}) . "\n" } @$credentials); +		     map { to_double_quoted($_->{mntpoint}, $_->{username}, $_->{password}) . "\n" } @$credentials);  }  sub mountpoint_credentials_save { @@ -45,7 +45,7 @@ sub mountpoint_credentials_save {  } -sub read_credentials_raw { +sub read_credentials_raw() {      from_double_quoted(cat_(secrets_file()));  } @@ -66,12 +66,12 @@ sub from_double_quoted {      my ($file) = @_;      my @l;      my @lines = split("\n",$file); -    foreach (@lines){ +    foreach (@lines) {  	my ($mnt, $user, $pass, $comment);   	if (/^\s*(#.*)?$/) {  	    $comment = $1;  	} else { -            if(/^(?:"((?:\\.|[^"])*)"|((?:\\.|[^"\s#])+))\s+(?:"((?:\\.|[^"])*)"|((?:\\.|[^"\s#])+))(?:\s+(?:"((?:\\.|[^"])*)"|((?:\\.|[^"\s#])+)))?(?:\s*|\s*(#.*))?$/) { +            if (/^(?:"((?:\\.|[^"])*)"|((?:\\.|[^"\s#])+))\s+(?:"((?:\\.|[^"])*)"|((?:\\.|[^"\s#])+))(?:\s+(?:"((?:\\.|[^"])*)"|((?:\\.|[^"\s#])+)))?(?:\s*|\s*(#.*))?$/) {  	            $mnt = "$1$2";  		    $mnt =~ s/\\(.)/$1/g;  		    $user = "$3$4"; @@ -83,7 +83,7 @@ sub from_double_quoted {  		    die "bad entry $_";  	    }          } -        push @l, {'mntpoint'=>$mnt, 'username'=>$user, 'password'=>$pass, 'comment'=>$comment}; +        push @l, { 'mntpoint' => $mnt, 'username' => $user, 'password' => $pass, 'comment' => $comment };      }      @l;  } diff --git a/perl-install/fs/remote/nfs.pm b/perl-install/fs/remote/nfs.pm index 816c152a5..f7a98cb69 100644 --- a/perl-install/fs/remote/nfs.pm +++ b/perl-install/fs/remote/nfs.pm @@ -1,10 +1,11 @@ -package fs::remote::nfs; # $Id$ +package fs::remote::nfs;  use strict;  use diagnostics;  use common;  use fs::remote; +use network::tools;  use log;  our @ISA = 'fs::remote'; @@ -28,34 +29,36 @@ sub to_dev_raw {  sub check {      my ($_class, $in) = @_; -    $in->do_pkgs->ensure_binary_is_installed('nfs-utils-clients', 'showmount') or return; +    $in->do_pkgs->ensure_files_are_installed([ [ qw(nfs-utils showmount) ] , [ qw(nmap nmap) ] ]);      require services; -    services::start_not_running_service('portmap'); +    services::start_not_running_service('rpcbind');      services::start('nfs-common'); #- TODO: once nfs-common is fixed, it could use start_not_running_service()      1;  }  sub find_servers { -    open(my $F2, "rpcinfo-flushed -b mountd 2 |"); -    open(my $F3, "rpcinfo-flushed -b mountd 3 |"); - -    common::nonblock($F2); -    common::nonblock($F3); -    my $domain = chomp_(`domainname`); -    my ($s, %servers); -    my $quit; -    while (!$quit) { -	$quit = 1; -	sleep 1; -	while ($s = <$F2> || <$F3>) { -	    $quit = 0; -	    my ($ip, $name) = $s =~ /(\S+)\s+(\S+)/ or log::explanations("bad line in rpcinfo output"), next; -	    $name =~ s/\.$//; -	    $domain && $name =~ s/\Q.$domain\E$// -	      || $name =~ s/^([^.]*)\.local$/$1/; -	    $servers{$ip} ||= { ip => $ip, if_($name ne '(unknown)', name => $name) }; +    my @hosts; +    my %servers; +    my @routes = cat_("/proc/net/route"); +    @routes = reverse(@routes) if common::cmp_kernel_versions(c::kernel_version(), "2.6.39") >= 0; +    foreach (@routes) { +	if (/^(\S+)\s+([0-9A-F]+)\s+([0-9A-F]+)\s+[0-9A-F]+\s+\d+\s+\d+\s+(\d+)\s+([0-9A-F]+)/) { +	    my $net = network::tools::host_hex_to_dotted($2); +	    my $gateway = $3; +	    # get the netmask in binary and remove leading zeros +	    my $mask = unpack('B*', pack('h*', $5)); +	    $mask =~ s/^0*//; +	    push @hosts, $net . "/" . length($mask) if $gateway eq '00000000' && $net ne '169.254.0.0';  	} +     } +    # runs the nmap command on the local subnet +    my $cmd = "/usr/bin/nmap -p 111 --open --system-dns -oG - " . (join ' ',@hosts); +    open my $FH, "$cmd |" or die "Could not perform nmap scan - $!"; +    foreach (<$FH>) {  +      my ($ip, $name) = /^H\S+\s(\S+)\s+\((\S*)\).+Port/ or next; +      $servers{$ip} ||= { ip => $ip, name => $name || $ip };      } +    close $FH;      values %servers;  } diff --git a/perl-install/fs/remote/smb.pm b/perl-install/fs/remote/smb.pm index acdf0d7cf..d440fc174 100644 --- a/perl-install/fs/remote/smb.pm +++ b/perl-install/fs/remote/smb.pm @@ -1,4 +1,4 @@ -package fs::remote::smb; # $Id$ +package fs::remote::smb;  use strict;  use diagnostics; diff --git a/perl-install/fs/type.pm b/perl-install/fs/type.pm index 5ff8210f3..141d5b5e2 100644 --- a/perl-install/fs/type.pm +++ b/perl-install/fs/type.pm @@ -1,4 +1,4 @@ -package fs::type; # $Id$ +package fs::type;  use diagnostics;  use strict; @@ -6,10 +6,19 @@ use strict;  use common;  use devices; +=head1 SYNOPSYS + +B<fs::type> enables to perform various tests on filesystem types. + +=head1 Functions + +=over + +=cut  our @ISA = qw(Exporter);  our @EXPORT = qw( -   isEmpty isExtended isTrueLocalFS isTrueFS isDos isSwap isOtherAvailableFS isRawLVM isRawRAID isRawLUKS isRAID isLVM isLUKS isMountableRW isNonMountable isPartOfLVM isPartOfRAID isPartOfLoopback isLoopback isMounted isBusy isSpecial isApple isAppleBootstrap isWholedisk isFat_or_NTFS isRecovery +   isBlockCheckable isEmpty isExtended isFormatable isTrueLocalFS isTrueFS isDos isSwap isOtherAvailableFS isRawLVM isRawRAID isRawLUKS isRAID isLVM isLUKS isMountableRW isNonMountable isPartOfLVM isPartOfRAID isPartOfLoopback isLoopback isMounted isBusy isSpecial isApple isAppleBootstrap isBIOS_GRUB isESP isFat_or_NTFS isnormal_Fat_or_NTFS isRecovery     maybeFormatted set_isFormatted defaultFS  ); @@ -23,22 +32,19 @@ my (%type_name2pt_type, %type_name2fs_type, %fs_type2pt_type, %pt_type2fs_type,    0x83 => 'ext2',     'Linux native',    0x83 => 'ext3',     'Journalised FS: ext3',    0x83 => 'ext4',     'Journalised FS: ext4', -  0x83 => 'reiserfs', 'Journalised FS: ReiserFS', -if_(arch() =~ /ppc|i.86|ia64|x86_64/,  -  0x83 => 'xfs',      'Journalised FS: XFS', +  0x83 => 'btrfs',    'Journalised FS: Btrfs', +(is_uefi() ? +  (0xef => 'vfat',     'EFI System Partition') : +  ('BIOS_GRUB' => 'BIOS_GRUB',  'BIOS boot or Empty partition')  ), -if_(arch() =~ /ppc|i.86|x86_64/,  +if_(arch() =~ /i.86|x86_64/, +  0x83 => 'xfs',      'Journalised FS: XFS',    0x83 => 'jfs',      'Journalised FS: JFS', -), -if_(arch() =~ /i.86|ia64|x86_64/,    0x0b => 'vfat',     'FAT32',    0x07 => 'ntfs-3g',  'NTFS-3G',    0x07 => 'ntfs',     'NTFS', -), -if_(arch() =~ /ppc/, -  0x401	=> '',         'Apple Bootstrap', -  0x402	=> 'hfs',      'Apple HFS Partition', -  0x41  => '',         'PPC PReP Boot', +  0x07 => 'ntfs3',    'NTFS3', +  0x07 => 'exfat',    'exFAT',  ),  	], @@ -56,20 +62,7 @@ if_(arch() =~ /ppc/,  	],  	other => [ - if_(arch() =~ /^ia64/, -  0x100 => '',         'Various', -), if_(arch() =~ /^ppc/, -  0x401	=> 'apple',    'Apple Partition', -), if_(arch() =~ /^sparc/, -  0x01 => 'ufs',      'SunOS boot', -  0x02 => 'ufs',      'SunOS root', -  0x03 => '',      'SunOS swap', -  0x04 => 'ufs',      'SunOS usr', -  0x05 => '',      'Whole disk', -  0x06 => 'ufs',      'SunOS stand', -  0x07 => 'ufs',      'SunOS var', -  0x08 => 'ufs',      'SunOS home', -), if_(arch() =~ /^i.86|x86_64/, + if_(arch() =~ /^i.86|x86_64/,    0x01 => 'vfat',     'FAT12',    0x02 => '',         'XENIX root',    0x03 => '',         'XENIX usr', @@ -96,9 +89,7 @@ if_(arch() =~ /ppc/,    0x39 => '',         'Plan 9',    0x3c => '',         'PartitionMagic recovery',    0x40 => '',         'Venix 80286', -if_(arch() !~ /ppc/,    0x41 => '',         'PPC PReP Boot', -),    0x42 => '',         'SFS',    0x4d => '',         'QNX4.x',    0x4e => '',         'QNX4.x 2nd part', @@ -119,11 +110,9 @@ if_(arch() !~ /ppc/,    0x75 => '',         'PC/IX',    0x80 => '',         'Old Minix',    0x81 => '',         'Minix / old Linux', - if_(!$::isInstall, -  0x83 => 'reiser4',  'Journalised FS: Reiser4', -  0x83 => 'nilfs2',   'NILFS2', - ), -  0x83 => 'btrfs',    'Btrfs', +  0x83 => 'f2fs',     'Journalised FS: F2FS', +  0x83 => 'reiserfs', 'Journalised FS: ReiserFS', +  0x83 => 'nilfs2',   'Journalised FS: NILFS2',    0x84 => '',         'OS/2 hidden C: drive',    0x86 => '',         'NTFS volume set (0x86)',    0x87 => '',         'NTFS volume set (0x87)', @@ -155,7 +144,6 @@ if_(arch() !~ /ppc/,    0xe4 => '',         'SpeedStor (FAT-16)',    0xeb => 'befs',     'BeOS fs',    0xee => '',         'EFI GPT', -  0xef => 'vfat',     'EFI (FAT-12/16/32)',    0xf0 => '',         'Linux/PA-RISC boot',    0xf4 => '',         'SpeedStor (large part.)',    0xf2 => '',         'DOS secondary', @@ -187,10 +175,10 @@ sub type_names {      my @l = @{$type_names{important}};      push @l, grep { $_ ne 'Encrypted' } @{$type_names{non_fs_type}};      push @l, sort @{$type_names{other}} if $expert; -    if ($o_hd && !$o_hd->use_pt_type) { -	warn "$_ => $type_name2fs_type{$_}\n" foreach @l; +    # not show partition types which have no associated filesystem for LVM LV: +    if ($o_hd && isLVM($o_hd)) {  	@l = grep { $type_name2fs_type{$_} } @l; -	@l = uniq_ { $type_name2fs_type{$_[0]} } @l; +	@l = uniq_ { $type_name2fs_type{$_} } @l;  	(@l, @{$type_names{non_fs_type}});      } else {  	@l; @@ -275,9 +263,10 @@ sub fs_type_from_magic {  sub call_blkid {      my ($part) = @_; +    # IMPORTANT: Always use the -p argument with blkid. See r7324 commit msg      my %h = map {  	if_(/(.*?)=(.*)/, $1 => $2); -    } run_program::get_stdout('blkid', '2>', '/dev/null', '-o', 'udev', '-p', devices::make($part->{device})); +    } run_program::get_stdout_raw({ timeout => 30 }, 'blkid', '2>', '/dev/null', '-o', 'udev', '-p', devices::make($part->{device}));      \%h;  } @@ -303,6 +292,7 @@ sub type_subpart_from_magic {      }      if ($p) { +	$p->{fs_type} = '' if $part->{pt_type} eq 'BIOS_GRUB' && $p->{fs_type} ne 'iso9660';  	$part->{fs_type_from_magic} = $p->{fs_type};  	$p->{device_LABEL} = $ids->{ID_FS_LABEL} if $ids->{ID_FS_LABEL};  	$p->{device_UUID} = $ids->{ID_FS_UUID} if $ids->{ID_FS_UUID}; @@ -311,40 +301,78 @@ sub type_subpart_from_magic {      $p;  } -sub defaultFS { 'ext4' } +# helpers +sub defaultFS() { 'ext4' } +sub true_local_fs_types() { qw(btrfs ext3 ext2 ext4 f2fs reiserfs xfs jfs) } -sub true_local_fs_types() { qw(btrfs ext3 ext2 ext4 reiserfs reiser4 xfs jfs) } - -sub isEmpty { !$_[0]{fs_type} && $_[0]{pt_type} == 0 } -sub isEfi { arch() =~ /ia64/ && $_[0]{pt_type} == 0xef } -sub isWholedisk { arch() =~ /^sparc/ && $_[0]{pt_type} == 5 } -sub isExtended { arch() !~ /^sparc/ && ($_[0]{pt_type} == 5 || $_[0]{pt_type} == 0xf || $_[0]{pt_type} == 0x85) } +sub isEmpty { !$_[0]{fs_type} && !$_[0]{pt_type} } +sub isBIOS_GRUB { $_[0]{pt_type} eq 'BIOS_GRUB' } +sub isESP { $_[0]{pt_type} == 0xef && member($_[0]{fs_type}, qw(fat32 vfat)) } +sub isExtended { $_[0]{pt_type} == 5 || $_[0]{pt_type} == 0xf || $_[0]{pt_type} == 0x85 } +sub isBlockCheckable { !member($_[0]{fs_type}, qw(btrfs hfs ntfs ntfs-3g reiserfs xfs)) }  sub isRawLVM { $_[0]{pt_type} == 0x8e || $_[0]{type_name} eq 'Linux Logical Volume Manager' }  sub isRawRAID { $_[0]{pt_type} == 0xfd || $_[0]{type_name} eq 'Linux RAID' }  sub isRawLUKS { $_[0]{type_name} eq 'Encrypted' }  sub isSwap { $_[0]{fs_type} eq 'swap' } -sub isDos { arch() !~ /^sparc/ && ${{ 1 => 1, 4 => 1, 6 => 1 }}{$_[0]{pt_type}} } -sub isFat_or_NTFS { member($_[0]{fs_type}, 'vfat', 'ntfs', 'ntfs-3g') } +sub isDos { ${{ 1 => 1, 4 => 1, 6 => 1 }}{$_[0]{pt_type}} } +sub isFat_or_NTFS { member($_[0]{fs_type}, qw(vfat ntfs ntfs3 ntfs-3g)) } +sub isnormal_Fat_or_NTFS { grep { isFat_or_NTFS($_) && !isESP($_) && !isRecovery($_) } @_ }  sub isApple { $_[0]{pt_type} == 0x401 && defined $_[0]{isDriver} }  sub isAppleBootstrap { $_[0]{pt_type} == 0x401 && defined $_[0]{isBoot} }  sub isRecovery {       isFat_or_NTFS($_[0]) && ($_[0]{type_name} =~ /^Hidden/ || +      $_[0]{pt_type} == 0x12 || # "Compaq diagnostics"          member($_[0]{device_LABEL} ,  -            # Extracted from /usr/share/hal/fdi/policy/10osvendor/20-storage-methods.fdi -            # Hopefuly we'll ask to hal/udev someday -            'RECOVERY', 'PQSERVICE', 'HP_RECOVERY', 'Recovery Partition', 'DellUtility', 'DellRestore', 'IBM_SERVICE', 'SERVICEV001', 'SERVICEV002') -    ) +            # Extracted from /usr/lib/udev/rules.d/80-udisks2.rules +            # Hopefuly we'll ask to udev/udisk2 someday +            # generated by grep Recovery /usr/lib/udev/rules.d/80-udisks2.rules : +            qw(Recovery RECOVERY Lenovo_Recovery HP_RECOVERY Recovery_Partition DellUtility DellRestore IBM_SERVICE SERVICEV001 SERVICEV002 SYSTEM_RESERVED System_Reserved WINRE_DRV DIAGS IntelRST), +            # gathered over the years (Hald, mga#1371, mga#15999): +            qw(PQSERVICE Packard_Bell Push_Button_Reset SYSTEM_DRV)) +    );  } -sub isTrueFS { isTrueLocalFS($_[0]) || member($_[0]{fs_type}, qw(nfs)) } +=item isTrueLocalFS($part) + +Like isTrueFS(), to make a distinction between ext3/reiserfs/... and NFS + => allow /home on NFS + +=cut + +sub isTrueFS { isTrueLocalFS($_[0]) || $_[0]{fs_type} eq 'nfs' } + +=item isTrueFS($part) + +Is is a general purpose file system with the right Unix properties + +=cut +  sub isTrueLocalFS { member($_[0]{fs_type}, true_local_fs_types()) } -sub isOtherAvailableFS { isEfi($_[0]) || isFat_or_NTFS($_[0]) || member($_[0]{fs_type}, 'ufs', 'hfs', 'iso9660') } #- other OS that linux can access its filesystem +=item isOtherAvailableFS($part) + +Is it another OS that linux can access its filesystem + +=cut + +sub isOtherAvailableFS { isESP($_[0]) || isFat_or_NTFS($_[0]) || member($_[0]{fs_type}, 'ufs', 'hfs', 'iso9660', 'nilfs2', 'exfat') }  sub isMountableRW { (isTrueFS($_[0]) || isOtherAvailableFS($_[0])) && $_[0]{fs_type} ne 'ntfs' }  sub cannotBeMountable {       my ($part) = @_; -    isRawRAID($part) || isRawLUKS($part) || isRawLVM($part); +    isRawRAID($part) || isRawLUKS($part) || isRawLVM($part) || isBIOS_GRUB($part); +} + +=item isFormatable($part) + +Is not a special sg that cannot be mounted/formatted (parts of RAID/LVM, BIOS_GRUB). Basically the reverse of cannotBeMountable(). + +=cut + +sub isFormatable { +    my ($part) = @_; +    !cannotBeMountable($part);  } +  sub isNonMountable {       my ($part) = @_;      cannotBeMountable($part) || $part->{fs_type} eq 'ntfs' && !$part->{isFormatted} && $part->{notFormatted}; @@ -362,7 +390,12 @@ sub isMounted { $_[0]{isMounted} }  sub isBusy { isMounted($_[0]) || isPartOfRAID($_[0]) || isPartOfLVM($_[0]) || $_[0]{dm_active} || isPartOfLoopback($_[0]) }  sub isSpecial { isRAID($_[0]) || isLVM($_[0]) || isLoopback($_[0]) || isUBD($_[0]) } -#- not for partitions, but for hds: +=item is_dmraid($hd) + +Check that a disk (not a partition) is in a fake/soft RAID + +=cut +  sub is_dmraid { $_[0]{bus} =~ /^dmraid_/ }  sub can_be_this_fs_type { @@ -387,24 +420,37 @@ sub set_isFormatted {      delete $part->{fs_type_from_magic};  } -#- do this before modifying $part->{fs_type} +=item check($fs_type, $_hd, $part) + +Called before before modifying $part->{fs_type} + +=cut +  sub check {      my ($fs_type, $_hd, $part) = @_; -    $fs_type eq "jfs" && $part->{size} < MB(16) and die N("You can not use JFS for partitions smaller than 16MB"); -    $fs_type eq "reiserfs" && $part->{size} < MB(32) and die N("You can not use ReiserFS for partitions smaller than 32MB"); +    $fs_type eq "jfs" && $part->{size} < MB(16) and die N("You cannot use JFS for partitions smaller than 16MB"); +    $fs_type eq "reiserfs" && $part->{size} < MB(32) and die N("You cannot use ReiserFS for partitions smaller than 32MB"); +    $fs_type eq "btrfs" && $part->{size} < MB(256) and die N("You cannot use btrfs for partitions smaller than 256MB");  }  sub guessed_by_mount() {      grep { $_ && !/nodev/ } chomp_(cat_('/etc/filesystems'));  } -sub directories_needed_to_boot() {  +sub directories_needed_to_boot_not_ESP() {      qw(/ /usr /var /boot /tmp);  } +sub directories_needed_to_boot() {  +    directories_needed_to_boot_not_ESP(), '/boot/EFI'; +}  sub carry_root_loopback {      my ($part) = @_;      any { $_->{mntpoint} eq '/' } @{$part->{loopback} || []};  } +=back + +=cut +  1; diff --git a/perl-install/fs/wild_device.pm b/perl-install/fs/wild_device.pm index 37818ce5a..ff5a32253 100644 --- a/perl-install/fs/wild_device.pm +++ b/perl-install/fs/wild_device.pm @@ -1,8 +1,8 @@ -package fs::wild_device; # $Id$ +package fs::wild_device;  use diagnostics;  use strict; - +use devices;  use common; @@ -11,13 +11,13 @@ sub analyze {      if ($dev =~ m!^/u?dev/(.*)!) {  	'dev', $dev; -    } elsif ($dev !~ m!^/! && (-e "/dev/$dev" || -e "$::prefix/dev/$dev")) { +    } elsif ($dev !~ m!^/! && (-e "/dev/$dev" || -e "/dev/$dev")) {  	'dev', "/dev/$dev";      } elsif ($dev =~ /^LABEL=(.*)/) {  	'label', $1;      } elsif ($dev =~ /^UUID=(.*)/) {  	'uuid', $1; -    } elsif ($dev eq 'none' || $dev eq 'rootfs') { +    } elsif (member($dev, qw(none rootfs))) {  	'virtual';      } elsif ($dev =~ m!^(\S+):/(\w|$)!) {  	'nfs'; @@ -40,11 +40,11 @@ sub to_subpart {  	    $part->{device_UUID} = $val;  	} elsif ($kind eq 'dev') {  	    my %part = (faked_device => 0); -	    if (my $rdev = (stat "$::prefix$dev")[6]) { +	    if (my $rdev = (stat "$dev")[6]) {  		($part{major}, $part{minor}) = unmakedev($rdev);  	    } -	    my $symlink = readlink("$::prefix$dev") unless $dev =~ m!mapper/!; +	    my $symlink = $dev !~ m!mapper/! ? readlink("$dev") : undef;  	    $dev =~ s!/u?dev/!!;  	    if ($symlink && $symlink !~ m!^/!) { @@ -67,7 +67,7 @@ sub to_subpart {  	    return \%part;  	}      } else { -	if ($dev =~ m!^/! && -f "$::prefix$dev") { +	if ($dev =~ m!^/! && -f "$dev") {  	    #- it must be a loopback file or directory to bind  	} else {  	    log::l("part_from_wild_device_name: unknown device $dev"); | 
