Completed parted and GPT support
authorJamie Cameron <jcameron@webmin.com>
Sat, 28 May 2011 02:44:13 +0000 (19:44 -0700)
committerJamie Cameron <jcameron@webmin.com>
Sat, 28 May 2011 02:44:13 +0000 (19:44 -0700)
fdisk/CHANGELOG
fdisk/edit_disk.cgi
fdisk/edit_part.cgi
fdisk/edit_relabel.cgi [new file with mode: 0644]
fdisk/fdisk-lib.pl
fdisk/lang/en
fdisk/relabel.cgi [new file with mode: 0644]
fdisk/save_part.cgi
lvm/lvm-lib.pl

index 76cb05b..b03ccee 100644 (file)
@@ -26,3 +26,5 @@ Added support for new SCSI device information files under /sys, as seen in 2.6.3
 ---- Changes since 1.500 ----
 Added support for creating EXT4 filesystems.
 SATA devices using SCSI emulution now show up with SATA as the description.
+---- Changes since 1.550 ----
+Added support for using parted to manage disks if installed, which also supports the new GPT partition table format which is needed on disks larger than 2T.
index c6a36dc..0253da8 100755 (executable)
@@ -36,7 +36,7 @@ if ($extended) {
        push(@edlinks, "<a href=\"edit_part.cgi?disk=$d->{'index'}&new=2\">".
                       $text{'index_addlog'}."</a>");
        }
-elsif ($usedpri != 4) {
+elsif ($usedpri != 4 && &supports_extended()) {
        push(@edlinks, "<a href=\"edit_part.cgi?disk=$d->{'index'}&new=3\">".
                        $text{'index_addext'}."</a>");
        }
@@ -50,6 +50,9 @@ if ($d->{'model'}) {
        push(@info, &text('disk_model', $d->{'model'}));
        }
 push(@info, &text('disk_cylinders', $d->{'cylinders'}));
+if ($d->{'table'}) {
+       push(@info, &text('disk_table', uc($d->{'table'})));
+       }
 print &ui_links_row(\@info),"<p>\n";
 
 # Show table of partitions, if any
@@ -146,6 +149,11 @@ if (&supports_smart($d)) {
                              $text{'index_smartdesc'},
                              &ui_hidden("drive", $d->{'device'}));
        }
+if (&supports_relabel($d)) {
+       print &ui_buttons_row("edit_relabel.cgi", $text{'index_relabel'},
+                             $text{'index_relabeldesc'},
+                             &ui_hidden("device", $d->{'device'}));
+       }
 print &ui_buttons_end();
 
 &ui_print_footer("", $text{'index_return'});
index 986d9ca..d7d91a5 100755 (executable)
@@ -279,5 +279,6 @@ if (!$in{'new'} && !$pinfo->{'extended'}) {
        print &ui_buttons_end();
        }
 
-&ui_print_footer("", $text{'index_return'});
+&ui_print_footer("edit_disk.cgi?device=$dinfo->{'device'}",
+                $text{'disk_return'});
 
