More work on parted support
authorJamie Cameron <jcameron@webmin.com>
Fri, 27 May 2011 00:31:45 +0000 (17:31 -0700)
committerJamie Cameron <jcameron@webmin.com>
Fri, 27 May 2011 00:31:45 +0000 (17:31 -0700)
fdisk/config [new file with mode: 0644]
fdisk/config.info [new file with mode: 0644]
fdisk/edit_part.cgi
fdisk/fdisk-lib.pl
fdisk/index.cgi
fdisk/lang/en
fdisk/save_part.cgi

diff --git a/fdisk/config b/fdisk/config
new file mode 100644 (file)
index 0000000..65c4748
--- /dev/null
@@ -0,0 +1 @@
+format=msdos
diff --git a/fdisk/config.info b/fdisk/config.info
new file mode 100644 (file)
index 0000000..c6127f3
--- /dev/null
@@ -0,0 +1,2 @@
+mode=Partition management command,1,fdisk-Fdisk,parted-Parted,-Choose automatically
+format=Default partition table format,1,msdos-MSDOS,gpt-GPT
index 73f7bc9..986d9ca 100755 (executable)
@@ -111,9 +111,11 @@ print &ui_table_row($text{'edit_device'}, $dev);
 
 # Partition type
 if ($pinfo->{'extended'} || $in{'new'} == 3) {
+       # Extended, cannot change
        print &ui_table_row($text{'edit_type'}, $text{'extended'});
        }
