diff options
Diffstat (limited to 'rescue')
-rwxr-xr-x | rescue/partimage_whole_disk | 84 |
1 files changed, 33 insertions, 51 deletions
diff --git a/rescue/partimage_whole_disk b/rescue/partimage_whole_disk index e507c2638..dd17a2993 100755 --- a/rescue/partimage_whole_disk +++ b/rescue/partimage_whole_disk @@ -33,8 +33,7 @@ $ENV{HOME} = '/'; log::openLog("/var/log/partimage_whole_disk.log"); my @partimage_cmd = ('partimage', if_($server, '-s', $server)); -$action eq 'save_all' && @ARGV == 1 || - $action eq 'rest_all' && @ARGV or usage(); +@ARGV == 1 or usage(); run_program::run('drvinst', 'STORAGE_SCSI', 'STORAGE_IDE'); @@ -43,7 +42,7 @@ my $all_hds = fsedit::get_hds({}); if ($action eq 'save_all') { save_all($ARGV[0]); } elsif ($action eq 'rest_all') { - rest_all(@ARGV); + rest_all($ARGV[0]); } sub save_all { @@ -79,54 +78,32 @@ sub save_all { save_part_list($dir, $hd->{geom}, $part_list); } sub rest_all { - my (@dirs) = @_; + my ($dir) = @_; - my %best; - DIRS: foreach (@dirs) { - my ($forced_geom, $part_list) = read_part_list($_) or log::l("read_part_list $_ failed"), next; - my %h = (dir => $_, forced_geom => $forced_geom, part_list => $part_list); - log::l("trying with $h{dir}"); + my ($forced_geom, $part_list) = read_part_list($dir) or error("read_part_list $dir failed"); - ($h{hd}) = my @used_hds = uniq(map { + (my $hd) = my @used_hds = uniq(map { my $part = $_; find { $part->{device} =~ /^\Q$_->{device}\E./ } fs::get::hds($all_hds) - or log::l("can't find hard drive for partition $part->{device}"), next DIRS; + or error("can't find hard drive for partition $part->{device}"); } @$part_list); - @used_hds >= 1 or log::l("no matching hd"), next; - @used_hds <= 1 or log::l("multiple hds: " . join(' ', map { $_->{device} } @used_hds)), next; + @used_hds >= 1 or error("no matching hd"); + @used_hds <= 1 or error("multiple hds: " . join(' ', map { $_->{device} } @used_hds)); fs::type::set_fs_type($_, $_->{fs_type}) foreach @$part_list; - put_in_hash($_, partition_table::hd2minimal_part($h{hd})) foreach @$part_list; - - ($h{from_partimage}, my $other) = partition { $_->{saved} } @$part_list; - ($h{from_resize}, $h{created}) = partition { member($_->{fs_type}, 'vfat', 'ntfs') } @$other; + put_in_hash($_, partition_table::hd2minimal_part($hd)) foreach @$part_list; - $h{valid_resize} = every { - my $part = fs::get::device2part($_->{device}, [ fs::get::fstab($all_hds) ]) or log::l("partition to resize is missing ($_->{device})"); - my $ok = $part && $part->{fs_type} eq $_->{fs_type}; - $ok or log::l("partition $_->{device} doesn't have the right filesystem ($part->{fs_type} != $_->{fs_type})"); - $ok; - } @{$h{from_resize}}; + my ($from_partimage, $other) = partition { $_->{saved} } @$part_list; + my ($from_resize, $created) = partition { member($_->{fs_type}, 'vfat', 'ntfs') } @$other; - $h{total} = sum(map { $_->{size} } @$part_list); - if ($h{total} > $h{hd}{totalsectors}) { - log::l("discarding $h{dir} since total $h{total} > $h{hd}{totalsectors}"); - } elsif ($h{valid_resize} < $best{valid_resize}) { - log::l("discarding $h{dir} since it has invalid resize whereas $best{dir} has valid resize"); - } elsif ($h{total} > $best{total}) { - log::l("$h{dir} is better than $best{dir} since total $h{total} > $best{total}"); - %best = %h; - } else { - log::l("$h{dir} is not better than $best{dir} since total $h{total} <= $best{total}"); + my $total = sum(map { $_->{size} } @$part_list); + if ($total > $hd->{totalsectors}) { + error("$dir doesn't fit: $total > $hd->{totalsectors}"); } - } - $best{dir} or die "no valid partimage data dirs\n"; - my %h = %best; - log::l("chosen dir $h{dir}"); - foreach (@{$h{from_resize}}) { + foreach (@$from_resize) { #- resize first my $part = fs::get::device2part($_->{device}, [ fs::get::fstab($all_hds) ]); if (!$part) { @@ -140,11 +117,11 @@ sub rest_all { next; } - if (@{$h{from_resize}} == 1) { - my $half_size = int($h{hd}{totalsectors} / 2) - 2 * $h{hd}->cylinder_size; - my $suggested_total = $h{total} - $_->{size} + $half_size; - log::l("resizing bigger? (size $_->{size}, half_size $half_size, total $h{total}, suggested_total $suggested_total)"); - if ($half_size > $_->{size} && $suggested_total < $h{hd}{totalsectors}) { + if (@$from_resize == 1) { + my $half_size = int($hd->{totalsectors} / 2) - 2 * $hd->cylinder_size; + my $suggested_total = $total - $_->{size} + $half_size; + log::l("resizing bigger? (size $_->{size}, half_size $half_size, total $total, suggested_total $suggested_total)"); + if ($half_size > $_->{size} && $suggested_total < $hd->{totalsectors}) { log::l("prefering to resize $_->{device} to size $half_size instead of $_->{size}"); $_->{size} = $half_size; } @@ -162,19 +139,18 @@ sub rest_all { } } - my $hd = $h{hd}; - put_in_hash($hd->{geom}, $h{forced_geom}); + put_in_hash($hd->{geom}, $forced_geom); log::l("totalsectors $hd->{totalsectors} heads $hd->{geom}{heads} sectors $hd->{geom}{sectors}"); partition_table::raw::compute_nb_cylinders($hd->{geom}, $hd->{totalsectors}); #- grow the last ext3 partition - if (my $part = find { isTrueLocalFS($_) } reverse @{$h{part_list}}) { + if (my $part = find { isTrueLocalFS($_) } reverse @$part_list) { $part->{ratio} = 1; } #- write the partition table partition_table::raw::zero_MBR($hd); - foreach my $part (grep { $_->{rootDevice} eq $hd->{device} } @{$h{part_list}}) { + foreach my $part (grep { $_->{rootDevice} eq $hd->{device} } @$part_list) { next if $part->{missing}; my $hole = find { isEmpty($_) && $_->{size} >= $part->{size} } partition_table::get_normal_parts_and_holes($hd) or die "not enough room for $part->{device}"; @@ -199,8 +175,8 @@ sub rest_all { partition_table::write($hd); #- restore from partimage - foreach (@{$h{from_partimage}}) { - run_or_die(@partimage_cmd, 'restore', '-b', devices::make($_->{device}), "$h{dir}/$_->{device}"); + foreach (@$from_partimage) { + run_or_die(@partimage_cmd, 'restore', '-b', devices::make($_->{device}), "$dir/$_->{device}"); if ($_->{ratio}) { my $resize = diskdrake::resize_ext2->new($_->{device}, devices::make($_->{device})); @@ -208,13 +184,13 @@ sub rest_all { } } - foreach (@{$h{created}}) { + foreach (@$created) { fs::format::part_raw($_, undef); } run_program::run('guessmounts'); - if (my @missing = grep { $_->{missing} } @{$h{part_list}}) { + if (my @missing = grep { $_->{missing} } @$part_list) { my $missing = join('|', map { quotemeta($_->{device}) } @missing); log::l("drop missing devices from fstab and lilo.conf: $missing"); $::prefix = '/mnt'; @@ -255,3 +231,9 @@ sub run_or_die { my (@l) = @_; run_program::raw({ timeout => 4 * 60 * 60 }, @l) or die join(' ', @l) . " failed\n"; } + +sub error { + my ($msg) = @_; + log::l($msg); + die "$msg\n"; +} |