summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xrescue/make_rescue_img29
-rwxr-xr-xrescue/partimage_whole_disk133
2 files changed, 157 insertions, 5 deletions
diff --git a/rescue/make_rescue_img b/rescue/make_rescue_img
index 32a5f1417..871a0c1ff 100755
--- a/rescue/make_rescue_img
+++ b/rescue/make_rescue_img
@@ -41,9 +41,9 @@ sub install_l {
sub installown($$) {
my ($own, $dir) = @_;
- return if -e "$tmp$dir$own";
+ return if -e "$tmp$dir/" . basename($own);
mkdir_p("$tmp$dir");
- _ "cp -a $own $tmp$dir";
+ _ "cp $own $tmp$dir";
}
_ "$sudo rm -rf $tmp" if -e $tmp;
@@ -113,20 +113,39 @@ installown("../mdk-stage1/dhcp-client", "/usr/sbin");
__ "strip $tmp/{lib,$lib,bin,sbin}/* $tmp/usr/{bin,sbin}/* 2>/dev/null";
if ($ENV{PARTIMAGE_DIR}) {
+
+ my $perl_install = "../perl-install";
+ foreach (`strace -efile perl -cw -I $perl_install partimage_whole_disk 2>&1`) {
+ my ($f) = /^open\("(.*?)",.*\)\s*=\s*\d+$/ or next;
+ if ($f =~ s!^\Q$perl_install/!!) {
+ installown("$perl_install/$f", dirname("/usr/lib/libDrakX/$f"));
+ } elsif ($f =~ m!^/dev/! || $f eq 'partimage_all_disk') {
+ # skip
+ } else {
+ installown($f, dirname($f));
+ }
+ }
+ installown('partimage_whole_disk', '/usr/sbin');
+
_ "rpm2cpio $ENV{PARTIMAGE_RPM} | (cd $tmp ; cpio -idu ./usr/sbin/partimage)";
my $server = 'partimaged';
+ $server = 'leia';
substInFile {
$_ = <<EOF if /^\s*rescue-gui/;
if grep -q save_all /proc/cmdline; then
- drvinst ; dhcp-client ; partimage -s $server -b save_all $ENV{PARTIMAGE_DIR}; reboot
+ drvinst ; dhcp-client ; partimage_whole_disk save_all $ENV{PARTIMAGE_DIR} $server
+ echo "Press enter"
+ read
fi
if grep -q rest_all /proc/cmdline; then
local=/tmp/image$ENV{PARTIMAGE_DIR}
if [ -d \$local ]; then
- partimage -b rest_all \$local; reboot
+ partimage_whole_disk rest_all \$local
else
- drvinst ; dhcp-client ; partimage -s $server -b rest_all $ENV{PARTIMAGE_DIR}; reboot
+ drvinst ; dhcp-client ; partimage_whole_disk rest_all $ENV{PARTIMAGE_DIR} $server
fi
+ echo "Press enter"
+ read
fi
EOF
} "$tmp/etc/rc.sysinit";
diff --git a/rescue/partimage_whole_disk b/rescue/partimage_whole_disk
new file mode 100755
index 000000000..7d36e9cfb
--- /dev/null
+++ b/rescue/partimage_whole_disk
@@ -0,0 +1,133 @@
+#!/usr/bin/perl
+
+use lib qw(/usr/lib/libDrakX ../perl-install);
+use standalone;
+use fsedit;
+use fs::format;
+use fs::type;
+use resize_fat::main;
+use diskdrake::resize_ntfs;
+use common;
+use partition_table::empty;
+use Carp::Heavy;
+
+#- help getting the file in make_rescue_img
+BEGIN { partition_table::raw::default_type() }
+
+my ($action, $dir, $server) = @ARGV;
+
+sub usage() { die "partimage_whole_disk <save_all | rest_all> <dir> [<server>]\n" }
+@ARGV == 2 || @ARGV == 3 or usage();
+
+$ENV{PATH} = "/sbin:/usr/sbin:$ENV{PATH}";
+log::openLog("/var/log/partimage_whole_disk.log");
+my @partimage_cmd = ('partimage', if_($server, '-s', $server));
+my $all_hds = fsedit::get_hds({});
+
+if ($action eq 'save_all') {
+ save_all();
+} elsif ($action eq 'rest_all') {
+ rest_all();
+} else {
+ usage();
+}
+
+sub save_all() {
+ my $hd = $all_hds->{hds}[0] or die "no main hard drive\n";
+ log::l("save_all on $hd->{device}");
+ my $part_list = [ partition_table::get_normal_parts($hd) ];
+
+ foreach (@$part_list) {
+ $_->{saved} = !member($_->{fs_type}, 'ntfs', 'vfat', 'swap');
+ if ($_->{saved}) {
+ run_program::run_or_die(@partimage_cmd,
+ '-V', 0, '--nombr', '--nodesc', '--nocheck', '-b', '-o',
+ 'save', devices::make($_->{device}), "$dir/$_->{device}");
+ }
+ }
+ save_part_list($part_list);
+}
+sub rest_all() {
+ my $part_list = read_part_list();
+ fs::type::set_fs_type($_, $_->{fs_type}) foreach @$part_list;
+
+ my @used_hds;
+ foreach my $part (@$part_list) {
+ if (my $hd = find { $part->{device} =~ /^\Q$_->{device}\E./ } fs::get::hds($all_hds)) {
+ push @used_hds, $hd;
+ put_in_hash($part, partition_table::hd2minimal_part($hd));
+ }
+ }
+
+ my ($from_partimage, $other) = partition { $_->{saved} } @$part_list;
+ my ($from_resize, $created) = partition { member($_->{fs_type}, 'vfat', 'ntfs') } @$other;
+
+ foreach (@$from_resize) {
+ #- resize first
+ my $part = fs::get::device2part($_->{device}, [ fs::get::fstab($all_hds) ]) or log::l("partition to resize is missing ($_->{device})"), next;
+ $_->{fs_type} eq $_->{fs_type} or log::l("partition $_->{device} doesn't have the right filesystem ($part->{fs_type} != $_->{fs_type})"), next;
+
+ $_->{start} = $part->{start};
+ if ($_->{size} < $part->{size}) {
+ log::l("resizing $_->{device} to $_->{size} (it is $part->{size})");
+ my $resize_pkg = $_->{fs_type} eq 'vfat' ? 'resize_fat::main' : 'diskdrake::resize_ntfs';
+ my $resize = $resize_pkg->new($_->{device}, devices::make($_->{device}));
+ $resize->resize($_->{size});
+ } else {
+ log::l("no need to resize $_->{device} since $_->{size} >= $part->{size}");
+ }
+ }
+
+ foreach my $hd (uniq(@used_hds)) {
+# put_in_hash($hd->{geom}, { heads => 240, sectors => 63 });
+
+ #- write the partition table
+ partition_table::raw::zero_MBR($hd);
+ foreach my $part (grep { $_->{rootDevice} eq $hd->{device} } @$part_list) {
+
+ my $hole = find { isEmpty($_) && $_->{size} >= $part->{size} } partition_table::get_normal_parts_and_holes($hd) or die "not enough room";
+ $part->{start} = $hole->{start};
+
+ log::l("handling $part->{device}");
+ my $extended = $part->{device} =~ /(\d+)$/ && $1 > 4 && $hd->hasExtended;
+
+ my %wanted_part = %$part;
+ if ($extended || $part->{start} == 1) {
+ $part->{size} += $hd->{geom}{sectors};
+ }
+ partition_table::add($hd, $part, $extended && 'Extended');
+ foreach ('device', 'size') {
+ $part->{$_} eq $wanted_part{$_} or log::l("bad $_ for $part->{device}: $part->{$_} != $wanted_part{$_}");
+ }
+ }
+ partition_table::write($hd);
+ }
+
+ #- restore from partimage
+ foreach (@$from_partimage) {
+ run_program::run_or_die(@partimage_cmd, 'restore', '-b', devices::make($_->{device}), "$dir/$_->{device}");
+ }
+
+ foreach (@$created) {
+ fs::format::part_raw($_, undef);
+ }
+
+ run_program::run('install_bootloader');
+}
+
+sub lst_fields() { qw(device size fs_type saved) }
+sub save_part_list {
+ my ($part_list) = @_;
+ my @l = map { join(' ', @$_{lst_fields()}) } @$part_list;
+ log::l("save_part_list: $_") foreach @l;
+ my $partimage = join(' ', @partimage_cmd);
+ open(my $F, "| $partimage -z0 -Bfoo=bar -o save_file $dir/.lst");
+ print $F "$_\n" foreach @l;
+}
+sub read_part_list() {
+ my $partimage = join(' ', @partimage_cmd);
+ open(my $F, "$partimage -z0 -Bfoo=bar rest_file $dir/.lst |");
+ my @l = chomp_(cat__($F));
+ log::l("read_part_list: $_") foreach @l;
+ [ map { my %l; @l{lst_fields()} = split; \%l } @l ];
+}