summaryrefslogtreecommitdiffstats
path: root/perl-install/partition_table.pm
diff options
context:
space:
mode:
authorMystery Man <unknown@mandriva.org>2004-11-06 08:30:59 +0000
committerMystery Man <unknown@mandriva.org>2004-11-06 08:30:59 +0000
commit42e38e074bf1200783849ea85e205e6614f988d7 (patch)
tree3c218a7ef3c66c8064eb2f6fa84ef44cef7b55a6 /perl-install/partition_table.pm
parenta4a67fd68bcffc42eb98871618c8f07b55157d5e (diff)
downloaddrakx-42e38e074bf1200783849ea85e205e6614f988d7.tar
drakx-42e38e074bf1200783849ea85e205e6614f988d7.tar.gz
drakx-42e38e074bf1200783849ea85e205e6614f988d7.tar.bz2
drakx-42e38e074bf1200783849ea85e205e6614f988d7.tar.xz
drakx-42e38e074bf1200783849ea85e205e6614f988d7.zip
This commit was manufactured by cvs2svn to create branch 'a'.topic/a
Diffstat (limited to 'perl-install/partition_table.pm')
-rw-r--r--perl-install/partition_table.pm627
1 files changed, 0 insertions, 627 deletions
diff --git a/perl-install/partition_table.pm b/perl-install/partition_table.pm
deleted file mode 100644
index 1d5e87e47..000000000
--- a/perl-install/partition_table.pm
+++ /dev/null
@@ -1,627 +0,0 @@
-package partition_table; # $Id$
-
-use diagnostics;
-use strict;
-
-use common;
-use fs::type;
-use partition_table::raw;
-use detect_devices;
-use log;
-
-our @fields2save = qw(primary extended totalsectors isDirty will_tell_kernel);
-
-
-sub hd2minimal_part {
- my ($hd) = @_;
- {
- rootDevice => $hd->{device},
- if_($hd->{usb_media_type}, is_removable => 1),
- };
-}
-
-#- works for both hard drives and partitions ;p
-sub description {
- my ($hd) = @_;
- my $win = $hd->{device_windobe};
-
- sprintf "%s%s (%s%s%s%s)",
- $hd->{device},
- $win && " [$win:]",
- formatXiB($hd->{totalsectors} || $hd->{size}, 512),
- $hd->{info} && ", $hd->{info}",
- $hd->{mntpoint} && ", " . $hd->{mntpoint},
- $hd->{fs_type} && ", $hd->{fs_type}";
-}
-
-sub isPrimary {
- my ($part, $hd) = @_;
- foreach (@{$hd->{primary}{raw}}) { $part eq $_ and return 1 }
- 0;
-}
-
-sub adjustStartAndEnd {
- my ($hd, $part) = @_;
-
- $hd->adjustStart($part);
- $hd->adjustEnd($part);
-}
-
-sub verifyNotOverlap {
- my ($a, $b) = @_;
- $a->{start} + $a->{size} <= $b->{start} || $b->{start} + $b->{size} <= $a->{start};
-}
-sub verifyInside {
- my ($a, $b) = @_;
- $b->{start} <= $a->{start} && $a->{start} + $a->{size} <= $b->{start} + $b->{size};
-}
-
-sub verifyParts_ {
- foreach my $i (@_) {
- foreach (@_) {
- next if !$i || !$_ || $i == $_ || isWholedisk($i) || isExtended($i); #- avoid testing twice for simplicity :-)
- if (isWholedisk($_)) {
- verifyInside($i, $_) or
- cdie sprintf("partition sector #$i->{start} (%s) is not inside whole disk (%s)!",
- formatXiB($i->{size}, 512), formatXiB($_->{size}, 512));
- } elsif (isExtended($_)) {
- verifyNotOverlap($i, $_) or
- log::l(sprintf("warning partition sector #$i->{start} (%s) is overlapping with extended partition!",
- formatXiB($i->{size}, 512))); #- only warning for this one is acceptable
- } else {
- verifyNotOverlap($i, $_) or
- cdie sprintf("partitions sector #$i->{start} (%s) and sector #$_->{start} (%s) are overlapping!",
- formatXiB($i->{size}, 512), formatXiB($_->{size}, 512));
- }
- }
- }
-}
-sub verifyParts {
- my ($hd) = @_;
- verifyParts_(get_normal_parts($hd));
-}
-sub verifyPrimary {
- my ($pt) = @_;
- $_->{start} > 0 || arch() =~ /^sparc/ || die "partition must NOT start at sector 0" foreach @{$pt->{normal}};
- verifyParts_(@{$pt->{normal}}, $pt->{extended});
-}
-
-sub compute_device_name {
- my ($part, $hd) = @_;
- $part->{device} = $hd->{prefix} . $part->{part_number};
- $part->{devfs_device} = $hd->{devfs_prefix} . '/part' . $part->{part_number};
-}
-
-sub assign_device_numbers {
- my ($hd) = @_;
-
- my $i = 1;
- my $start = 1;
-
- #- on PPC we need to assign device numbers to the holes too - big FUN!
- #- not if it's an IBM machine using a DOS partition table though
- if (arch() =~ /ppc/ && detect_devices::get_mac_model() !~ /^IBM/) {
- #- first sort the normal parts
- $hd->{primary}{normal} = [ sort { $a->{start} <=> $b->{start} } @{$hd->{primary}{normal}} ];
-
- #- now loop through them, assigning partition numbers - reserve one for the holes
- foreach (@{$hd->{primary}{normal}}) {
- if ($_->{start} > $start) {
- log::l("PPC: found a hole on $hd->{prefix} before $_->{start}, skipping device...");
- $i++;
- }
- $_->{part_number} = $i;
- compute_device_name($_, $hd);
- $start = $_->{start} + $_->{size};
- $i++;
- }
- } else {
- foreach (@{$hd->{primary}{raw}}) {
- $_->{part_number} = $i;
- compute_device_name($_, $hd);
- $i++;
- }
- foreach (map { $_->{normal} } @{$hd->{extended} || []}) {
- my $dev = $hd->{prefix} . $i;
- my $renumbered = $_->{device} && $dev ne $_->{device};
- if ($renumbered) {
- require fs;
- eval { fs::umount_part($_) }; #- at least try to umount it
- will_tell_kernel($hd, del => $_, 'delay_del');
- push @{$hd->{partitionsRenumbered}}, [ $_->{device}, $dev ];
- }
- $_->{part_number} = $i;
- compute_device_name($_, $hd);
- if ($renumbered) {
- will_tell_kernel($hd, add => $_, 'delay_add');
- }
- $i++;
- }
- }
-
- #- try to figure what the windobe drive letter could be!
- #
- #- first verify there's at least one primary dos partition, otherwise it
- #- means it is a secondary disk and all will be false :(
- #-
- my ($c, @others) = grep { isFat_or_NTFS($_) } @{$hd->{primary}{normal}};
-
- $i = ord 'C';
- $c->{device_windobe} = chr($i++) if $c;
- $_->{device_windobe} = chr($i++) foreach grep { isFat_or_NTFS($_) } map { $_->{normal} } @{$hd->{extended}};
- $_->{device_windobe} = chr($i++) foreach @others;
-}
-
-sub remove_empty_extended {
- my ($hd) = @_;
- my $last = $hd->{primary}{extended} or return;
- @{$hd->{extended}} = grep {
- if ($_->{normal}) {
- $last = $_;
- } else {
- %{$last->{extended}} = $_->{extended} ? %{$_->{extended}} : ();
- }
- $_->{normal};
- } @{$hd->{extended}};
- adjust_main_extended($hd);
-}
-
-sub adjust_main_extended {
- my ($hd) = @_;
-
- if (!is_empty_array_ref $hd->{extended}) {
- my ($l, @l) = @{$hd->{extended}};
-
- # the first is a special case, must recompute its real size
- my $start = round_down($l->{normal}{start} - 1, $hd->{geom}{sectors});
- my $end = $l->{normal}{start} + $l->{normal}{size};
- my $only_linux = 1; my $has_win_lba = 0;
- foreach (map { $_->{normal} } $l, @l) {
- $start = min($start, $_->{start});
- $end = max($end, $_->{start} + $_->{size});
- $only_linux &&= isTrueLocalFS($_) || isSwap($_);
- $has_win_lba ||= $_->{pt_type} == 0xc || $_->{pt_type} == 0xe;
- }
- $l->{start} = $hd->{primary}{extended}{start} = $start;
- $l->{size} = $hd->{primary}{extended}{size} = $end - $start;
- }
- if (!@{$hd->{extended} || []} && $hd->{primary}{extended}) {
- will_tell_kernel($hd, del => $hd->{primary}{extended});
- %{$hd->{primary}{extended}} = (); #- modify the raw entry
- delete $hd->{primary}{extended};
- }
- verifyParts($hd); #- verify everything is all right
-}
-
-sub adjust_local_extended {
- my ($hd, $part) = @_;
-
- my $extended = find { $_->{normal} == $part } @{$hd->{extended} || []} or return;
- $extended->{size} = $part->{size} + $part->{start} - $extended->{start};
-
- #- must write it there too because values are not shared
- my $prev = find { $_->{extended}{start} == $extended->{start} } @{$hd->{extended} || []} or return;
- $prev->{extended}{size} = $part->{size} + $part->{start} - $prev->{extended}{start};
-}
-
-sub get_normal_parts {
- my ($hd) = @_;
-
- @{$hd->{primary}{normal} || []}, map { $_->{normal} } @{$hd->{extended} || []}
-}
-
-sub get_normal_parts_and_holes {
- my ($hd) = @_;
- my ($start, $last) = ($hd->first_usable_sector, $hd->last_usable_sector);
-
- ref($hd) or print("get_normal_parts_and_holes: bad hd" . backtrace(), "\n");
-
- my $minimal_hole = put_in_hash({ pt_type => 0 }, hd2minimal_part($hd));
-
- my @l = map {
- my $current = $start;
- $start = $_->{start} + $_->{size};
- my $hole = { start => $current, size => $_->{start} - $current, %$minimal_hole };
- put_in_hash($hole, hd2minimal_part($hd));
- $hole, $_;
- } sort { $a->{start} <=> $b->{start} } grep { !isWholedisk($_) } get_normal_parts($hd);
-
- push @l, { start => $start, size => $last - $start, %$minimal_hole };
- grep { $_->{pt_type} || $_->{size} >= $hd->cylinder_size } @l;
-}
-
-sub read_one($$) {
- my ($hd, $sector) = @_;
- my ($pt, $info);
-
- #- it can be safely considered that the first sector is used to probe the partition table
- #- but other sectors (typically for extended partition ones) have to match this type!
- if (!$sector) {
- my @parttype = (
- if_(arch() =~ /^ia64/, 'gpt'),
- arch() =~ /^sparc/ ? ('sun', 'bsd') : ('dos', 'bsd', 'sun', 'mac'),
- );
- foreach ('empty', @parttype, 'lvm_PV', 'unknown') {
- /unknown/ and die "unknown partition table format on disk " . $hd->{file};
- eval {
- # perl_checker: require partition_table::bsd
- # perl_checker: require partition_table::dos
- # perl_checker: require partition_table::empty
- # perl_checker: require partition_table::gpt
- # perl_checker: require partition_table::lvm_PV
- # perl_checker: require partition_table::mac
- # perl_checker: require partition_table::sun
- require "partition_table/$_.pm";
- bless $hd, "partition_table::$_";
- ($pt, $info) = $hd->read($sector);
- log::l("found a $_ partition table on $hd->{file} at sector $sector");
- };
- $@ or last;
- }
- } else {
- #- keep current blessed object for that, this means it is neccessary to read sector 0 before.
- ($pt, $info) = $hd->read($sector);
- }
-
- my @extended = $hd->hasExtended ? grep { isExtended($_) } @$pt : ();
- my @normal = grep { $_->{size} && $_->{pt_type} && !isExtended($_) } @$pt;
- my $nb_special_empty = int(grep { $_->{size} && $_->{pt_type} == 0 } @$pt);
-
- @extended > 1 and die "more than one extended partition";
-
- put_in_hash($_, hd2minimal_part($hd)) foreach @normal, @extended;
- { raw => $pt, extended => $extended[0], normal => \@normal, info => $info, nb_special_empty => $nb_special_empty };
-}
-
-sub read {
- my ($hd) = @_;
- my $pt = read_one($hd, 0) or return 0;
- $hd->{primary} = $pt;
- undef $hd->{extended};
- verifyPrimary($pt);
- eval {
- my $need_removing_empty_extended;
- if ($pt->{extended}) {
- read_extended($hd, $pt->{extended}, \$need_removing_empty_extended) or return 0;
- }
- if ($need_removing_empty_extended) {
- #- special case when hda5 is empty, it must be skipped
- #- (windows XP generates such partition tables)
- remove_empty_extended($hd); #- includes adjust_main_extended
- }
-
- };
- die "extended partition: $@" if $@;
-
- assign_device_numbers($hd);
- remove_empty_extended($hd);
-
- $hd->set_best_geometry_for_the_partition_table;
- 1;
-}
-
-sub read_extended {
- my ($hd, $extended, $need_removing_empty_extended) = @_;
-
- my $pt = read_one($hd, $extended->{start}) or return 0;
- $pt = { %$extended, %$pt };
-
- push @{$hd->{extended}}, $pt;
- @{$hd->{extended}} > 100 and die "oops, seems like we're looping here :( (or you have more than 100 extended partitions!)";
-
- if (@{$pt->{normal}} == 0) {
- $$need_removing_empty_extended = 1;
- delete $pt->{normal};
- print "need_removing_empty_extended\n";
- } elsif (@{$pt->{normal}} > 1) {
- die "more than one normal partition in extended partition";
- } else {
- $pt->{normal} = $pt->{normal}[0];
- #- in case of extended partitions, the start sector is local to the partition or to the first extended_part!
- $pt->{normal}{start} += $pt->{start};
-
- #- the following verification can broke an existing partition table that is
- #- correctly read by fdisk or cfdisk. maybe the extended partition can be
- #- recomputed to get correct size.
- if (!verifyInside($pt->{normal}, $extended)) {
- $extended->{size} = $pt->{normal}{start} + $pt->{normal}{size};
- verifyInside($pt->{normal}, $extended) or die "partition $pt->{normal}{device} is not inside its extended partition";
- }
- }
-
- if ($pt->{extended}) {
- $pt->{extended}{start} += $hd->{primary}{extended}{start};
- return read_extended($hd, $pt->{extended}, $need_removing_empty_extended);
- } else {
- 1;
- }
-}
-
-sub will_tell_kernel {
- my ($hd, $action, $o_part, $o_delay) = @_;
-
- if ($action eq 'resize') {
- will_tell_kernel($hd, del => $o_part);
- will_tell_kernel($hd, add => $o_part);
- } else {
- my $part_number = sub { $o_part->{device} =~ /(\d+)$/ ? $1 : internal_error("bad device " . description($o_part)) };
- push @{$hd->{'will_tell_kernel' . ($o_delay || '')} ||= []},
- [
- $action,
- $action eq 'force_reboot' ? () :
- $action eq 'add' ? ($part_number->(), $o_part->{start}, $o_part->{size}) :
- $action eq 'del' ? $part_number->() :
- internal_error("unknown action $action")
- ];
- }
- if (!$o_delay) {
- foreach my $delay ('delay_del', 'delay_add') {
- my $l = delete $hd->{"will_tell_kernel$delay"} or next;
- push @{$hd->{will_tell_kernel} ||= []}, @$l;
- }
- }
- $hd->{isDirty} = 1;
-}
-
-sub tell_kernel {
- my ($hd, $tell_kernel) = @_;
-
- my $F = partition_table::raw::openit($hd);
-
- my $force_reboot = any { $_->[0] eq 'force_reboot' } @$tell_kernel;
- if (!$force_reboot) {
- foreach (@$tell_kernel) {
- my ($action, $part_number, $o_start, $o_size) = @$_;
-
- if ($action eq 'add') {
- $force_reboot ||= !c::add_partition(fileno $F, $part_number, $o_start, $o_size);
- } elsif ($action eq 'del') {
- $force_reboot ||= !c::del_partition(fileno $F, $part_number);
- }
- log::l("tell kernel $action ($hd->{device} $part_number $o_start $o_size), rebootNeeded is now " . bool2text($hd->{rebootNeeded}));
- }
- }
- if ($force_reboot) {
- my @magic_parts = grep { $_->{isMounted} && $_->{real_mntpoint} } get_normal_parts($hd);
- foreach (@magic_parts) {
- syscall_('umount', $_->{real_mntpoint}) or log::l(N("error unmounting %s: %s", $_->{real_mntpoint}, $!));
- }
- $hd->{rebootNeeded} = !ioctl($F, c::BLKRRPART(), 0);
- log::l("tell kernel force_reboot ($hd->{device}), rebootNeeded is now $hd->{rebootNeeded}.");
-
- foreach (@magic_parts) {
- syscall_('mount', $_->{real_mntpoint}, $_->{fs_type}, c::MS_MGC_VAL()) or log::l(N("mount failed: ") . $!);
- }
- }
-}
-
-# write the partition table
-sub write {
- my ($hd) = @_;
- $hd->{isDirty} or return;
- $hd->{readonly} and die "a read-only partition table should not be dirty!";
-
- #- set first primary partition active if no primary partitions are marked as active.
- if (my @l = @{$hd->{primary}{raw}}) {
- foreach (@l) {
- $_->{local_start} = $_->{start};
- $_->{active} ||= 0;
- }
- $l[0]{active} = 0x80 if !any { $_->{active} } @l;
- }
-
- #- last chance for verification, this make sure if an error is detected,
- #- it will never be writed back on partition table.
- verifyParts($hd);
-
- $hd->write(0, $hd->{primary}{raw}, $hd->{primary}{info}) or die "writing of partition table failed";
-
- #- should be fixed but a extended exist with no real extended partition, that blanks mbr!
- if (arch() !~ /^sparc/) {
- foreach (@{$hd->{extended}}) {
- # in case of extended partitions, the start sector must be local to the partition
- $_->{normal}{local_start} = $_->{normal}{start} - $_->{start};
- $_->{extended} and $_->{extended}{local_start} = $_->{extended}{start} - $hd->{primary}{extended}{start};
-
- $hd->write($_->{start}, $_->{raw}) or die "writing of partition table failed";
- }
- }
- $hd->{isDirty} = 0;
- $hd->{hasBeenDirty} = 1; #- used in undo (to know if undo should believe isDirty or not)
-
- if (my $tell_kernel = delete $hd->{will_tell_kernel}) {
- tell_kernel($hd, $tell_kernel);
- }
-}
-
-sub active {
- my ($hd, $part) = @_;
-
- $_->{active} = 0 foreach @{$hd->{primary}{normal}};
- $part->{active} = 0x80;
- $hd->{isDirty} = 1;
-}
-
-
-# remove a normal partition from hard drive hd
-sub remove {
- my ($hd, $part) = @_;
- my $i;
-
- #- first search it in the primary partitions
- $i = 0; foreach (@{$hd->{primary}{normal}}) {
- if ($_ eq $part) {
- will_tell_kernel($hd, del => $_);
-
- splice(@{$hd->{primary}{normal}}, $i, 1);
- %$_ = (); #- blank it
-
- $hd->raw_removed($hd->{primary}{raw});
- return 1;
- }
- $i++;
- }
-
- my ($first, $second, $third) = map { $_->{normal} } @{$hd->{extended} || []};
- if ($third && $first eq $part) {
- die "Can't handle removing hda5 when hda6 is not the second partition" if $second->{start} > $third->{start};
- }
-
- #- otherwise search it in extended partitions
- foreach (@{$hd->{extended} || []}) {
- $_->{normal} eq $part or next;
-
- delete $_->{normal}; #- remove it
- remove_empty_extended($hd);
- assign_device_numbers($hd);
-
- will_tell_kernel($hd, del => $part);
- return 1;
- }
- 0;
-}
-
-# create of partition at starting at `start', of size `size' and of type `pt_type' (nice comment, uh?)
-sub add_primary {
- my ($hd, $part) = @_;
-
- {
- local $hd->{primary}{normal}; #- save it to fake an addition of $part, that way add_primary do not modify $hd if it fails
- push @{$hd->{primary}{normal}}, $part;
- adjust_main_extended($hd); #- verify
- $hd->raw_add($hd->{primary}{raw}, $part);
- }
- push @{$hd->{primary}{normal}}, $part; #- really do it
-}
-
-sub add_extended {
- arch() =~ /^sparc|ppc/ and die N("Extended partition not supported on this platform");
-
- my ($hd, $part, $extended_type) = @_;
- $extended_type =~ s/Extended_?//;
-
- my $e = $hd->{primary}{extended};
-
- if ($e && !verifyInside($part, $e)) {
- #-die "sorry, can't add outside the main extended partition" unless $::unsafe;
- my $end = $e->{start} + $e->{size};
- my $start = min($e->{start}, $part->{start});
- $end = max($end, $part->{start} + $part->{size}) - $start;
-
- { #- faking a resizing of the main extended partition to test for problems
- local $e->{start} = $start;
- local $e->{size} = $end - $start;
- eval { verifyPrimary($hd->{primary}) };
- $@ and die
-N("You have a hole in your partition table but I can't use it.
-The only solution is to move your primary partitions to have the hole next to the extended partitions.");
- }
- }
-
- if ($e && $part->{start} < $e->{start}) {
- my $l = first(@{$hd->{extended}});
-
- #- the first is a special case, must recompute its real size
- $l->{start} = round_down($l->{normal}{start} - 1, $hd->cylinder_size);
- $l->{size} = $l->{normal}{start} + $l->{normal}{size} - $l->{start};
- my $ext = { %$l };
- unshift @{$hd->{extended}}, { pt_type => 5, raw => [ $part, $ext, {}, {} ], normal => $part, extended => $ext };
- #- size will be autocalculated :)
- } else {
- my ($ext, $ext_size) = is_empty_array_ref($hd->{extended}) ?
- ($hd->{primary}, -1) : #- -1 size will be computed by adjust_main_extended
- (top(@{$hd->{extended}}), $part->{size});
- my %ext = (pt_type => $extended_type || 5, start => $part->{start}, size => $ext_size);
-
- $hd->raw_add($ext->{raw}, \%ext);
- $ext->{extended} = \%ext;
- push @{$hd->{extended}}, { %ext, raw => [ $part, {}, {}, {} ], normal => $part };
- }
- $part->{start}++; $part->{size}--; #- let it start after the extended partition sector
- adjustStartAndEnd($hd, $part);
-
- adjust_main_extended($hd);
-}
-
-sub add {
- my ($hd, $part, $b_primaryOrExtended, $b_forceNoAdjust) = @_;
-
- get_normal_parts($hd) >= ($hd->{device} =~ /^rd/ ? 7 : $hd->{device} =~ /^(sd|ida|cciss|ataraid)/ ? 15 : 63) and cdie "maximum number of partitions handled by linux reached";
-
- set_isFormatted($part, 0);
- put_in_hash($part, hd2minimal_part($hd));
- $part->{start} ||= 1 if arch() !~ /^sparc/; #- starting at sector 0 is not allowed
- adjustStartAndEnd($hd, $part) unless $b_forceNoAdjust;
-
- my $nb_primaries = $hd->{device} =~ /^rd/ ? 3 : 1;
-
- if (arch() =~ /^sparc|ppc/ ||
- $b_primaryOrExtended eq 'Primary' ||
- $b_primaryOrExtended !~ /Extended/ && @{$hd->{primary}{normal} || []} < $nb_primaries) {
- eval { add_primary($hd, $part) };
- goto success if !$@;
- }
- if ($hd->hasExtended) {
- eval { add_extended($hd, $part, $b_primaryOrExtended) };
- goto success if !$@;
- }
- {
- add_primary($hd, $part);
- }
- success:
- assign_device_numbers($hd);
- will_tell_kernel($hd, add => $part);
-}
-
-# search for the next partition
-sub next {
- my ($hd, $part) = @_;
-
- first(
- sort { $a->{start} <=> $b->{start} }
- grep { $_->{start} >= $part->{start} + $part->{size} }
- get_normal_parts($hd)
- );
-}
-sub next_start {
- my ($hd, $part) = @_;
- my $next = &next($hd, $part);
- $next ? $next->{start} : $hd->{totalsectors};
-}
-
-sub load {
- my ($hd, $file, $b_force) = @_;
-
- open(my $F, $file) or die N("Error reading file %s", $file);
-
- my $h;
- {
- local $/ = "\0";
- eval <$F>;
- }
- $@ and die N("Restoring from file %s failed: %s", $file, $@);
-
- ref($h) eq 'ARRAY' or die N("Bad backup file");
-
- my %h; @h{@fields2save} = @$h;
-
- $h{totalsectors} == $hd->{totalsectors} or $b_force or cdie "bad totalsectors";
-
- #- unsure we don't modify totalsectors
- local $hd->{totalsectors};
-
- @$hd{@fields2save} = @$h;
-
- delete @$_{qw(isMounted isFormatted notFormatted toFormat toFormatUnsure)} foreach get_normal_parts($hd);
- will_tell_kernel($hd, 'force_reboot'); #- just like undo, do not force write_partitions so that user can see the new partition table but can still discard it
-}
-
-sub save {
- my ($hd, $file) = @_;
- my @h = @$hd{@fields2save};
- require Data::Dumper;
- eval { output($file, Data::Dumper->Dump([\@h], ['$h']), "\0") }
- or die N("Error writing to file %s", $file);
-}
-
-1;