summaryrefslogtreecommitdiffstats
path: root/rescue
diff options
context:
space:
mode:
Diffstat (limited to 'rescue')
-rwxr-xr-xrescue/partimage_whole_disk84
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";
+}