From 1fcdcfd86d44224d4937c93b17f08460fa83d807 Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Tue, 4 Aug 2009 14:54:13 +0000 Subject: - use full disk device when recording harddisk/oem_rescue/replicator masters (this is probably breaking recording USB masters) - allow to mount multiple partitions before recording target master --- draklive | 152 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 105 insertions(+), 47 deletions(-) diff --git a/draklive b/draklive index 10602f5..184ea51 100755 --- a/draklive +++ b/draklive @@ -707,6 +707,28 @@ sub get_hd_from_layout { }, 'partition_table::dos'; } +sub get_hd_from_file { + my ($media, $file) = @_; + my $hd = bless { + geom => get_harddisk_geometry($media), + file => $file, + }, 'partition_table::dos'; + partition_table::read($hd); + return $hd; +} + +sub guess_media_partitions_start { + my ($media, $hd) = @_; + #- try to find partition start by matching actual partition table and partitions list + my @all_parts = partition_table::get_normal_parts($hd); + $media->{partitions}[$_]{start} = $all_parts[$_]{start} for 0 .. $#all_parts; +} + +sub set_part_real_device { + my ($hd, $part) = @_; + $part->{real_device} = -f $hd->{file} ? get_partition_loop($hd, $part) : ($hd->{file} . $part->{device}); +} + sub allocate_master { my ($live, $media, $dest) = @_; @@ -729,7 +751,11 @@ sub allocate_master { partition_table::write($hd); my $inode_size = $media->get_media_setting('inode_size'); - map_index { allocate_partition($hd, $_, $inode_size) } @{$media->{partitions}}; + foreach my $part (@{$media->{partitions}}) { + my $loop = get_partition_loop($hd, $part); + MDV::Draklive::Utils::device_mkfs($loop, $part->{fs_type}, $inode_size) or die "unable to format $hd->{file}\n"; + devices::del_loop($loop); + } } sub create_disk_master { @@ -745,16 +771,9 @@ sub create_disk_master { $live->{media}->supplement_partitions($slash_size); my $dest = get_disk_master_path($live); - my @loops = allocate_master($live, $live->{media}, $dest); + allocate_master($live, $live->{media}, $dest); my $slash_idx = $live->{media}->find_partition_index('/'); - local $opts->{device} = $loops[$slash_idx]; - local $opts->{disk_device} = $dest; record_master($live, $opts); - my $oem_rescue_idx = $live->{media}->find_partition_index('OEM_RESCUE'); - if (defined $oem_rescue_idx) { - record_oem_rescue($live, $loops[$oem_rescue_idx], $opts); - } - run_('losetup', '-d', $_) foreach @loops; } #- $opts: @@ -864,11 +883,7 @@ sub install_usb_bootloader { run_('syslinux', if_(!$media->{fast_syslinux}, '-s'), $boot_device) or die "unable to run syslinux on $device\n"; } elsif ($bootloader eq 'grub') { - my $master_device = $opts->{disk_device}; - if (!$master_device) { - $master_device = $device; - $master_device =~ s/(\d+)$//; - } + my $master_device = $device; if ($master_device =~ m!/dev/!) { my $local_grub_install = $live->get_builddir . $live->{prefix}{build}{scripts} . '/grub-install'; mkdir_p(dirname($local_grub_install)); @@ -950,36 +965,54 @@ sub record_usb_master { sub record_harddisk_master { my ($live, $opts) = @_; + my $media = $live->{media}; my $media_boot = $live->get_media_prefix('boot', $opts->{boot}); my $media_loopbacks = $live->get_media_prefix('loopbacks', $opts->{boot}); - if (my $label = !$opts->{boot_only} && $opts->{device} && $media->get_media_label) { - set_device_label($opts->{device}, $media->get_media_setting('fs'), $label); - } - my $device = get_media_device($live, $opts) + $opts->{device} ||= get_disk_master_path($live); + my $main_device = get_media_device($live, $opts) or die "unable to find recording device (missing label? try with --device )\n"; + my $hd = get_hd_from_file($media, $main_device); + guess_media_partitions_start($media, $hd); + my @partitions = grep { $_->{mntpoint} =~m!^/! } @{$media->{partitions}}; + mkdir_p($live->{mnt}); - run_('mount', $device, $live->{mnt}) - or die "unable to mount $device\n"; + foreach my $part (sort { $a->{mntpoint} cmp $b->{mntpoint} } @partitions) { + set_part_real_device($hd, $part); + my $mnt = $live->{mnt} . $part->{mntpoint}; + mkdir_p($mnt); + run_('mount', $part->{real_device}, $mnt) + or die "unable to mount $part->{real_device}\n"; + } + + if (my $label = !$opts->{boot_only} && $opts->{device} && $media->get_media_label) { + my $slash_idx = $media->find_partition_index('/'); + my $slash = $media->{partitions}[$slash_idx]; + set_device_label($slash->{real_device}, $media->get_media_setting('fs'), $label); + } + my $r = 1; do { my $source = $live->get_system_root; my $total = directory_usage($source); local $/ = "\r"; - my $r = run_foreach(update_progress_rsync($live, $total), 'rsync', '-a', $source . '/', $live->{mnt}); - if (!$r) { - run_('umount', $live->{mnt}); - maybe_umount_device($device); - die "unable to copy system files\n"; - } + $r = run_foreach(update_progress_rsync($live, $total), 'rsync', '-a', $source . '/', $live->{mnt}) + or last; } unless $opts->{boot_only}; - install_grub_to_image($live, $media, $opts->{disk_device}); + install_grub_to_image($live, $media, $hd->{file}); - run_('umount', $live->{mnt}); - maybe_umount_device($device); + foreach my $part (sort { $b->{mntpoint} cmp $a->{mntpoint} } @partitions) { + run_('umount', $part->{real_device}); + maybe_umount_device($part->{real_device}); + devices::del_loop($part->{real_device}) if -f $hd->{file}; + } + + $r or die "unable to copy system files\n"; + + record_oem_rescue($live, $opts) if $live->{oem_rescue}; } #- $opts: @@ -1107,16 +1140,31 @@ sub record_rescue_files { } sub record_oem_rescue { - my ($live, $device, $opts) = @_; + my ($live, $opts) = @_; + + my $media = $live->{media}; + my $oem_rescue_idx = $media->find_partition_index('OEM_RESCUE'); + defined $oem_rescue_idx or die "no OEM_RESCUE partition"; + + $opts->{device} ||= get_disk_master_path($live); + my $main_device = get_media_device($live, $opts) + or die "unable to find recording device (missing label? try with --device )\n"; + + my $hd = get_hd_from_file($media, $main_device); + guess_media_partitions_start($media, $hd); + + my $oem_rescue = $media->{partitions}[$oem_rescue_idx]; + set_part_real_device($hd, $oem_rescue); mkdir_p($live->{mnt}); - run_('mount', $device, $live->{mnt}) - or die "unable to mount $device\n"; + run_('mount', $oem_rescue->{real_device}, $live->{mnt}) + or die "unable to mount $oem_rescue->{real_device}\n"; - record_rescue_files($live->{mnt}, $device, [ get_rescue_files($live, $live->{oem_rescue}) ]); + record_rescue_files($live->{mnt}, $oem_rescue->{real_device}, [ get_rescue_files($live, $live->{oem_rescue}) ]); - run_('umount', $live->{mnt}); - maybe_umount_device($device); + run_('umount', $oem_rescue->{real_device}); + maybe_umount_device($oem_rescue->{real_device}); + devices::del_loop($oem_rescue->{real_device}) if -f $hd->{file}; } sub get_disk_replicator_path { @@ -1137,30 +1185,40 @@ sub create_usb_replicator { my $size = fold_left { $::a + $::b } map { directory_usage($_, 'apparent') } keys(%files); $live->{replicator}{media}->supplement_partitions($size); - my @loops = allocate_master($live, $live->{replicator}{media}, $dest); - my $slash_idx = $live->{replicator}{media}->find_partition_index('/'); - my $opts = { device => $loops[$slash_idx], disk_device => $dest, append => $live->{replicator}{append} }; - record_usb_replicator($live, $opts); - run_('losetup', '-d', $_) foreach @loops; + allocate_master($live, $live->{replicator}{media}, $dest); + record_usb_replicator($live, {}); } sub record_usb_replicator { my ($live, $opts) = @_; + my $media = $live->{replicator}{media}; my $media_boot = $live->get_media_prefix('boot'); - my $device = get_media_device($live, $opts) + + $opts->{append} ||= $live->{replicator}{append}; + $opts->{device} ||= get_disk_replicator_path($live); + my $main_device = get_media_device($live, $opts) or die "unable to find recording device (missing label? try with --device )\n"; + + my $hd = get_hd_from_file($media, $main_device); + guess_media_partitions_start($media, $hd); + + my $slash_idx = $media->find_partition_index('/'); + my $slash = $media->{partitions}[$slash_idx]; + set_part_real_device($hd, $slash); + mkdir_p($live->{mnt}); - run_('mount', $device, $live->{mnt}) - or die "unable to mount $device\n"; + run_('mount', $slash->{real_device}, $live->{mnt}) + or die "unable to mount $slash->{real_device}\n"; rm_rf($live->{mnt} . $media_boot) if -e $live->{mnt} . $media_boot; - install_usb_bootloader($live, $media, $opts->{device}, $opts); + install_usb_bootloader($live, $media, $slash->{real_device}, $opts); - record_rescue_files($live->{mnt}, $device, [ get_disk_replicator_files($live) ]); + record_rescue_files($live->{mnt}, $slash->{real_device}, [ get_disk_replicator_files($live) ]); output_p($live->{mnt} . "/images/list", "EN,English," . basename(get_disk_image_path($live)) . ",on\n"); - run_('umount', $live->{mnt}); - maybe_umount_device($device); + run_('umount', $slash->{real_device}); + maybe_umount_device($slash->{real_device}); + devices::del_loop($slash->{real_device}) if -f $hd->{file}; } sub create_cdrom_replicator { -- cgit v1.2.1