package fs::partitioning_wizard; # $Id: partitioning_wizard.pm 269969 2010-06-09 13:01:09Z pterjan $ use diagnostics; use strict; use utf8; use common; use devices; use fsedit; use fs::type; use fs::mount_point; 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. sub from_Mb { my ($mb, $min, $max) = @_; $mb <= to_Mb($min) and return $min; $mb >= to_Mb($max) and return $max; MB($mb); } sub to_Mb { my ($size_sector) = @_; to_int($size_sector / 2048); } sub partition_with_diskdrake { my ($in, $all_hds, $fstab, $manual_fstab, $_partitions, $partitioning_flags, $skip_mtab) = @_; my $ok; do { $ok = 1; my $do_force_reload = sub { 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; $all_hds; }; require diskdrake::interactive; { local $::expert = 0; diskdrake::interactive::main($in, $all_hds, $do_force_reload); } my @fstab = fs::get::fstab($all_hds); 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). 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")); $ok = ''; } } until $ok; 1; } sub partitionWizardSolutions { my ($in, $all_hds, $all_fstab, $manual_fstab, $partitions, $partitioning_flags, $skip_mtab, $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) ]; } else { $fstab = $full_fstab; } my @wizlog; my (%solutions); my $min_linux = MB(600); my $min_swap = MB(50); my $min_freewin = MB(100); # 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 } ]; } else { push @wizlog, N("Not enough free space to allocate new partitions") . ": " . (@hds_can_add ? fs::get::hds_free_space(@hds_can_add) . " < $min_linux" : "no harddrive on which partitions can be added"); } if (my @truefs = grep { isTrueLocalFS($_) } @$fstab) { #- value twice the ext2 partitions $solutions{existing_part} = [ 20 + @truefs + @$fstab, N("Use existing partitions"), sub { fs::mount_point::ask_mount_points($in, $full_fstab, $all_hds) } ]; } else { 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) { @ok_for_resize_fat = map { my $part = $_; my $hd = fs::get::part2hd($part, $all_hds); my $resize_fat = eval { my $pkg = $part->{fs_type} eq 'vfat' ? do { require resize_fat::main; 'resize_fat::main'; } : do { require diskdrake::resize_ntfs; 'diskdrake::resize_ntfs'; }; $pkg->new($part->{device}, devices::make($part->{device})); }; if ($@) { log::l("The FAT resizer is unable to handle $part->{device} partition%s", formatError($@)); undef $part; } if ($part) { my $min_win = eval { my $_w = $in->wait_message(N("Resizing"), N("Computing the size of the Microsoft Windows® partition")); $resize_fat->min_size + $min_freewin; }; if ($@) { log::l("The FAT resizer is unable to get minimal size for $part->{device} partition %s", formatError($@)); undef $part; } else { my $min_linux_all = $min_linux + $min_swap; #- make sure that even after normalizing the size to cylinder boundaries, the minimun will be saved, #- this save at least a cylinder (less than 8Mb). $min_win += partition_table::raw::cylinder_size($hd); if ($part->{size} <= $min_linux_all + $min_win) { # die N("Your Microsoft Windows® partition is too fragmented. Please reboot your computer under Microsoft Windows®, run the ``defrag'' utility, then restart the %s installation.", N("Mageia")); undef $part; } else { $part->{resize_fat} = $resize_fat; $part->{min_win} = $min_win; $part->{min_linux} = $min_linux_all; #- try to keep at least 1GB free for Windows #- try to use from 6GB to 10% free space for Linux 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->{req_size} = max(min($suggested_size, $part->{size} - $part->{min_linux}), $part->{min_win}); } } } $part || (); } @ok_for_resize_fat; if (@ok_for_resize_fat) { $solutions{resize_fat} = [ 20 - @ok_for_resize_fat, N("Use the free space on a Microsoft Windows® partition"), sub { my $part; if (!$in->isa('interactive::gtk')) { $part = $in->ask_from_listf_raw({ messages => N("Which partition do you want to resize?"), interactive_help_id => 'resizeFATChoose', }, \&partition_table::description, \@ok_for_resize_fat) or return; $part->{size} > $part->{min_linux} + $part->{min_win} or die N("Your Microsoft Windows® partition is too fragmented. Please reboot your computer under Microsoft Windows®, run the ``defrag'' utility, then restart the %s installation.", N("Mageia")); } else { $part = top(grep { $_->{req_size} } @ok_for_resize_fat); } my $resize_fat = $part->{resize_fat}; [ticket/12953] Page title not updated when notifications are marked as read * Geolim4/ticket/12953: [ticket/12953] Page title not updated when notifications are marked as read