summaryrefslogtreecommitdiffstats
path: root/perl-install/fs/partitioning_wizard.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/fs/partitioning_wizard.pm')
-rw-r--r--perl-install/fs/partitioning_wizard.pm235
1 files changed, 141 insertions, 94 deletions
diff --git a/perl-install/fs/partitioning_wizard.pm b/perl-install/fs/partitioning_wizard.pm
index 0aa8f82f4..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;
@@ -13,15 +13,27 @@ use partition_table;
use partition_table::raw;
use partition_table::dos;
use POSIX qw(ceil);
-use mygtk2;
-use ugtk2 qw(:wrappers);
-#- 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);
@@ -35,10 +47,18 @@ sub partition_with_diskdrake {
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();
@@ -65,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;
}
@@ -91,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 ?
@@ -112,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);
@@ -153,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});
@@ -178,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);
@@ -225,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 ];
}
@@ -245,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;
} ];
}
@@ -270,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;
@@ -293,34 +327,47 @@ sub warn_reboot_needed {
sub create_display_box {
my ($kind, $resize, $fill_empty, $button) = @_;
- my @parts = diskdrake::hd_gtk::kind2parts($kind);
+ # 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->();
@@ -328,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 {
@@ -372,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;
});
@@ -395,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;
@@ -442,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]));
@@ -460,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]};
}
@@ -493,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, diskdrake::hd_gtk::raid2real_kind($_) foreach @{$all_hds->{raids}};
+ #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|;
@@ -525,16 +565,16 @@ 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);
@@ -547,7 +587,9 @@ sub main {
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);
@@ -563,7 +605,7 @@ sub main {
);
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;
@@ -598,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)));
}
}
@@ -605,4 +648,8 @@ sub main {
1;
}
+=back
+
+=cut
+
1;