summaryrefslogtreecommitdiffstats
path: root/perl-install/diskdrake/interactive.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/diskdrake/interactive.pm')
-rw-r--r--perl-install/diskdrake/interactive.pm194
1 files changed, 103 insertions, 91 deletions
diff --git a/perl-install/diskdrake/interactive.pm b/perl-install/diskdrake/interactive.pm
index ca0cbef66..10b041053 100644
--- a/perl-install/diskdrake/interactive.pm
+++ b/perl-install/diskdrake/interactive.pm
@@ -1,4 +1,4 @@
-package diskdrake::interactive; # $Id: interactive.pm 269771 2010-06-03 11:50:24Z pterjan $
+package diskdrake::interactive;
use diagnostics;
use strict;
@@ -21,18 +21,16 @@ use any;
use log;
-=begin
-
=head1 SYNOPSYS
-struct part {
+ struct part {
int active # one of { 0 | 0x80 } x86 only, primary only
int start # in sectors
int size # in sectors
int pt_type # 0x82, 0x83, 0x6 ...
string fs_type # 'ext2', 'nfs', ...
string type_name # 'Linux RAID', 'Linux Logical Volume Manager', ...
-
+
int part_number # 1 for hda1...
string device # 'hda5', 'sdc1' ...
string device_LABEL # volume label. LABEL=xxx or /dev/disk/by-label/xxx can be used in fstab instead of the device
@@ -42,7 +40,7 @@ struct part {
bool prefer_device # should the {device} be used in fstab
bool faked_device # false if {device} is a real device, true for nfs/smb/dav/none devices. If the field does not exist, we do not know
bool device_LABEL_changed # true if device_LABEL is different from the one on the disk
-
+
string rootDevice # 'sda', 'hdc' ... (can also be a VG_name)
string real_mntpoint # directly on real /, '/tmp/hdimage' ...
string mntpoint # '/', '/usr' ...
@@ -51,32 +49,32 @@ struct part {
string encrypt_key # [0-9A-Za-z./]{20,}
string comment # comment to have in fstab
string volume_label #
-
+
bool is_removable # is the partition on a removable drive
bool isMounted
-
+
bool isFormatted
bool notFormatted
# isFormatted means the device is formatted
# !isFormatted && notFormatted means the device is not formatted
# !isFormatted && !notFormatted means we do not know which state we're in
-
+
string raid # for partitions of type isRawRAID and which isPartOfRAID, the raid device
string lvm # partition used as a PV for the VG with {lvm} as VG_name #-#
loopback loopback[] # loopback living on this partition
-
+
string dmcrypt_key
string dm_name
bool dm_active
-
+
# internal
string real_device # '/dev/loop0', '/dev/loop1' ... (used for encrypted loopback)
-
+
# internal CHS (Cylinder/Head/Sector)
int start_cyl, start_head, start_sec, end_cyl, end_head, end_sec,
}
-struct part_allocate inherits part {
+ struct part_allocate inherits part {
int maxsize # in sectors (alike "size")
int min_hd_size # in sectors (do not allocate if the drive is smaller than the given size)
int ratio #
@@ -84,44 +82,44 @@ struct part_allocate inherits part {
string parts # for creating raid partitions. eg: 'foo bar' where 'foo' and 'bar' are mntpoint
}
-struct part_raid inherits part {
+ struct part_raid inherits part {
string chunk-size # in KiB, usually '64'
string level # one of { 0, 1, 4, 5, 'linear' }
string UUID
-
+
part disks[]
-
+
# invalid: active, start, rootDevice, device_windobe?, CHS
}
-struct part_dmcrypt inherits part {
+ struct part_dmcrypt inherits part {
string dmcrypt_name
-
+
# rootDevice is special here: it is the device hosting the dm
}
-struct part_loopback inherits part {
+ struct part_loopback inherits part {
string loopback_file # absolute file name which is relative to the partition
part loopback_device # where the loopback file live
-
+
# device is special here: it is the absolute filename of the loopback file.
-
+
# invalid: active, start, rootDevice, device_windobe, CHS
}
-struct part_lvm inherits part {
+ struct part_lvm inherits part {
# invalid: active, start, device_windobe, CHS
string lv_name
}
-struct partition_table_elem {
+ struct partition_table_elem {
part normal[] #
part extended # the main/next extended
part raw[4] # primary partitions
}
-struct geom {
+ struct geom {
int heads
int sectors
int cylinders
@@ -129,14 +127,14 @@ struct geom {
int start # always 0, forget it
}
-struct hd {
+ struct hd {
int totalsectors # size in sectors
string device # 'hda', 'sdc' ...
string device_alias # 'cdrom', 'floppy' ...
string media_type # one of { 'hd', 'cdrom', 'fd', 'tape' }
string capacity # contain of the strings of { 'burner', 'DVD' }
string info # name of the hd, eg: 'QUANTUM ATLAS IV 9 WLS'
-
+
bool readonly # is it allowed to modify the partition table
bool getting_rid_of_readonly_allowed # is it forbidden to write because the partition table is badly handled, or is it because we MUST not change the partition table
bool isDirty # does it need to be written to the disk
@@ -147,37 +145,37 @@ struct hd {
# - add an extended partition which is the first extended partition
list allPartitionsRenumbered # used to update bootloader configuration
int bus, id
-
+
bool is_removable # is it a removable drive
-
+
partition_table_elem primary
partition_table_elem extended[]
-
+
geom geom
-
+
# internal
string prefix # for some RAID arrays device=>c0d0 and prefix=>c0d0p
string file # '/dev/hda' ...
}
-struct hd_lvm inherits hd {
+ struct hd_lvm inherits hd {
int PE_size # block size (granularity, similar to cylinder size on x86)
string VG_name # VG name
-
+
part_lvm disks[]
-
+
# invalid: bus, id, extended, geom
}
-struct raw_hd inherits hd {
+ struct raw_hd inherits hd {
string fs_type # 'ext2', 'nfs', ...
string mntpoint # '/', '/usr' ...
string options # 'defaults', 'noauto'
-
+
# invalid: isDirty, will_tell_kernel, rebootNeeded, primary, extended
}
-struct all_hds {
+ struct all_hds {
hd hds[]
hd_lvm lvms[]
part_raid raids[]
@@ -188,7 +186,7 @@ struct all_hds {
raw_hd smbs[]
raw_hd davs[]
raw_hd special[]
-
+
# internal: if fstab_to_string($all_hds) eq current_fstab then no need to save
string current_fstab
}
@@ -291,14 +289,14 @@ sub Done {
}
if (!$::isInstall) {
my $new = fs::fstab_to_string($all_hds);
- if ($new ne $all_hds->{current_fstab} && $in->ask_yesorno(N("Confirmation"), N("Do you want to save /etc/fstab modifications"), 1)) {
+ if ($new ne $all_hds->{current_fstab} && $in->ask_yesorno(N("Confirmation"), N("Do you want to save the /etc/fstab modifications?"), 1)) {
$all_hds->{current_fstab} = $new;
fs::write_fstab($all_hds);
}
update_bootloader_for_renumbered_partitions($in, $all_hds);
if (any { $_->{rebootNeeded} } @{$all_hds->{hds}}) {
- $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"));
tell_wm_and_reboot();
}
}
@@ -335,7 +333,7 @@ sub hd_possible_actions {
sub hd_possible_actions_interactive {
my ($_in, $_hd, $_all_hds) = @_;
- &hd_possible_actions, N_("Hard drive information");
+ &hd_possible_actions, N_("Hard disk drive information");
}
sub Clear_all {
@@ -354,16 +352,18 @@ sub Clear_all {
$hd->{getting_rid_of_readonly_allowed} = 0; #- we don't need this flag anymore
fsedit::partition_table_clear_and_initialize($all_hds->{lvms}, $hd, $in);
}
+ my $fstab = [ fs::get::fstab($all_hds) ];
+ fsedit::init_efi_suggestions($fstab, 1);
}
sub Auto_allocate {
my ($in, $hd, $all_hds) = @_;
- my $suggestions = partitions_suggestions($in) or return;
+ my $suggestions = partitions_suggestions($in, $all_hds) or return;
my %all_hds_ = %$all_hds;
$all_hds_{hds} = [ sort { $a == $hd ? -1 : 1 } fs::get::hds($all_hds) ];
- eval { fsedit::auto_allocate(\%all_hds_, $suggestions) };
+ eval { fsedit::auto_allocate(\%all_hds_, $suggestions, $hd) };
if ($@) {
$@ =~ /partition table already full/ or die;
@@ -395,6 +395,10 @@ sub Hd_info {
# per-part actions
################################################################################
+sub is_LVM_resizable {
+ my ($part) = @_;
+ member($part->{fs_type}, qw(btrfs ext3 ext4 reiserfs xfs));
+}
sub part_possible_actions {
my ($_in, $hd, $part, $all_hds) = @_;
$part or return;
@@ -405,7 +409,7 @@ sub part_possible_actions {
N_("Type") => '!isBusy && $::expert && (!readonly || $part->{pt_type} == 0x83)',
N_("Options") => '!isSwap($part) && !isNonMountable && $::expert',
N_("Label") => '!isNonMountable && $::expert && fs::format::canEditLabel($part)',
- N_("Resize") => '!isBusy && !readonly && !isSpecial || isLVM($hd) && LVM_resizable',
+ N_("Resize") => '!isBusy && !readonly && !isSpecial || isLVM($hd) && is_LVM_resizable',
N_("Format") => '!isBusy && !isRawLVM && !isPartOfLVM && (!readonly && ($::expert || $::isStandalone) || fs::type::isRawLUKS($part))',
N_("Mount") => '!isBusy && (hasMntpoint || isSwap) && maybeFormatted && ($::expert || $::isStandalone)',
N_("Add to RAID") => '!isBusy && isRawRAID && (!isSpecial || isRAID)',
@@ -424,7 +428,6 @@ sub part_possible_actions {
my %macros = (
readonly => '$hd->{readonly}',
hasMntpoint => '$part->{mntpoint}',
- LVM_resizable => 'member($part->{fs_type}, qw(reiserfs xfs ext3 ext4 btrfs))',
canModifyRAID => 'isPartOfRAID($part) && !isMounted(fs::get::device2part($part->{raid}, $all_hds->{raids}))',
);
if (isEmpty($part)) {
@@ -445,10 +448,10 @@ sub part_possible_actions {
}
sub View {
- my ($in, $hd, $part, $all_hds) = @_;
+ my ($in, $_hd, $part, $_all_hds) = @_;
my $handle = any::inspect($part, $::prefix);
if ($handle) {
- $in->ask_directory({'directory'=>$handle->{dir}});
+ $in->ask_directory({ 'directory' => $handle->{dir} });
} else {
$in->ask_warn(N("Error"), N("Failed to mount partition"));
}
@@ -501,10 +504,10 @@ sub Create {
if_($::expert && $hd->hasExtended,
{ label => N("Preference: "), val => \$primaryOrExtended, list => [ '', "Extended", "Primary", if_($::expert, "Extended_0x85") ] },
),
- if_($::expert && isLVM($hd),
+ if_(isLVM($hd),
{ label => N("Logical volume name "), val => \$part->{lv_name}, list => [ qw(root swap usr home var), '' ], sort => 0, not_edit => 0 },
),
- { label => N("Encrypt partition"), type => 'bool', val => \$use_dmcrypt },
+ { label => N("Encrypt partition"), type => 'bool', val => \$use_dmcrypt, disabled => sub { $part->{mntpoint} eq "/boot" } },
{ label => N("Encryption key "), val => \$part->{dmcrypt_key}, disabled => sub { !$use_dmcrypt }, hidden => 1, weakness_check => 1 },
{ label => N("Encryption key (again)"), val => \$part->{dmcrypt_key2}, disabled => sub { !$use_dmcrypt }, hidden => 1 },
], complete => sub {
@@ -518,8 +521,8 @@ sub Create {
# if user asked to encrypt the partition, use dm-crypt and create requested fs inside
if ($use_dmcrypt) {
my $err;
- $err = N("The encryption keys do not match") unless ($part->{dmcrypt_key} eq $part->{dmcrypt_key2});
- $err = N("Missing encryption key") unless ($part->{dmcrypt_key});
+ $err = N("The encryption keys do not match") unless $part->{dmcrypt_key} eq $part->{dmcrypt_key2};
+ $err = N("Missing encryption key") unless $part->{dmcrypt_key};
if ($err) {
$in->ask_warn(N("Error"), $err);
return 1;
@@ -565,13 +568,7 @@ First remove a primary partition and create an extended partition."));
if ($::isStandalone) {
fs::format::check_package_is_installed_format($in->do_pkgs, $p->{fs_type}) or log::l("Missing package");
}
- if ($::expert && !member($p->{fs_type}, 'reiserfs', 'reiser4', 'xfs', 'hfs', 'ntfs', 'ntfs-3g')) {
- $p->{toFormatCheck} = $in->ask_yesorno(N("Confirmation"), N("Check bad blocks?"));
- }
- $p->{isFormatted} = 0; #- force format;
- # Wait for the newly created device to appear before formatting it
- my ($_w, $wait_message) = $in->wait_message_with_progress_bar;
- fs::format::part($all_hds, $p, $wait_message) unless isRawLVM($p);
+ _format_raw($in, $p, $all_hds, isRawLVM($p));
}
warn_if_renumbered($in, $hd);
@@ -605,9 +602,6 @@ sub Delete {
delete $part->{loopback_device}{loopback} if @$l == 0;
fsedit::recompute_loopbacks($all_hds);
} else {
- if (arch() =~ /ppc/) {
- undef $partition_table::mac::bootstrap_part if isAppleBootstrap($part) && ($part->{device} = $partition_table::mac::bootstrap_part);
- }
partition_table::remove($hd, $part);
warn_if_renumbered($in, $hd);
}
@@ -675,10 +669,10 @@ sub Type {
}
sub Label {
- my ($in, $_hd, $part) = @_;
+ my ($in, $hd, $part) = @_;
my $new_label = $part->{device_LABEL} || "";
- write_partitions($in, $_hd) or return;
+ write_partitions($in, $hd) or return;
$in->ask_from(N("Set volume label"),
maybeFormatted($part) ?
@@ -820,7 +814,7 @@ sub Resize {
#- for these, we have tools to resize partition table
#- without losing data (or at least we hope so :-)
if (%nice_resize) {
- ask_alldatamaybelost($in, $part, N_("All data on this partition should be backed-up")) or return;
+ ask_alldatamaybelost($in, $part, N_("All data on this partition should be backed up")) or return;
} else {
ask_alldatawillbelost($in, $part, N_("After resizing partition %s, all data on this partition will be lost")) or return;
}
@@ -853,13 +847,14 @@ sub Resize {
lvm::lv_resize($low_part, $oldsize);
} else {
if ($write_partitions && isLUKS($part)) {
- run_program::run('cryptsetup', 'luksClose', $part->{dmcrypt_name}) or die ("Failed to resize partition, maybe it is mounted");
+ run_program::run('cryptsetup', 'luksClose', $part->{dmcrypt_name}) or die("Failed to resize partition, maybe it is mounted");
}
partition_table::will_tell_kernel($hd, resize => $low_part);
partition_table::adjust_local_extended($hd, $low_part);
partition_table::adjust_main_extended($hd);
write_partitions($in, $hd) or return if $write_partitions && %nice_resize;
if ($write_partitions && isLUKS($part)) {
+ require fs::dmcrypt;
fs::dmcrypt::open_part([], $low_part);
}
}
@@ -895,13 +890,15 @@ filesystem checks will be run on your next boot into Microsoft Windows®"));
mkdir_p($dir);
fs::mount::mount(devices::make($part->{device}), $dir, $part->{fs_type});
}
- if (!run_program::run("btrfsctl", "-r", $part->{size}*512, $dir)) {
+ if (!run_program::run(qw(btrfs filesystem resize), $part->{size}*512, $dir)) {
$nice_resize{btrfs} = undef;
if (!$part->{isMounted}) {
fs::mount::umount($dir);
unlink($dir);
}
}
+ } elsif ($nice_resize{nilfs}) {
+ run_program::run_or_die("nilfs-resize", $part->{mntpoint});
}
if (%nice_resize) {
@@ -949,11 +946,26 @@ sub dmcrypt_open {
hidden => 1, focus => sub { 1 } } ]) or return;
}
- eval { fs::dmcrypt::open_part($all_hds->{dmcrypts}, $part) };
+ eval { require fs::dmcrypt; fs::dmcrypt::open_part($all_hds->{dmcrypts}, $part) };
if ($@) {
delete $part->{dmcrypt_key};
die(($? >> 8) == 255 ? N("Invalid key") : $@);
}
+ detect_lvms_on_dmcrypt($all_hds);
+}
+
+# Detect LVMs on top of dmcrypt
+sub detect_lvms_on_dmcrypt {
+ my ($all_hds) = @_,
+ require File::Temp;
+ require fs::dmcrypt;
+ my (undef, $tmp_file) = File::Temp::mkstemp('/tmp/crypttab.XXXXXXX');
+ fs::dmcrypt::save_crypttab_($all_hds, $tmp_file);
+ require lvm;
+ lvm::detect_during_install();
+ $all_hds->{lvms} = [ fsedit::lvms($all_hds) ];
+ fs::dmcrypt::read_crypttab_($all_hds, $tmp_file);
+ rm_rf($tmp_file);
}
sub Add2RAID {
@@ -985,12 +997,12 @@ sub Add2LVM {
require lvm;
if (!ref $lvm) {
# create new lvm
- my $n = 0;
- while (member("vg$n", @lvm_names)) {
+ my $n; my $str = "vg-mga";
+ while (member("$str$n", @lvm_names)) {
$n++;
}
- my $name = "vg$n";
+ my $name = "$str$n";
$in->ask_from_({ title => N("LVM name"),
messages => N("Enter a name for the new LVM volume group"),
focus_first => 1,
@@ -1000,7 +1012,7 @@ sub Add2LVM {
$in->ask_warn(N("Error"), N("\"%s\" already exists", $name));
return 0;
} },
- [{label=>N("LVM name"),val=> \$name}]) or return;
+ [ { label => N("LVM name"), val => \$name } ]) or return;
$lvm = new lvm($name);
push @$lvms, $lvm;
@@ -1019,6 +1031,7 @@ sub RemoveFromRAID {
}
sub RemoveFromDm {
my ($_in, $_hd, $part, $all_hds) = @_;
+ require fs::dmcrypt;
fs::dmcrypt::close_part($all_hds->{dmcrypts}, $part);
}
sub RemoveFromLVM {
@@ -1085,7 +1098,7 @@ sub Loopback {
}
sub Options {
- my ($in, $hd, $part, $all_hds) = @_;
+ my ($in, $_hd, $part, $_all_hds) = @_;
my @simple_options = qw(users noauto username= password=);
@@ -1136,12 +1149,12 @@ sub Options {
*{'Modify RAID'} = \&ModifyRAID;
*{'Add to RAID'} = \&Add2RAID;
*{'Remove from RAID'} = \&RemoveFromRAID;
- *{'Use'} = \&dmcrypt_open;
+ *{Use} = \&dmcrypt_open;
*{'Remove from dm'} = \&RemoveFromDm;
*{'Add to LVM'} = \&Add2LVM;
*{'Remove from LVM'} = \&RemoveFromLVM;
*{'Use for loopback'} = \&Loopback;
- *{'Hard drive information'} = \&Hd_info;
+ *{'Hard disk drive information'} = \&Hd_info;
}
@@ -1192,7 +1205,9 @@ sub ask_alldatawillbelost {
}
sub partitions_suggestions {
- my ($in) = @_;
+ my ($in, $all_hds) = @_;
+ my $fstab = [ fs::get::fstab($all_hds) ];
+ fsedit::init_efi_suggestions($fstab);
my $t = $::expert ?
$in->ask_from_list_(N("Partitioning Type"), N("What type of partitioning?"), [ keys %fsedit::suggestions ]) :
'simple';
@@ -1232,7 +1247,7 @@ sub check {
sub check_rebootNeeded {
my ($_in, $hd) = @_;
- $hd->{rebootNeeded} and die N("You'll need to reboot before the modification can take place");
+ $hd->{rebootNeeded} and die N("You'll need to reboot before the modification can take effect");
}
sub write_partitions {
@@ -1245,7 +1260,7 @@ sub write_partitions {
partition_table::write($hd) if !$::testing;
check_rebootNeeded($in, $hd) if !$b_skip_check_rebootNeeded;
# fix resizing's failures due to udev's race when writing the partition table
- run_program::run('udevadm', 'settle') unless $::isInstall;
+ run_program::run('udevadm', 'settle');
1;
}
@@ -1259,7 +1274,7 @@ sub ensure_we_have_encrypt_key_if_needed {
}
sub dmcrypt_format {
- my ($in, $hd, $part, $all_hds) = @_;
+ my ($in, $_hd, $part, $_all_hds) = @_;
my $_wait = $in->wait_message(N("Please wait"), N("Formatting partition %s", $part->{device}));
require fs::dmcrypt;
fs::dmcrypt::format_part($part);
@@ -1281,12 +1296,18 @@ sub format_ {
if ($::isStandalone) {
fs::format::check_package_is_installed_format($in->do_pkgs, $part->{fs_type}) or return;
}
- if ($::expert && !member($part->{fs_type}, 'reiserfs', 'reiser4', 'xfs', 'hfs', 'ntfs', 'ntfs-3g')) {
- $part->{toFormatCheck} = $in->ask_yesorno(N("Confirmation"), N("Check bad blocks?"));
+ _format_raw($in, $part, $all_hds);
+}
+
+sub _format_raw {
+ my ($in, $part, $all_hds, $o_skip) = @_;
+ if ($::expert && !member($part->{fs_type}, 'reiserfs', 'xfs', 'hfs', 'ntfs', 'ntfs-3g')) {
+ $part->{toFormatCheck} = $in->ask_yesorno(N("Confirmation"), N("Check for bad blocks?"));
}
$part->{isFormatted} = 0; #- force format;
+ # Wait for the newly created device to appear before formatting it
my ($_w, $wait_message) = $in->wait_message_with_progress_bar;
- fs::format::part($all_hds, $part, $wait_message);
+ fs::format::part($all_hds, $part, $wait_message) if !$o_skip;
1;
}
@@ -1364,16 +1385,7 @@ sub format_part_info {
$info .= N("Volume label: ") . "$part->{device_LABEL}\n" if $part->{device_LABEL};
$info .= N("UUID: ") . "$part->{device_UUID}\n" if $::expert && $part->{device_UUID};
$info .= N("DOS drive letter: %s (just a guess)\n", $part->{device_windobe}) if $part->{device_windobe};
- if (arch() eq "ppc") {
- my $pType = $part->{pType};
- $pType =~ s/[^A-Za-z0-9_]//g;
- $info .= N("Type: ") . $pType . ($::expert ? sprintf " (0x%x)", $part->{pt_type} : '') . "\n";
- if (defined $part->{pName}) {
- my $pName = $part->{pName};
- $pName =~ s/[^A-Za-z0-9_]//g;
- $info .= N("Name: ") . $pName . "\n";
- }
- } elsif (isEmpty($part)) {
+ if (isEmpty($part)) {
$info .= N("Empty") . "\n";
} else {
$info .= N("Type: ") . (fs::type::part2type_name($part) || $part->{fs_type}) . ($::expert ? sprintf " (0x%x)", $part->{pt_type} : '') . "\n";
@@ -1390,7 +1402,7 @@ sub format_part_info {
$info .= N("Mounted\n") if $part->{isMounted};
$info .= N("RAID %s\n", $part->{raid}) if isPartOfRAID($part);
if (fs::type::isRawLUKS($part) || fs::type::isLUKS($part)) {
- $info .= N("Encrypted")."\n";
+ $info .= N("Encrypted") . "\n";
if (fs::type::isRawLUKS($part)) {
$info .= ($part->{dm_active} && $part->{dm_name} ? N(" (mapped on %s)", $part->{dm_name}) :
$part->{dm_name} ? N(" (to map on %s)", $part->{dm_name}) :