diff --git a/fdisk/edit_relabel.cgi b/fdisk/edit_relabel.cgi
new file mode 100644 (file)
index 0000000..3468c03
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/local/bin/perl
+# Show a form to re-write a disks partition table
+
+require './fdisk-lib.pl';
+&ReadParse();
+&can_edit_disk($in{'device'}) || &error($text{'disk_ecannot'});
+
+# Get the disk
+@disks = &list_disks_partitions();
+($d) = grep { $_->{'device'} eq $in{'device'} } @disks;
+$d || &error($text{'disk_egone'});
+@parts = @{$d->{'parts'}};
+if (!@parts && $d->{'cylinders'} * $d->{'cylsize'} > 2*1024*1024*1024*1024) {
+       # Recommend GPT format for new large disks
+       $d->{'table'} = 'gpt';
+       }
+elsif (!@parts) {
+       $d->{'table'} = $config{'format'};
+       }
+
+&ui_print_header($d->{'desc'}, $text{'relabel_title'}, "");
+
+print "<b>",&text('relabel_warn', $d->{'desc'}, $d->{'device'}),"</b><p>\n";
+
+print &ui_form_start("relabel.cgi");
+print &ui_hidden("device", $in{'device'});
+print &ui_table_start(undef, undef, 2);
+
+print &ui_table_row($text{'relabel_parts'},
+       join(", ", map { &tag_name($_->{'type'})." ".
+                        &nice_size(($_->{'end'} - $_->{'start'} + 1) *
+                                   $d->{'cylsize'}) } @parts) ||
+       $text{'relabel_noparts'});
+
+print &ui_table_row($text{'relabel_table'},
+       &ui_select("table", $d->{'table'},
+                  [ map { [ $_, $text{'table_'.$_} || uc($_) ] }
+                        &list_table_types($d) ]));
+
+print &ui_table_end();
+print &ui_form_end([ [ undef, $text{'relabel_ok'} ] ]);
+
+&ui_print_footer("edit_disk.cgi?device=$dinfo->{'device'}",
+                $text{'disk_return'});
+
index ec99599..77e0a68 100755 (executable)
@@ -213,8 +213,9 @@ closedir(IDS);
 local $devs = join(" ", @devs);
 local ($disk, $m2);
 if ($has_parted) {
-       open(FDISK, join(" ; ", map { "parted $_ unit cyl print 2>/dev/null" }
-                                   @devs)." |");
+       open(FDISK, join(" ; ",
+               map { "parted $_ unit cyl print 2>/dev/null || ".
+                     "fdisk -l $_ 2>/dev/null" } @devs)." |");
        }
 else {
        open(FDISK, "fdisk -l $devs 2>/dev/null |");
@@ -233,7 +234,8 @@ while(<FDISK>) {
                elsif ($m2) {
                        # New style fdisk
                        $disk = { 'device' => $1,
-                                 'prefix' => $1 };
+                                 'prefix' => $1,
+                                 'table' => 'msdos', };
                        <FDISK> =~ /(\d+)\s+\S+\s+(\d+)\s+\S+\s+(\d+)/ || next;
                        $disk->{'heads'} = $1;
                        $disk->{'sectors'} = $2;
@@ -245,7 +247,8 @@ while(<FDISK>) {
                                  'prefix' => $1,
                                  'heads' => $2,
                                  'sectors' => $3,
-                                 'cylinders' => $4 };
+                                 'cylinders' => $4,
+                                 'table' => 'msdos', };
                        }
                $disk->{'index'} = scalar(@disks);
                $disk->{'parts'} = [ ];
@@ -1309,6 +1312,7 @@ else { return " $_[2] $in{$_[0]}"; }
        'e3', 'DOS read-only',
        'e4', 'SpeedStor',
        'eb', 'BeOS',
+       'ee', 'GPT',
        'f1', 'SpeedStor',
        'f4', 'SpeedStor large partition',
        'f2', 'DOS secondary',
@@ -1455,6 +1459,36 @@ if ($has_xfs_db && ($_[2] eq "xfs" || !$_[2])) {
 return 0;
 }
 
+# set_name(&disk, &partition, name)
+# Sets the name of a partition, for partition types that support it
+sub set_name
+{
+my ($dinfo, $pinfo, $name) = @_;
+my $cmd = "parted -s ".$dinfo->{'device'}." name ".$pinfo->{'number'}." ";
+if ($name) {
+       $cmd .= quotemeta($name);
+       }
+else {
+       $cmd .= " '\"\"'";
+       }
+my $out = &backquote_logged("$cmd </dev/null 2>&1");
+if ($?) {
+       &error("$cmd failed : $out");
+       }
+}
+
+# set_partition_table(device, table-type)
+# Wipe and re-create the partition table on some disk
+sub set_partition_table
+{
+my ($disk, $table) = @_;
+my $cmd = "parted -s ".$disk." mktable ".$table;
+my $out = &backquote_logged("$cmd </dev/null 2>&1");
+if ($?) {
+       &error("$cmd failed : $out");
+       }
+}
+
 # supports_label(&partition)
 # Returns 1 if the label can be set on a partition
 sub supports_label
@@ -1478,6 +1512,13 @@ local ($d) = @_;
 return $d->{'type'} eq 'ide' || $d->{'type'} eq 'scsi' && $d->{'model'} =~ /ATA/;
 }
 
+# supports_relabel(&disk)
+# Return 1 if a disk can have it's partition table re-written
+sub supports_relabel
+{
+return $has_parted ? 1 : 0;
+}
+
 # supports_smart(&disk)
 sub supports_smart
 {
@@ -1485,3 +1526,24 @@ return &foreign_installed("smart-status") &&
        &foreign_available("smart-status");
 }
 
