Add support for gpart in BSD Fdisk

https://github.com/webmin/webmin/issues/2364#issuecomment-2657006714
This commit is contained in:
Ilia Ross
2025-02-13 20:19:47 +02:00
parent 3b3f1b3146
commit 07e9674b3a
15 changed files with 803 additions and 682 deletions

View File

@ -13,7 +13,7 @@ our (%text);
sub check_fdisk sub check_fdisk
{ {
foreach my $cmd ("fdisk", "disklabel") { foreach my $cmd ("fdisk", "disklabel", "gpart") {
if (!&has_command($cmd)) { if (!&has_command($cmd)) {
return &text('index_ecmd', "<tt>$cmd</tt>"); return &text('index_ecmd', "<tt>$cmd</tt>");
} }
@ -30,6 +30,9 @@ my @rv;
# Iterate over disk devices # Iterate over disk devices
foreach my $dev (glob("/dev/ada[0-9]"), glob("/dev/ada[0-9][0-9]"), foreach my $dev (glob("/dev/ada[0-9]"), glob("/dev/ada[0-9][0-9]"),
glob("/dev/ad[0-9]"), glob("/dev/ad[0-9][0-9]"), glob("/dev/ad[0-9]"), glob("/dev/ad[0-9][0-9]"),
glob("/dev/nvd[0-9]"), glob("/dev/nvd[0-9][0-9]"),
glob("/dev/vtbd[0-9]"), glob("/dev/vtbd[0-9][0-9]"),
glob("/dev/md[0-9]"), glob("/dev/md[0-9][0-9]"),
glob("/dev/da[0-9]"), glob("/dev/da[0-9][0-9]")) { glob("/dev/da[0-9]"), glob("/dev/da[0-9][0-9]")) {
next if (!-r $dev || -l $dev); next if (!-r $dev || -l $dev);
my $disk = { 'device' => $dev, my $disk = { 'device' => $dev,
@ -48,7 +51,19 @@ foreach my $dev (glob("/dev/ada[0-9]"), glob("/dev/ada[0-9][0-9]"),
push(@rv, $disk); push(@rv, $disk);
# Get size and slices # Get size and slices
my $out = &backquote_command("fdisk ".quotemeta($dev)); my $out;
my $sdev = 's';
if (&has_command('gpart')) {
# Get size and slices with GPT support
$out = &backquote_command("gpart show -p ".quotemeta($dev));
$sdev = 'p';
}
else {
$out = &backquote_command("fdisk ".quotemeta($dev));
}
if ($out =~ /Scheme:\s*GPT/i) {
$disk->{'type'} = 'gpt';
}
my @lines = split(/\r?\n/, $out); my @lines = split(/\r?\n/, $out);
my $slice; my $slice;
for(my $i=0; $i<@lines; $i++) { for(my $i=0; $i<@lines; $i++) {
@ -69,9 +84,9 @@ foreach my $dev (glob("/dev/ada[0-9]"), glob("/dev/ada[0-9][0-9]"),
$lines[$i] =~ /data\s+for\s+partition\s+(\d+)/) { $lines[$i] =~ /data\s+for\s+partition\s+(\d+)/) {
# Start of a slice # Start of a slice
$slice = { 'number' => $1, $slice = { 'number' => $1,
'device' => $dev."s".$1, 'device' => $dev."$sdev".$1,
'index' => scalar(@{$disk->{'slices'}}) }; 'index' => scalar(@{$disk->{'slices'}}) };
if ($slice->{'device'} =~ /^\/dev\/([a-z]+)(\d+)s(\d+)/){ if ($slice->{'device'} =~ /^\/dev\/([a-z]+)(\d+)[ps](\d+)/) {
$slice->{'desc'} = &text('select_slice', $slice->{'desc'} = &text('select_slice',
uc($disk->{'type'}), "$2", "$3"); uc($disk->{'type'}), "$2", "$3");
} }
@ -116,15 +131,22 @@ foreach my $dev (glob("/dev/ada[0-9]"), glob("/dev/ada[0-9][0-9]"),
foreach my $slice (@{$disk->{'slices'}}) { foreach my $slice (@{$disk->{'slices'}}) {
$slice->{'parts'} = [ ]; $slice->{'parts'} = [ ];
next if (!-e $slice->{'device'}); next if (!-e $slice->{'device'});
my $out = &backquote_command("disklabel ".$slice->{'device'}); my $out;
if (&has_command('gpart')) {
$out = &backquote_command("gpart show -p ".$slice->{'device'});
}
else {
$out = &backquote_command("disklabel ".$slice->{'device'});
}
my @lines = split(/\r?\n/, $out); my @lines = split(/\r?\n/, $out);
foreach my $l (@lines) { foreach my $l (@lines) {
if ($l =~ /^\s*([a-z]):\s+(\d+)\s+(\d+)\s+(\S+)/) { if ($l =~ /^\s*([a-z]):\s+(\d+)\s+(\d+)\s+(\S+)(\s+(\S+))?/) {
my $part = { 'letter' => $1, my $part = { 'letter' => $1,
'blocks' => $2, 'blocks' => $2,
'startblock' => $3, 'startblock' => $3,
'type' => $4, 'type' => $4,
'device' =>$slice->{'device'}.$1 }; 'device' =>$slice->{'device'}.$1 };
$part->{'label'} = $6 if ($6);
$part->{'size'} = $part->{'blocks'} * $part->{'size'} = $part->{'blocks'} *
$disk->{'blocksize'}; $disk->{'blocksize'};
$part->{'desc'} = &text('select_part', $part->{'desc'} = &text('select_part',
@ -210,12 +232,12 @@ if ($dev =~ /^\/dev\/([a-z]+)(\d+)$/) {
return &text('select_device', return &text('select_device',
$1 eq 'da' ? 'SCSI' : 'IDE', "$2"); $1 eq 'da' ? 'SCSI' : 'IDE', "$2");
} }
elsif ($dev =~ /^\/dev\/([a-z]+)(\d+)s(\d+)$/) { elsif ($dev =~ /^\/dev\/([a-z]+)(\d+)[ps](\d+)$/) {
# A slice within a disk # A slice within a disk
return &text('select_slice', return &text('select_slice',
$1 eq 'da' ? 'SCSI' : 'IDE', "$2", "$3"); $1 eq 'da' ? 'SCSI' : 'IDE', "$2", "$3");
} }
elsif ($dev =~ /^\/dev\/([a-z]+)(\d+)s(\d+)([a-z])$/) { elsif ($dev =~ /^\/dev\/([a-z]+)(\d+)[ps](\d+)([a-z])$/) {
# A partition within a slice # A partition within a slice
return &text('select_part', return &text('select_part',
$1 eq 'da' ? 'SCSI' : 'IDE', "$2", "$3", uc($4)); $1 eq 'da' ? 'SCSI' : 'IDE', "$2", "$3", uc($4));
@ -249,6 +271,10 @@ return $ex ? $out : undef;
sub delete_slice sub delete_slice
{ {
my ($disk, $slice) = @_; my ($disk, $slice) = @_;
if ($disk->{'type'} eq 'gpt') {
return &backquote_logged("gpart delete -i $slice->{'number'} ".
"$disk->{'device'} 2>&1");
}
return &execute_fdisk_commands($disk, return &execute_fdisk_commands($disk,
[ "p $slice->{'number'} 0 0 0" ]); [ "p $slice->{'number'} 0 0 0" ]);
} }
@ -258,6 +284,17 @@ return &execute_fdisk_commands($disk,
sub create_slice sub create_slice
{ {
my ($disk, $slice) = @_; my ($disk, $slice) = @_;
if ($disk->{'type'} eq 'gpt') {
my $cmd = "gpart add -t $slice->{'type'} -b $slice->{'startblock'} -s ".
"$slice->{'blocks'}";
$cmd .= " -l $slice->{'label'}" if $slice->{'label'};
$cmd .= " $disk->{'device'}";
my $err = &backquote_logged("$cmd 2>&1");
if (!$err) {
$slice->{'device'} = $disk->{'device'}."p".$slice->{'number'};
}
return $err;
}
my $type = hex($slice->{'type'}); my $type = hex($slice->{'type'});
my $start = int($slice->{'startblock'} * $disk->{'blocksize'} / 1024); my $start = int($slice->{'startblock'} * $disk->{'blocksize'} / 1024);
my $length = int($slice->{'blocks'} * $disk->{'blocksize'} / 1024); my $length = int($slice->{'blocks'} * $disk->{'blocksize'} / 1024);
@ -274,6 +311,15 @@ return $err;
sub modify_slice sub modify_slice
{ {
my ($disk, $oldslice, $slice) = @_; my ($disk, $oldslice, $slice) = @_;
if ($disk->{'type'} eq 'gpt') {
if ($oldslice->{'type'} ne $slice->{'type'}) {
my $cmd = "gpart modify -i $slice->{'number'} -t $slice->{'type'}";
$cmd .= " -l $slice->{'label'}" if $slice->{'label'};
$cmd .= " $disk->{'device'}";
return &backquote_logged("$cmd 2>&1");
}
return undef;
}
if ($oldslice->{'type'} ne $slice->{'type'}) { if ($oldslice->{'type'} ne $slice->{'type'}) {
# Change the type # Change the type
my $type = hex($slice->{'type'}); my $type = hex($slice->{'type'});
@ -298,13 +344,18 @@ return undef;
sub initialize_slice sub initialize_slice
{ {
my ($disk, $slice) = @_; my ($disk, $slice) = @_;
if ($disk->{'type'} eq 'gpt') {
return &backquote_logged("gpart create -s GPT $slice->{'device'} 2>&1");
}
my $err = &backquote_logged("bsdlabel -w $slice->{'device'}"); my $err = &backquote_logged("bsdlabel -w $slice->{'device'}");
return $? ? $err : undef; return $? ? $err : undef;
} }
sub list_partition_types sub list_partition_types
{ {
return ( '4.2BSD', 'swap', 'unused', 'vinum' ); return ( '4.2BSD', 'swap', 'unused', 'vinum',
'freebsd-ufs', 'freebsd-swap', 'freebsd-zfs',
'freebsd-boot', 'freebsd-raid', 'freebsd-label' );
} }
# save_partition(&disk, &slice, &part) # save_partition(&disk, &slice, &part)
@ -312,6 +363,20 @@ return ( '4.2BSD', 'swap', 'unused', 'vinum' );
sub save_partition sub save_partition
{ {
my ($disk, $slice, $part) = @_; my ($disk, $slice, $part) = @_;
if ($disk->{'type'} eq 'gpt') {
my $cmd = "gpart add -t $part->{'type'}";
$cmd .= " -b $part->{'startblock'}" if $part->{'startblock'};
$cmd .= " -s $part->{'blocks'}" if $part->{'blocks'};
$cmd .= " -l $part->{'label'}" if $part->{'label'};
$cmd .= " " . $slice->{'device'};
my $err = &backquote_logged("$cmd 2>&1");
if (!$err) {
$part->{'device'} = $slice->{'device'}.$part->{'letter'};
}
return $err;
}
# Edit or add a line in the existing label
my $out = &backquote_command("bsdlabel $slice->{'device'}"); my $out = &backquote_command("bsdlabel $slice->{'device'}");
if ($? && $out =~ /no\s+valid\s+label/) { if ($? && $out =~ /no\s+valid\s+label/) {
# No label at all yet .. initialize # No label at all yet .. initialize
@ -322,6 +387,8 @@ if ($? && $out =~ /no\s+valid\s+label/) {
# Edit or add a line in the existing label # Edit or add a line in the existing label
my $wantline = " ".$part->{'letter'}.": ".$part->{'blocks'}." ". my $wantline = " ".$part->{'letter'}.": ".$part->{'blocks'}." ".
$part->{'startblock'}." ".$part->{'type'}; $part->{'startblock'}." ".$part->{'type'};
$wantline .= " " . $part->{'label'} if ($part->{'label'});
my @lines = split(/\r?\n/, $out); my @lines = split(/\r?\n/, $out);
my $found = 0; my $found = 0;
for(my $i=0; $i<@lines; $i++) { for(my $i=0; $i<@lines; $i++) {
@ -348,6 +415,9 @@ sub delete_partition
my ($disk, $slice, $part) = @_; my ($disk, $slice, $part) = @_;
# Fix up the line for the part being deleted # Fix up the line for the part being deleted
if ($disk->{'type'} eq 'gpt') {
return &backquote_logged("gpart delete -i $part->{'letter'} $slice->{'device'} 2>&1");
}
my $out = &backquote_command("bsdlabel $slice->{'device'}"); my $out = &backquote_command("bsdlabel $slice->{'device'}");
my @lines = split(/\r?\n/, $out); my @lines = split(/\r?\n/, $out);
my $found = 0; my $found = 0;

7
bsdfdisk/create_part.cgi Executable file → Normal file
View File

@ -19,7 +19,7 @@ $slice || &error($text{'slice_egone'});
# Validate inputs, starting with slice number # Validate inputs, starting with slice number
my $part = { }; my $part = { };
$in{'letter'} =~ /^[a-d]$/i || &error($text{'npart_eletter'}); $in{'letter'} =~ /^[a-z]$/i || &error($text{'npart_eletter'});
$in{'letter'} = lc($in{'letter'}); $in{'letter'} = lc($in{'letter'});
my ($clash) = grep { $_->{'letter'} eq $in{'letter'} } @{$slice->{'parts'}}; my ($clash) = grep { $_->{'letter'} eq $in{'letter'} } @{$slice->{'parts'}};
$clash && &error(&text('npart_eclash', $in{'letter'})); $clash && &error(&text('npart_eclash', $in{'letter'}));
@ -29,15 +29,18 @@ $part->{'letter'} = $in{'letter'};
$in{'start'} =~ /^\d+$/ || &error($text{'nslice_estart'}); $in{'start'} =~ /^\d+$/ || &error($text{'nslice_estart'});
$in{'end'} =~ /^\d+$/ || &error($text{'nslice_eend'}); $in{'end'} =~ /^\d+$/ || &error($text{'nslice_eend'});
$in{'start'} < $in{'end'} || &error($text{'npart_erange'}); $in{'start'} < $in{'end'} || &error($text{'npart_erange'});
$part->{'startblock'} = $in{'start'}; $part->{'startblock'} = int($in{'start'}/2048)*2048; # 1MB alignment
$part->{'blocks'} = $in{'end'} - $in{'start'}; $part->{'blocks'} = $in{'end'} - $in{'start'};
# Slice type # Slice type
$part->{'type'} = $in{'type'}; $part->{'type'} = $in{'type'};
# Set partition properties
$part->{'label'} = $in{'label'} if ($in{'label'} =~ /^[a-zA-Z0-9._-]+$/);
# Do the creation # Do the creation
&ui_print_header($slice->{'desc'}, $text{'npart_title'}, ""); &ui_print_header($slice->{'desc'}, $text{'npart_title'}, "");
# Create the partition
print &text('npart_creating', $in{'letter'}, $slice->{'desc'}),"<p>\n"; print &text('npart_creating', $in{'letter'}, $slice->{'desc'}),"<p>\n";
my $err = &save_partition($disk, $slice, $part); my $err = &save_partition($disk, $slice, $part);
if ($err) { if ($err) {

4
bsdfdisk/create_slice.cgi Executable file → Normal file
View File

@ -26,15 +26,17 @@ $slice->{'number'} = $in{'number'};
$in{'start'} =~ /^\d+$/ || &error($text{'nslice_estart'}); $in{'start'} =~ /^\d+$/ || &error($text{'nslice_estart'});
$in{'end'} =~ /^\d+$/ || &error($text{'nslice_eend'}); $in{'end'} =~ /^\d+$/ || &error($text{'nslice_eend'});
$in{'start'} < $in{'end'} || &error($text{'nslice_erange'}); $in{'start'} < $in{'end'} || &error($text{'nslice_erange'});
$slice->{'startblock'} = $in{'start'}; $slice->{'startblock'} = int($in{'start'}/2048)*2048; # Align to 1MB
$slice->{'blocks'} = $in{'end'} - $in{'start'}; $slice->{'blocks'} = $in{'end'} - $in{'start'};
# Slice type # Slice type
$slice->{'type'} = $in{'type'}; $slice->{'type'} = $in{'type'};
$slice->{'label'} = $in{'label'} if ($in{'label'} =~ /^[a-zA-Z0-9._-]+$/);
# Do the creation # Do the creation
&ui_print_header($disk->{'desc'}, $text{'nslice_title'}, ""); &ui_print_header($disk->{'desc'}, $text{'nslice_title'}, "");
# Create the slice
print &text('nslice_creating', $in{'number'}, $disk->{'desc'}),"<p>\n"; print &text('nslice_creating', $in{'number'}, $disk->{'desc'}),"<p>\n";
my $err = &create_slice($disk, $slice); my $err = &create_slice($disk, $slice);
if ($err) { if ($err) {

4
bsdfdisk/edit_disk.cgi Executable file → Normal file
View File

@ -23,9 +23,9 @@ push(@info, &text('disk_dsize', &nice_size($disk->{'size'})));
if ($disk->{'model'}) { if ($disk->{'model'}) {
push(@info, &text('disk_model', $disk->{'model'})); push(@info, &text('disk_model', $disk->{'model'}));
} }
push(@info, &text('disk_cylinders', $disk->{'cylinders'}));
push(@info, &text('disk_blocks', $disk->{'blocks'})); push(@info, &text('disk_blocks', $disk->{'blocks'}));
push(@info, &text('disk_device', "<tt>$disk->{'device'}</tt>")); push(@info, &text('disk_device', "<tt>$disk->{'device'}</tt>"));
push(@info, &text('disk_scheme', uc($disk->{'type'} || "MBR")));
print &ui_links_row(\@info),"<p>\n"; print &ui_links_row(\@info),"<p>\n";
# Show partitions table # Show partitions table
@ -41,6 +41,7 @@ if (@{$disk->{'slices'}}) {
$text{'disk_start'}, $text{'disk_start'},
$text{'disk_end'}, $text{'disk_end'},
$text{'disk_use'}, $text{'disk_use'},
$text{'disk_label'},
]); ]);
foreach my $p (@{$disk->{'slices'}}) { foreach my $p (@{$disk->{'slices'}}) {
# Create images for the extent # Create images for the extent
@ -75,6 +76,7 @@ if (@{$disk->{'slices'}}) {
$p->{'startblock'} + $p->{'blocks'} - 1, $p->{'startblock'} + $p->{'blocks'} - 1,
$use ? $use : $use ? $use :
$n ? &text('disk_scount', $n) : "", $n ? &text('disk_scount', $n) : "",
$p->{'label'},
]); ]);
} }
print &ui_columns_end(); print &ui_columns_end();

4
bsdfdisk/edit_part.cgi Executable file → Normal file
View File

@ -49,10 +49,14 @@ if ($canedit) {
print &ui_table_row($text{'part_type'}, print &ui_table_row($text{'part_type'},
&ui_select("type", $part->{'type'}, &ui_select("type", $part->{'type'},
[ &list_partition_types() ], 1, 0, 1)); [ &list_partition_types() ], 1, 0, 1));
print &ui_table_row($text{'part_label'},
&ui_textbox("label", $part->{'label'}, 20));
} }
else { else {
print &ui_table_row($text{'part_type'}, print &ui_table_row($text{'part_type'},
$part->{'type'}); $part->{'type'});
print &ui_table_row($text{'part_label'},
$part->{'label'});
} }
print &ui_table_row($text{'part_use'}, print &ui_table_row($text{'part_use'},

11
bsdfdisk/edit_slice.cgi Executable file → Normal file
View File

@ -41,16 +41,19 @@ print &ui_table_row($text{'slice_sstart'},
print &ui_table_row($text{'slice_send'}, print &ui_table_row($text{'slice_send'},
$slice->{'startblock'} + $slice->{'blocks'} - 1); $slice->{'startblock'} + $slice->{'blocks'} - 1);
# GPT type selection
print &ui_table_row($text{'slice_stype'}, print &ui_table_row($text{'slice_stype'},
&ui_select("type", $slice->{'type'}, &ui_select("type", $slice->{'type'},
[ sort { $a->[1] cmp $b->[1] } [ &list_partition_types() ]));
map { [ $_, &fdisk::tag_name($_) ] }
&fdisk::list_tags() ]));
print &ui_table_row($text{'slice_sactive'}, print &ui_table_row($text{'slice_sactive'},
$slice->{'active'} ? $text{'yes'} : $slice->{'active'} ? $text{'yes'} :
&ui_yesno_radio("active", $slice->{'active'})); &ui_yesno_radio("active", $slice->{'active'}));
# Label field
print &ui_table_row($text{'slice_label'},
&ui_textbox("label", $slice->{'label'}, 20));
# Usage status
print &ui_table_row($text{'slice_suse'}, print &ui_table_row($text{'slice_suse'},
!@st ? $text{'part_nouse'} : !@st ? $text{'part_nouse'} :
$st[2] ? &text('part_inuse', $use) : $st[2] ? &text('part_inuse', $use) :
@ -74,6 +77,7 @@ if (@{$slice->{'parts'}}) {
$text{'slice_start'}, $text{'slice_start'},
$text{'slice_end'}, $text{'slice_end'},
$text{'slice_use'}, $text{'slice_use'},
$text{'slice_label'},
]); ]);
foreach my $p (@{$slice->{'parts'}}) { foreach my $p (@{$slice->{'parts'}}) {
# Create images for the extent # Create images for the extent
@ -104,6 +108,7 @@ if (@{$slice->{'parts'}}) {
$p->{'startblock'}, $p->{'startblock'},
$p->{'startblock'} + $p->{'blocks'} - 1, $p->{'startblock'} + $p->{'blocks'} - 1,
$use, $use,
$p->{'label'},
]); ]);
} }
print &ui_columns_end(); print &ui_columns_end();

10
bsdfdisk/fsck.cgi Executable file → Normal file
View File

@ -16,20 +16,20 @@ my ($disk) = grep { $_->{'device'} eq $in{'device'} } @disks;
$disk || &error($text{'disk_egone'}); $disk || &error($text{'disk_egone'});
my ($slice) = grep { $_->{'number'} eq $in{'slice'} } @{$disk->{'slices'}}; my ($slice) = grep { $_->{'number'} eq $in{'slice'} } @{$disk->{'slices'}};
$slice || &error($text{'slice_egone'}); $slice || &error($text{'slice_egone'});
my ($object, $part); my $object = $slice;
# Handle partitions if specified
my $part;
if ($in{'part'} ne '') { if ($in{'part'} ne '') {
($part) = grep { $_->{'letter'} eq $in{'part'} } ($part) = grep { $_->{'letter'} eq $in{'part'} }
@{$slice->{'parts'}}; @{$slice->{'parts'}};
$part || &error($text{'part_egone'}); $part || &error($text{'part_egone'});
$object = $part; $object = $part;
} }
else {
$object = $slice;
}
&ui_print_unbuffered_header($object->{'desc'}, $text{'fsck_title'}, ""); &ui_print_unbuffered_header($object->{'desc'}, $text{'fsck_title'}, "");
# Do the creation # Run filesystem check
print &text('fsck_checking', "<tt>$object->{'device'}</tt>"),"<br>\n"; print &text('fsck_checking', "<tt>$object->{'device'}</tt>"),"<br>\n";
print "<pre>\n"; print "<pre>\n";
my $cmd = &get_check_filesystem_command($disk, $slice, $part); my $cmd = &get_check_filesystem_command($disk, $slice, $part);

2
bsdfdisk/index.cgi Executable file → Normal file
View File

@ -9,6 +9,7 @@ require './bsdfdisk-lib.pl';
our (%in, %text, %config, $module_name); our (%in, %text, %config, $module_name);
&ui_print_header(undef, $text{'index_title'}, "", "intro", 1, 1, 0, &ui_print_header(undef, $text{'index_title'}, "", "intro", 1, 1, 0,
&has_command('gpart') ? &help_search_link("gpart", "man") :
&help_search_link("fdisk", "man")); &help_search_link("fdisk", "man"));
my $err = &check_fdisk(); my $err = &check_fdisk();
@ -30,6 +31,7 @@ if (@disks) {
&nice_size($d->{'size'}), &nice_size($d->{'size'}),
$d->{'model'}, $d->{'model'},
scalar(@{$d->{'slices'}}), scalar(@{$d->{'slices'}}),
uc($d->{'type'}),
]); ]);
} }
print &ui_columns_end(); print &ui_columns_end();

7
bsdfdisk/log_parser.pl Executable file → Normal file
View File

@ -8,10 +8,15 @@ do 'bsdfdisk-lib.pl';
sub parse_webmin_log sub parse_webmin_log
{ {
my ($user, $script, $action, $type, $object, $p) = @_; my ($user, $script, $action, $type, $object, $p) = @_;
if ($type eq "slice" || $type eq "part") { if ($type eq "slice" || $type eq "part" || $type eq "object") {
return &text('log_'.$action.'_'.$type, return &text('log_'.$action.'_'.$type,
"<tt>".&html_escape($object)."</tt>"); "<tt>".&html_escape($object)."</tt>");
} }
if ($type eq "disk") {
return &text('log_'.$action.'_disk',
"<tt>".&html_escape($object)."</tt>");
}
return undef; return undef;
} }
1;

10
bsdfdisk/newfs.cgi Executable file → Normal file
View File

@ -16,16 +16,16 @@ my ($disk) = grep { $_->{'device'} eq $in{'device'} } @disks;
$disk || &error($text{'disk_egone'}); $disk || &error($text{'disk_egone'});
my ($slice) = grep { $_->{'number'} eq $in{'slice'} } @{$disk->{'slices'}}; my ($slice) = grep { $_->{'number'} eq $in{'slice'} } @{$disk->{'slices'}};
$slice || &error($text{'slice_egone'}); $slice || &error($text{'slice_egone'});
my ($object, $part); my $object = $slice;
# Handle partitions if specified
my $part;
if ($in{'part'} ne '') { if ($in{'part'} ne '') {
($part) = grep { $_->{'letter'} eq $in{'part'} } ($part) = grep { $_->{'letter'} eq $in{'part'} }
@{$slice->{'parts'}}; @{$slice->{'parts'}};
$part || &error($text{'part_egone'}); $part || &error($text{'part_egone'});
$object = $part; $object = $part;
} }
else {
$object = $slice;
}
# Validate inputs # Validate inputs
my $newfs = { }; my $newfs = { };
@ -39,7 +39,7 @@ $newfs->{'label'} = $in{'label_def'} ? undef : $in{'label'};
&ui_print_unbuffered_header($object->{'desc'}, $text{'newfs_title'}, ""); &ui_print_unbuffered_header($object->{'desc'}, $text{'newfs_title'}, "");
# Do the creation # Create the filesystem
print &text('newfs_creating', "<tt>$object->{'device'}</tt>"),"<br>\n"; print &text('newfs_creating', "<tt>$object->{'device'}</tt>"),"<br>\n";
print "<pre>\n"; print "<pre>\n";
my $cmd = &get_create_filesystem_command($disk, $slice, $part, $newfs); my $cmd = &get_create_filesystem_command($disk, $slice, $part, $newfs);

18
bsdfdisk/newfs_form.cgi Executable file → Normal file
View File

@ -9,22 +9,20 @@ require './bsdfdisk-lib.pl';
our (%in, %text, $module_name); our (%in, %text, $module_name);
&ReadParse(); &ReadParse();
# Get the disk and slice # Get the disk and partition details
my @disks = &list_disks_partitions(); my @disks = &list_disks_partitions();
my ($disk) = grep { $_->{'device'} eq $in{'device'} } @disks; my ($disk) = grep { $_->{'device'} eq $in{'device'} } @disks;
$disk || &error($text{'disk_egone'}); $disk || &error($text{'disk_egone'});
my ($slice) = grep { $_->{'number'} eq $in{'slice'} } @{$disk->{'slices'}}; my ($slice) = grep { $_->{'number'} eq $in{'slice'} } @{$disk->{'slices'}};
$slice || &error($text{'slice_egone'}); $slice || &error($text{'slice_egone'});
my $object; my $object = $slice;
if ($in{'part'} ne '') { if ($in{'part'} ne '') {
my ($part) = grep { $_->{'letter'} eq $in{'part'} } my ($part) = grep { $_->{'letter'} eq $in{'part'} }
@{$slice->{'parts'}}; @{$slice->{'parts'}};
$part || &error($text{'part_egone'}); $part || &error($text{'part_egone'});
$object = $part; $object = $part;
} }
else {
$object = $slice;
}
&ui_print_header($object->{'desc'}, $text{'newfs_title'}, ""); &ui_print_header($object->{'desc'}, $text{'newfs_title'}, "");
@ -35,16 +33,20 @@ print &ui_hidden("part", $in{'part'});
print &ui_table_start($text{'newfs_header'}, undef, 2); print &ui_table_start($text{'newfs_header'}, undef, 2);
print &ui_table_row($text{'part_device'}, print &ui_table_row($text{'part_device'},
"<tt>$object->{'device'}</tt>"); "<tt>$object->{'device'}</tt>") if ($object->{'device'});
# Free blocks percentage
print &ui_table_row($text{'newfs_free'}, print &ui_table_row($text{'newfs_free'},
&ui_opt_textbox("free", undef, 4, $text{'newfs_deffree'})."%"); &ui_opt_textbox("free", undef, 4, $text{'newfs_free_def'},
$text{'newfs_free_pc'})." %");
# Enable TRIM support
print &ui_table_row($text{'newfs_trim'}, print &ui_table_row($text{'newfs_trim'},
&ui_yesno_radio("trim", 0)); &ui_yesno_radio("trim", 0));
# Filesystem label
print &ui_table_row($text{'newfs_label'}, print &ui_table_row($text{'newfs_label'},
&ui_opt_textbox("label", undef, 20, $text{'newfs_none'})); &ui_opt_textbox("label", undef, 20, $text{'newfs_label_def'}));
print &ui_table_end(); print &ui_table_end();
print &ui_form_end([ [ undef, $text{'newfs_create'} ] ]); print &ui_form_end([ [ undef, $text{'newfs_create'} ] ]);

12
bsdfdisk/part_form.cgi Executable file → Normal file
View File

@ -32,11 +32,11 @@ while($used{$l}) {
print &ui_table_row($text{'npart_letter'}, print &ui_table_row($text{'npart_letter'},
&ui_textbox("letter", $l, 4)); &ui_textbox("letter", $l, 4));
# Slice size in blocks # Available space in blocks
print &ui_table_row($text{'npart_diskblocks'}, print &ui_table_row($text{'npart_diskblocks'},
$slice->{'blocks'}); $slice->{'blocks'});
# Start and end blocks (defaults to last part) # Start and end blocks calculation
my ($start, $end) = (0, $slice->{'blocks'}); my ($start, $end) = (0, $slice->{'blocks'});
foreach my $p (sort { $a->{'startblock'} cmp $b->{'startblock'} } foreach my $p (sort { $a->{'startblock'} cmp $b->{'startblock'} }
@{$slice->{'parts'}}) { @{$slice->{'parts'}}) {
@ -47,11 +47,15 @@ print &ui_table_row($text{'nslice_start'},
print &ui_table_row($text{'nslice_end'}, print &ui_table_row($text{'nslice_end'},
&ui_textbox("end", $end, 10)); &ui_textbox("end", $end, 10));
# Partition type # Partition type selection
print &ui_table_row($text{'npart_type'}, print &ui_table_row($text{'npart_type'},
&ui_select("type", '4.2BSD', &ui_select("type", 'freebsd-ufs',
[ &list_partition_types() ])); [ &list_partition_types() ]));
# Partition label (optional)
print &ui_table_row($text{'npart_label'},
&ui_textbox("label", "", 20));
print &ui_table_end(); print &ui_table_end();
print &ui_form_end([ [ undef, $text{'create'} ] ]); print &ui_form_end([ [ undef, $text{'create'} ] ]);

14
bsdfdisk/save_part.cgi Executable file → Normal file
View File

@ -26,9 +26,19 @@ if (@st && $st[2]) {
&error(&text('part_esave', $use)); &error(&text('part_esave', $use));
} }
# Make the change # Update partition properties
$part->{'type'} = $in{'type'}; $part->{'type'} = $in{'type'};
my $err = &save_partition($disk, $slice, $part); my $err;
if (defined($in{'label'})) {
my $oldpart = { %$part };
$part->{'label'} = $in{'label'} if defined($in{'label'});
# Apply changes using gpart
$err = &modify_partition($disk, $slice, $oldpart, $part);
}
else {
$err = &save_partition($disk, $slice, $part);
}
&error($err) if ($err); &error($err) if ($err);
&webmin_log("modify", "part", $part->{'device'}, $part); &webmin_log("modify", "part", $part->{'device'}, $part);

28
bsdfdisk/save_slice.cgi Executable file → Normal file
View File

@ -8,7 +8,7 @@ no warnings 'uninitialized';
require './bsdfdisk-lib.pl'; require './bsdfdisk-lib.pl';
our (%in, %text, $module_name); our (%in, %text, $module_name);
&ReadParse(); &ReadParse();
&error_setup($text{'slice_err'}); &error_setup($text{'save_err'});
# Get the disk and slice # Get the disk and slice
my @disks = &list_disks_partitions(); my @disks = &list_disks_partitions();
@ -17,14 +17,24 @@ $disk || &error($text{'disk_egone'});
my ($slice) = grep { $_->{'number'} eq $in{'slice'} } @{$disk->{'slices'}}; my ($slice) = grep { $_->{'number'} eq $in{'slice'} } @{$disk->{'slices'}};
$slice || &error($text{'slice_egone'}); $slice || &error($text{'slice_egone'});
# Apply changes if ($in{'delete'}) {
my $oldslice = { %$slice }; # Delete the slice
$slice->{'type'} = $in{'type'}; my $err = &delete_slice($disk, $slice);
if (!$slice->{'active'}) { &error($err) if ($err);
$slice->{'active'} = $in{'active'}; &webmin_log("delete", "slice", $slice->{'device'}, $slice);
}
else {
# Validate inputs
$in{'type'} =~ /^\S+$/ || &error($text{'save_etype'});
$in{'label'} =~ /^[a-zA-Z0-9._-]+$/ || &error($text{'save_elabel'});
# Update the slice
my $oldslice = { %$slice };
$slice->{'type'} = $in{'type'};
$slice->{'label'} = $in{'label'};
my $err = &modify_slice($disk, $oldslice, $slice);
&error($err) if ($err);
&webmin_log("modify", "slice", $slice->{'device'}, $slice);
} }
my $err = &modify_slice($disk, $oldslice, $slice);
&error($err) if ($err);
&webmin_log("modify", "slice", $slice->{'device'}, $slice);
&redirect("edit_disk.cgi?device=$in{'device'}"); &redirect("edit_disk.cgi?device=$in{'device'}");

18
bsdfdisk/slice_form.cgi Executable file → Normal file
View File

@ -34,8 +34,8 @@ print &ui_table_row($text{'nslice_diskblocks'},
$disk->{'blocks'}); $disk->{'blocks'});
# Start and end blocks (defaults to last slice+1) # Start and end blocks (defaults to last slice+1)
my ($start, $end) = (63, $disk->{'blocks'}); my ($start, $end) = (2048, $disk->{'blocks'});
foreach my $s (sort { $a->{'startblock'} cmp $b->{'startblock'} } foreach my $s (sort { $a->{'startblock'} <=> $b->{'startblock'} }
@{$disk->{'slices'}}) { @{$disk->{'slices'}}) {
$start = $s->{'startblock'} + $s->{'blocks'} + 1; $start = $s->{'startblock'} + $s->{'blocks'} + 1;
} }
@ -44,14 +44,16 @@ print &ui_table_row($text{'nslice_start'},
print &ui_table_row($text{'nslice_end'}, print &ui_table_row($text{'nslice_end'},
&ui_textbox("end", $end, 10)); &ui_textbox("end", $end, 10));
# Slice type # GPT partition type
print &ui_table_row($text{'nslice_type'}, print &ui_table_row($text{'nslice_type'},
&ui_select("type", 'a5', &ui_select("type", 'freebsd-ufs',
[ sort { $a->[1] cmp $b->[1] } [ &list_partition_types() ]));
map { [ $_, &fdisk::tag_name($_) ] }
&fdisk::list_tags() ]));
# Also create partition? # Partition label
print &ui_table_row($text{'nslice_label'},
&ui_textbox("label", "", 20));
# Create filesystem option
print &ui_table_row($text{'nslice_makepart'}, print &ui_table_row($text{'nslice_makepart'},
&ui_yesno_radio("makepart", 1)); &ui_yesno_radio("makepart", 1));