-else {
+elsif ($pinfo->{'edittype'} || $in{'new'}) {
+       # Can change
        print &ui_table_row($text{'edit_type'},
                &ui_select("type",
                           $in{'new'} ? &default_tag() : $pinfo->{'type'},
@@ -121,6 +123,12 @@ else {
                                 (sort { &tag_name($a) cmp &tag_name($b) }
                                       &list_tags()) ]));
        }
+else {
+       # Tool doesn't allow change
+       print &ui_table_row($text{'edit_type'},
+                           &tag_name($pinfo->{'type'}));
+               
+       }
 
 # Extent and cylinders
 if ($in{'new'}) {
@@ -174,7 +182,7 @@ if (!$in{'new'}) {
        }
 
 # Show field for editing filesystem label
-if (($has_e2label || $has_xfs_db) && $pinfo->{'type'} eq '83' && !$in{'new'}) {
+if (($has_e2label || $has_xfs_db) && &supports_label($pinfo) && !$in{'new'}) {
        local $label = $in{'new'} ? undef : &get_label($pinfo->{'device'});
        if (@stat) {
                print &ui_table_row($text{'edit_label'},
@@ -186,10 +194,16 @@ if (($has_e2label || $has_xfs_db) && $pinfo->{'type'} eq '83' && !$in{'new'}) {
                }
        }
 
+# Show field for partition name
+if (&supports_name($dinfo)) {
+       print &ui_table_row($text{'edit_name'},
+                       &ui_textbox("name", $pinfo->{'name'}, 20));
+       }
+
 # Show current UUID
 if ($has_volid && !$in{'new'}) {
        local $volid = &get_volid($pinfo->{'device'});
-       print &ui_table_row($text{'edit_volid'}, "<tt>$volid</tt>");
+       print &ui_table_row($text{'edit_volid'}, "<tt>$volid</tt>", 3);
        }
 
 print &ui_table_end();
index ab4b47a..ec99599 100755 (executable)
@@ -20,7 +20,15 @@ $has_xfs_db = &has_command("xfs_db");
 $has_volid = &has_command("vol_id");
 $has_reiserfstune = &has_command("reiserfstune");
 $uuid_directory = "/dev/disk/by-uuid";
-$has_parted = !$config{'noparted'} && &has_command("parted");
+if ($config{'mode'} eq 'parted') {
+       $has_parted = 1;
+       }
+elsif ($config{'mode'} eq 'fdisk') {
+       $has_parted = 0;
+       }
+else {
+       $has_parted = !$config{'noparted'} && &has_command("parted");
+       }
 $| = 1;
 
 # list_disks_partitions([include-cds])
@@ -401,23 +409,31 @@ while(<FDISK>) {
                                'end' => $4,
                                'blocks' => int($5),
                                'extended' => $6 eq '5' || $6 eq 'f' ? 1 : 0,
-                               'index' => scalar(@{$disk->{'parts'}}) };
+                               'index' => scalar(@{$disk->{'parts'}}),
+                               'edittype' => 1, };
                $part->{'desc'} = &partition_description($part->{'device'});
                push(@{$disk->{'parts'}}, $part);
                }
-       elsif (/^\s*(\d+)\s+(\d+)cyl\s+(\d+)cyl\s+(\d+)cyl\s+(primary|logical|extended)\s*(\S*)/) {
+       elsif (/^\s*(\d+)\s+(\d+)cyl\s+(\d+)cyl\s+(\d+)cyl(\s+(primary|logical|extended))?\s*(\S*)\s*(\S*)/) {
                # Partition within the current disk from parted
                local $part = { 'number' => $1,
                                'device' => $disk->{'device'}.$1,
-                               'type' => $6,
+                               'type' => $7,
                                'start' => $2+1,
                                'end' => $3+1,
                                'blocks' => $4 * $disk->{'cylsize'},
-                               'extended' => $5 eq 'extended' ? 1 : 0,
-                               'index' => scalar(@{$disk->{'parts'}}) };
+                               'extended' => $6 eq 'extended' ? 1 : 0,
+                               'index' => scalar(@{$disk->{'parts'}}),
+                               'name' => $8,
+                               'edittype' => 0, };
+               $part->{'type'} = 'ext2' if ($part->{'type'} =~ /^ext/);
                $part->{'desc'} = &partition_description($part->{'device'});
                push(@{$disk->{'parts'}}, $part);
                }
+       elsif (/Partition\s+Table:\s+(\S+)/) {
+               # Parted partition table type
+               $disk->{'table'} = $1;
+               }
        }
 close(FDISK);
 
@@ -547,7 +563,7 @@ sub delete_partition
 my ($disk, $part) = @_;
 if ($has_parted) {
        # Using parted
-       my $cmd = "parted ".$disk." rm ".$part;
+       my $cmd = "parted -s ".$disk." rm ".$part;
        my $out = &backquote_logged("$cmd </dev/null 2>&1");
        if ($?) {
                &error("$cmd failed : $out");
@@ -576,7 +592,15 @@ my ($disk, $part, $start, $end, $type) = @_;
 if ($has_parted) {
        # Using parted
        my $pe = $part > 4 ? "logical" : "primary";
-       my $cmd = "parted ".$disk." unit cyl mkpartfs ".$pe." ".$type." ".($start-1)." ".$end;
+       my $cmd;
+       if ($type) {
+               $cmd = "parted -s ".$disk." unit cyl mkpartfs ".$pe." ".
+                      $type." ".($start-1)." ".$end;
+               }
+       else {
+               $cmd = "parted -s ".$disk." unit cyl mkpart ".$pe." ".
+                      ($start-1)." ".$end;
+               }
        my $out = &backquote_logged("$cmd </dev/null 2>&1");
        if ($?) {
                &error("$cmd failed : $out");
@@ -616,23 +640,38 @@ undef(@list_disks_partitions_cache);
 }
 
 # create_extended(disk, partition, start, end)
+# Create a new extended partition
 sub create_extended
 {
-&open_fdisk("$_[0]");
-&wprint("n\n");
-&wait_for($fh, 'primary.*\r\n');
-&wprint("e\n");
-&wait_for($fh, 'Partition.*:');
-&wprint("$_[1]\n");
-&wait_for($fh, 'First.*:');
-&wprint("$_[2]\n");
-&wait_for($fh, 'Last.*:');
-&wprint("$_[3]\n");
-&wait_for($fh, 'Command.*:');
+my ($disk, $part, $start, $end) = @_;
+if ($has_parted) {
+       # Create using parted
+       my $cmd = "parted -s ".$disk." unit cyl mkpart extended ".
+                 ($start-1)." ".$end;
+       my $out = &backquote_logged("$cmd </dev/null 2>&1");
+       if ($?) {
+               &error("$cmd failed : $out");
+               }
+       }
+else {
+       # Use classic fdisk
+       &open_fdisk($disk);
+       &wprint("n\n");
+       &wait_for($fh, 'primary.*\r\n');
+       &wprint("e\n");
+       &wait_for($fh, 'Partition.*:');
+       &wprint("$part\n");
+       &wait_for($fh, 'First.*:');
+       &wprint("$start\n");
+       &wait_for($fh, 'Last.*:');
+       &wprint("$end\n");
+       &wait_for($fh, 'Command.*:');
 
-&wprint("w\n");
-&wait_for($fh, 'Syncing'); sleep(3);
-&close_fdisk();
+       &wprint("w\n");
+       &wait_for($fh, 'Syncing');
+       sleep(3);
+       &close_fdisk();
+       }
 undef(@list_disks_partitions_cache);
 }
 
@@ -666,14 +705,59 @@ return $has_parted ? 'ext2' : '83';
 # Given a partition tag, returns the filesystem type (assuming it is supported)
 sub conv_type
 {
-local @rv;
-if ($_[0] eq "4" || $_[0] eq "6" ||
-    $_[0] eq "1" || $_[0] eq "e") { @rv = ( "msdos" ); }
-elsif ($_[0] eq "b" || $_[0] eq "c") { @rv = ( "vfat" ); }
-elsif ($_[0] eq "83") { @rv = ( "ext3", "ext4", "ext2", "xfs", "reiserfs" ); }
-elsif ($_[0] eq "82") { @rv = ( "swap" ); }
-elsif ($_[0] eq "81") { @rv = ( "minix" ); }
-else { return ( ); }
+my ($tag) = @_;
+my @rv;
+if ($has_parted) {
+       # Use parted type names
+       if ($tag eq "fat16") {
+               @rv = ( "msdos" );
+               }
+       elsif ($tag eq "fat32") {
+               @rv = ( "vfat" );
+               }
+       elsif ($tag eq "ext2") {
+               @rv = ( "ext3", "ext4", "ext2", "xfs", "reiserfs" );
+               }
+       elsif ($tag eq "hfs") {
+               @rv = ( "hfs" );
+               }
+       elsif ($tag eq "linux-swap") {
+               @rv = ( "swap" );
+               }
+       elsif ($tag eq "NTFS") {
+               @rv = ( "ntfs" );
+               }
+       elsif ($tag eq "reiserfs") {
+               @rv = "reiserfs";
+               }
+       elsif ($tag eq "ufs") {
+               @rv = ( "ufs" );
+               }
+       else {
+               return ( );
+               }
+       }
+else {
+       # Use fdisk type IDs
+       if ($tag eq "4" || $tag eq "6" || $tag eq "1" || $tag eq "e") {
+               @rv = ( "msdos" );
+               }
+       elsif ($tag eq "b" || $tag eq "c") {
+               @rv = ( "vfat" );
+               }
+       elsif ($tag eq "83") {
+               @rv = ( "ext3", "ext4", "ext2", "xfs", "reiserfs" );
+               }
+       elsif ($tag eq "82") {
+               @rv = ( "swap" );
+               }
+       elsif ($tag eq "81") {
+               @rv = ( "minix" );
+               }
+       else {
+               return ( );
+               }
+       }
 local %supp = map { $_, 1 } &mount::list_fstypes();
 @rv = grep { $supp{$_} } @rv;
 return wantarray ? @rv : $rv[0];
@@ -1371,6 +1455,22 @@ if ($has_xfs_db && ($_[2] eq "xfs" || !$_[2])) {
 return 0;
 }
 
+# supports_label(&partition)
+# Returns 1 if the label can be set on a partition
+sub supports_label
+{
+my ($part) = @_;
+return $part->{'type'} eq '83' || $part->{'type'} eq 'ext2';
+}
+
+# supports_name(&disk)
+# Returns 1 if the name can be set on a disk's partitions
+sub supports_name
+{
+my ($disk) = @_;
+return $disk->{'table'} eq 'gpt';
+}
+
 # supports_hdparm(&disk)
 sub supports_hdparm
 {
index 2d554c4..af2f139 100755 (executable)
@@ -16,10 +16,20 @@ if (@disks == 1 && &can_edit_disk($disks[0]->{'device'})) {
        }
 
 $pdesc = $has_parted ? $text{'index_parted'} : $text{'index_fdisk'};
-&ui_print_header($pdesc, $module_info{'desc'}, "", undef, 0, 1, 0,
+&ui_print_header($pdesc, $module_info{'desc'}, "", undef, 1, 1, 0,
        &help_search_link("fdisk", "man", "doc", "howto"));
 $extwidth = 250;
 
+# Check for critical commands
+if ($has_parted) {
+       &has_command("parted") ||
+               &ui_print_endpage(&text('index_ecmd', '<tt>parted</tt>'));
+       }
+else {
+       &has_command("fdisk") ||
+               &ui_print_endpage(&text('index_ecmd', '<tt>fdisk</tt>'));
+       }
+
 # Show a table of just disks
 @disks = sort { $a->{'device'} cmp $b->{'device'} } @disks;
 if (@disks) {
index 18cb104..382bd5c 100644 (file)
@@ -1,6 +1,7 @@
 index_title=Partition Manager
 index_parted=Using <tt>parted</tt>
 index_fdisk=Using <tt>fdisk</tt>
+index_ecmd=You have selected to use the $1 command for partition management, but it is not installed on your system.
 index_err=Failed to list disks
 index_disk=Disk
 index_parts=Partitions
@@ -84,7 +85,8 @@ edit_mountlvm=Part of LVM volume group $1
 edit_notexist=Not created yet
 edit_notused=Not in use
 edit_size=Size
-edit_label=Partition label
+edit_label=Filesystem label
+edit_name=Partition name
 edit_volid=Volume ID
 edit_blocks=$1 blocks
 edit_inuse=This partition cannot be changed as it is currently in use or configured for use.
@@ -267,5 +269,6 @@ 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_return=list of partitions
 
 __norefs=1
index 44f57af..809dacb 100755 (executable)
@@ -16,7 +16,7 @@ if ($in{'delete'} && $in{'confirm'}) {
        $pinfo = $plist[$in{'part'}];
        &delete_partition($dinfo->{'device'}, $pinfo->{'number'});
        &webmin_log("delete", "part", $dinfo->{'device'}, \%in);
-       &redirect("");
+       &redirect("edit_disk.cgi?device=$dinfo->{'device'}");
        }
 elsif ($in{'delete'}) {
        # Ask the user if he really wants to delete the partition
@@ -33,17 +33,22 @@ elsif ($in{'delete'}) {
        print "<input type=submit name=confirm value='$text{'delete_ok'}'>\n";
        print "</form></center>\n";
 
-       &ui_print_footer("", $text{'index_return'});
+       &ui_print_footer("edit_disk.cgi?device=$dinfo->{'device'}",
+                        $text{'disk_return'});
        }
 elsif (!$in{'new'}) {
-       # changing existing partition
+       # Changing existing partition type and label
        $pinfo = $plist[$in{'part'}];
-       &change_type($dinfo->{'device'}, $pinfo->{'number'}, $in{'type'});
-       if (defined($in{'label'}) && $in{'type'} eq '83') {
+       if ($pinfo->{'edittype'}) {
+               &change_type($dinfo->{'device'}, $pinfo->{'number'},
+                            $in{'type'});
+               $pinfo->{'type'} = $in{'type'};
+               }
+       if (defined($in{'label'}) && &supports_label($pinfo)) {
                &set_label($pinfo->{'device'}, $in{'label'});
                }
        &webmin_log("modify", "part", $dinfo->{'device'}, \%in);
-       &redirect("");
+       &redirect("edit_disk.cgi?device=$dinfo->{'device'}");
        }
 else {
        # Adding new partition
@@ -77,7 +82,8 @@ else {
        else {
                &create_partition($dinfo->{'device'}, $in{'newpart'},
                                  $in{'start'}, $in{'end'}, $in{'type'});
-               if ($in{'label'} && $in{'type'} eq '83') {
+               $pinfo = { 'type' => $in{'type'} };
+               if ($in{'label'} && &supports_label($pinfo)) {
                        local $dev = $dinfo->{'prefix'}.$in{'newpart'};
                        &set_label($dev, $in{'label'});
                        }