+# supports_extended(&disk)
+# Return 1 if some disk can support extended partitions
+sub supports_extended
+{
+my ($disk) = @_;
+return $disk->{'label'} eq 'msdos' ? 1 : 0;
+}
+
+# list_table_types(&disk)
+# Returns the list of supported partition table types for a disk
+sub list_table_types
+{
+if ($has_parted) {
+       return ( 'msdos', 'gpt', 'bsd', 'dvh', 'loop', 'mac', 'pc98', 'sun' );
+       }
+else {
+       return ( 'msdos' );
+       }
+}
+
+1;
index 382bd5c..a37a22c 100644 (file)
@@ -25,6 +25,8 @@ index_hdparm=Edit IDE parameters
 index_hdparmdesc=Change settings for an IDE drive, such as the DMA mode, standby timeout and number of sectors read.
 index_smart=Show SMART status
 index_smartdesc=Displays the status reported by this drive, including temperature and error rates.
+index_relabel=Wipe Partitions
+index_relabeldesc=Delete all existing partitions and create a new partition table with a different format.
 index_use=Use
 index_free=Free
 index_return=disk list
@@ -269,6 +271,17 @@ disk_size=Size
 disk_dsize=<b>Disk size:</b> $1
 disk_model=<b>Make and model:</b> $1
 disk_cylinders=<b>Cylinders:</b> $1
+disk_table=<b>Partition format:</b> $1
 disk_return=list of partitions
 
+relabel_title=Wipe Partitions
+relabel_warn=Are you sure you want to wipe all partitions on $1 ($2) by re-writing the disk label? All existing data and filesystems will be lost!
+relabel_parts=Existing partitions
+relabel_noparts=None created yet
+relabel_table=Partition table format
+relabel_ok=Wipe and Re-Label
+
+table_msdos=MS-DOS (Standard partition format)
+table_gpt=GPT (For 2T or larger disks)
+
 __norefs=1
diff --git a/fdisk/relabel.cgi b/fdisk/relabel.cgi
new file mode 100644 (file)
index 0000000..db626f0
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/local/bin/perl
+# Re-write the partition table
+
+require './fdisk-lib.pl';
+&ReadParse();
+&can_edit_disk($in{'device'}) || &error($text{'disk_ecannot'});
+
+# Get the disk
+@disks = &list_disks_partitions();
+($d) = grep { $_->{'device'} eq $in{'device'} } @disks;
+$d || &error($text{'disk_egone'});
+
+# Wipe the partition
+&set_partition_table($d->{'device'}, $in{'table'});
+&redirect("edit_disk.cgi?device=$in{'device'}");
index 809dacb..647cfca 100755 (executable)
@@ -47,6 +47,9 @@ elsif (!$in{'new'}) {
        if (defined($in{'label'}) && &supports_label($pinfo)) {
                &set_label($pinfo->{'device'}, $in{'label'});
                }
+       if (defined($in{'name'}) && &supports_name($dinfo)) {
+               &set_name($dinfo, $pinfo, $in{'name'});
+               }
        &webmin_log("modify", "part", $dinfo->{'device'}, \%in);
        &redirect("edit_disk.cgi?device=$dinfo->{'device'}");
        }
@@ -82,11 +85,15 @@ else {
        else {
                &create_partition($dinfo->{'device'}, $in{'newpart'},
                                  $in{'start'}, $in{'end'}, $in{'type'});
-               $pinfo = { 'type' => $in{'type'} };
+               $pinfo = { 'type' => $in{'type'},
+                          'number' => $in{'newpart'} };
                if ($in{'label'} && &supports_label($pinfo)) {
                        local $dev = $dinfo->{'prefix'}.$in{'newpart'};
                        &set_label($dev, $in{'label'});
                        }
+               if ($in{'name'} && &supports_name($dinfo)) {
+                       &set_name($dinfo, $pinfo, $in{'name'});
+                       }
                &webmin_log("create", "part", $dinfo->{'device'}, \%in);
                }
        if (&need_reboot($dinfo)) {
index 303ded8..c670836 100755 (executable)
@@ -726,7 +726,7 @@ foreach $d (&fdisk::list_disks_partitions()) {
                next if ($used{$p->{'device'}} || $p->{'extended'});
                local @ds = &device_status($p->{'device'});
                next if (@ds);
-               if ($p->{'type'} eq '83') {
+               if ($p->{'type'} eq '83' || $p->{'type'} eq 'ext2') {
                        local $label = &fdisk::get_label($p->{'device'});
                        next if ($used{"LABEL=$label"});
                        }