summaryrefslogtreecommitdiffstats
path: root/perl-install/fs
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/fs')
-rw-r--r--perl-install/fs/any.pm85
-rw-r--r--perl-install/fs/dmcrypt.pm83
-rw-r--r--perl-install/fs/dmraid.pm91
-rw-r--r--perl-install/fs/format.pm197
-rw-r--r--perl-install/fs/get.pm35
-rw-r--r--perl-install/fs/loopback.pm2
-rw-r--r--perl-install/fs/mount.pm14
-rw-r--r--perl-install/fs/mount_options.pm12
-rw-r--r--perl-install/fs/mount_point.pm29
-rw-r--r--perl-install/fs/partitioning.pm8
-rw-r--r--perl-install/fs/partitioning_wizard.pm258
-rw-r--r--perl-install/fs/proc_partitions.pm18
-rw-r--r--perl-install/fs/remote.pm2
-rw-r--r--perl-install/fs/remote/davfs.pm16
-rw-r--r--perl-install/fs/remote/nfs.pm45
-rw-r--r--perl-install/fs/remote/smb.pm2
-rw-r--r--perl-install/fs/type.pm161
-rw-r--r--perl-install/fs/wild_device.pm14
18 files changed, 749 insertions, 323 deletions
diff --git a/perl-install/fs/any.pm b/perl-install/fs/any.pm
index 65ca02403..ce4de2ca3 100644
--- a/perl-install/fs/any.pm
+++ b/perl-install/fs/any.pm
@@ -1,11 +1,15 @@
-package fs::any; # $Id: any.pm 269745 2010-06-02 11:21:42Z pterjan $
+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 a226bcbc7..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', 'xts', '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 {
@@ -67,7 +107,7 @@ sub format_part {
common::with_private_tmp_file($tmp_key_file, $part->{dmcrypt_key}, sub {
_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 {
@@ -80,9 +120,15 @@ sub open_part {
});
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}");
@@ -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 a744f01af..7a279abc7 100644
--- a/perl-install/fs/dmraid.pm
+++ b/perl-install/fs/dmraid.pm
@@ -1,4 +1,4 @@
-package fs::dmraid; # $Id: dmraid.pm 265309 2010-01-27 00:28:23Z pterjan $
+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 de444c694..1fa90c29e 100644
--- a/perl-install/fs/format.pm
+++ b/perl-install/fs/format.pm
@@ -1,4 +1,4 @@
-package fs::format; # $Id: format.pm 268842 2010-05-17 06:54:44Z pterjan $
+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' ],
+ dos => [ 'dosfstools', 'mkfs.fat' ],
+ vfat => [ 'dosfstools', 'mkfs.fat', '-F', '32' ],
+ exfat => [ 'exfatprogs', 'mkfs.exfat' ],
swap => [ 'util-linux', 'mkswap' ],
- ntfs => [ 'ntfsprogs', 'mkntfs', '--fast' ],
- 'ntfs-3g' => [ 'ntfsprogs', 'mkntfs', '--fast' ],
- btrfs => [ 'btrfs-progs', 'mkfs.btrfs' ],
- nilfs2 => [ 'nilfs-utils', 'mkfs.nilfs2' ],
+ 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 ],
@@ -46,34 +73,63 @@ my %LABELs = ( #- option, length, handled_by_mount
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', 'swaplabel', '-L' ],
- ntfs => [ 'ntfsprogs', 'ntfslabel' ],
- 'ntfs-3g' => [ 'ntfsprogs', 'ntfslabel' ],
- btrfs => [ 'btrfs-progs', 'btrfs', 'filesystem', 'label' ],
- nilfs2 => [ 'nilfs-utils', 'nilfs-tune', '-L' ],
+ ntfs => [ 'ntfs-3g', 'ntfslabel' ],
+ 'ntfs-3g' => [ 'ntfs-3g', 'ntfslabel' ],
+ btrfs => [ 'btrfs-progs', 'btrfs', 'filesystem', 'label' ],
+ nilfs2 => [ 'nilfs-utils', 'nilfs-tune', '-L' ],
);
-# Preserve UUID on fs where we couldn't enforce it while formatting
-my %preserve_UUID = ( # package, commande
- #btrfs => [ 'btrfs-progs', 'FIXME' ],
+=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;
@@ -104,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)) {
@@ -117,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) = @_;
@@ -146,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) = @_;
@@ -172,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};
}
@@ -195,10 +289,8 @@ sub part_raw {
delete $part->{device_LABEL_changed};
- # Preserve UUID on fs where we couldn't enforce it while formatting
- my ($_pkg, $cmd) = @{$preserve_UUID{$fs_type}};
- run_program::raw($cmd, '-U', devices::make($dev)) if $cmd;
-
+ preserve_UUID_after_format($dev, $part, $fs_type);
+
if (member($fs_type, qw(ext3 ext4))) {
disable_forced_fsck($dev);
}
@@ -206,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) = @_;
@@ -215,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) = @_;
@@ -231,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));
@@ -241,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");
@@ -302,5 +428,8 @@ sub formatMount_all {
};
}
+=back
+
+=cut
1;
diff --git a/perl-install/fs/get.pm b/perl-install/fs/get.pm
index 461984431..00c807738 100644
--- a/perl-install/fs/get.pm
+++ b/perl-install/fs/get.pm
@@ -1,4 +1,4 @@
-package fs::get; # $Id: get.pm 245972 2008-09-18 17:00:11Z pixel $
+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);
@@ -156,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 8620e6068..8d0c729ec 100644
--- a/perl-install/fs/loopback.pm
+++ b/perl-install/fs/loopback.pm
@@ -1,4 +1,4 @@
-package fs::loopback; # $Id: loopback.pm 212860 2005-06-28 09:12:16Z prigaux $
+package fs::loopback;
use diagnostics;
use strict;
diff --git a/perl-install/fs/mount.pm b/perl-install/fs/mount.pm
index 4365c0caa..6afaa9260 100644
--- a/perl-install/fs/mount.pm
+++ b/perl-install/fs/mount.pm
@@ -1,4 +1,4 @@
-package fs::mount; # $Id: mount.pm 267516 2010-04-12 16:40:47Z pterjan $
+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 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);
}
@@ -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 bae101679..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: mount_options.pm 268841 2010-05-17 06:52:12Z pterjan $
+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;
}
@@ -186,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';
}
@@ -207,7 +207,7 @@ sub set_default {
#- 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, {
@@ -224,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 8dc4521ae..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: mount_point.pm 269270 2010-05-24 09:55:20Z pterjan $
+package fs::mount_point;
use diagnostics;
use strict;
@@ -24,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);
}
@@ -43,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 015a7e4e8..18fa7e114 100644
--- a/perl-install/fs/partitioning.pm
+++ b/perl-install/fs/partitioning.pm
@@ -1,16 +1,18 @@
-package fs::partitioning; # $Id: partitioning.pm 243679 2008-07-29 11:55:58Z tv $
+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)
@@ -52,7 +54,7 @@ sub choose_partitions_to_format {
({
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 97e7472f5..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: partitioning_wizard.pm 269969 2010-06-09 13:01:09Z pterjan $
+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,7 +75,7 @@ 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.
To accomplish this, create a partition (or click on an existing one).
@@ -58,22 +85,30 @@ 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);
@@ -146,12 +182,12 @@ sub partitionWizardSolutions {
$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});
@@ -171,7 +207,13 @@ sub partitionWizardSolutions {
}, \&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 %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 ];
}
@@ -238,13 +280,16 @@ filesystem checks will be run on your next boot into Microsoft Windows®")) if $
},
\&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;
@@ -285,35 +326,48 @@ sub warn_reboot_needed {
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 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,33 +375,31 @@ 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 {
@@ -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,8 +470,8 @@ 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);
@@ -435,8 +482,8 @@ sub display_choices {
$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,8 +619,8 @@ 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 cannot find any room for installing")), die 'already displayed';
@@ -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 8a1bc8ab0..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: proc_partitions.pm 232285 2007-12-03 16:41:16Z pixel $
+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 efc630d4c..ea5944a25 100644
--- a/perl-install/fs/remote.pm
+++ b/perl-install/fs/remote.pm
@@ -1,4 +1,4 @@
-package fs::remote; # $Id: remote.pm 215411 2007-04-25 12:26:16Z pixel $
+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 7ebda3b11..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: nfs.pm 254157 2009-03-17 16:13:42Z eugeni $
+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 616636807..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: smb.pm 258615 2009-07-27 06:26:03Z pterjan $
+package fs::remote::smb;
use strict;
use diagnostics;
diff --git a/perl-install/fs/type.pm b/perl-install/fs/type.pm
index 12db643bc..141d5b5e2 100644
--- a/perl-install/fs/type.pm
+++ b/perl-install/fs/type.pm
@@ -1,4 +1,4 @@
-package fs::type; # $Id: type.pm 269283 2010-05-24 15:31:58Z pterjan $
+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,9 +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) {
+ # 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;
@@ -274,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;
}
@@ -302,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};
@@ -310,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};
@@ -361,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 {
@@ -386,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 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 efb48d9d7..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: wild_device.pm 268572 2010-05-11 16:42:46Z pterjan $
+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");