Files
webmin/bsdfdisk/slice_form.cgi
karmantyu 032f4447db Add files via upload
gpart edition
2026-01-23 19:41:57 +01:00

134 lines
5.0 KiB
Perl
Executable File

#!/usr/local/bin/perl
# Show a form for creating a new slice
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './bsdfdisk-lib.pl';
our (%in, %text, $module_name);
&ReadParse();
# Get the disk
my @disks = &list_disks_partitions();
my ($disk) = grep { $_->{'device'} eq $in{'device'} } @disks;
$disk || &error($text{'disk_egone'});
&ui_print_header($disk->{'desc'}, $text{'nslice_title'}, "");
# Determine scheme for read-only behavior and note
my $base_device = $disk->{'device'}; $base_device =~ s{^/dev/}{};
my $disk_structure = get_disk_structure($base_device);
my $is_gpt = (is_using_gpart() && $disk_structure && ($disk_structure->{'scheme'}||'') =~ /GPT/i);
# Check if there is any free space on the device
my $has_free_space = 0;
if ($disk_structure && $disk_structure->{'entries'}) {
foreach my $entry (@{$disk_structure->{'entries'}}) {
if ($entry->{'type'} eq 'free' && $entry->{'size'} > 0) {
$has_free_space = 1;
last;
}
}
}
# If no free space, show error and return
if (!$has_free_space) {
print "<p><b>$text{'nslice_enospace'}</b></p>\n";
&ui_print_footer("edit_disk.cgi?device=$in{'device'}", $text{'disk_return'});
exit;
}
print &ui_form_start("create_slice.cgi", "post");
print &ui_hidden("device", $in{'device'});
print &ui_table_start($text{'nslice_header'}, undef, 2);
# Slice number (first free)
my %used = map { $_->{'number'}, $_ } @{$disk->{'slices'}};
my $n = 1;
while($used{$n}) {
$n++;
}
my $num_field = $is_gpt
? "<input type='text' name='number' value='".&html_escape($n)."' size='6' readonly> <span style='color:#666;font-style:italic'>".$text{'nslice_autonext'}."</span>"
: &ui_textbox("number", $n, 6);
print &ui_table_row($text{'nslice_number'}, $num_field);
# Disk size in blocks (prefer GPART total blocks)
my $disk_blocks = ($disk_structure && $disk_structure->{'total_blocks'}) ? $disk_structure->{'total_blocks'} : ($disk->{'blocks'} || 0);
print &ui_table_row($text{'nslice_diskblocks'}, $disk_blocks);
# Start and end blocks (defaults to last slice+1). Allow prefill from query.
my ($start, $end) = (2048, $disk_blocks > 0 ? $disk_blocks - 1 : 0);
foreach my $s (sort { $a->{'startblock'} <=> $b->{'startblock'} }
@{$disk->{'slices'}}) {
$start = $s->{'startblock'} + $s->{'blocks'}; # leave 1 block (512B) gap
}
if (defined $in{'start'} && $in{'start'} =~ /^\d+$/) { $start = $in{'start'}; }
if (defined $in{'end'} && $in{'end'} =~ /^\d+$/) { $end = $in{'end'}; }
print &ui_table_row($text{'nslice_start'},
&ui_textbox("start", $start, 10));
print &ui_table_row($text{'nslice_end'},
&ui_textbox("end", $end, 10));
# Slice type
if (is_using_gpart()) {
my $scheme = ($disk_structure && $disk_structure->{'scheme'}) ? $disk_structure->{'scheme'} : 'GPT';
my $default_stype = ($scheme =~ /GPT/i) ? 'freebsd-zfs' : 'freebsd';
print &ui_table_row($text{'nslice_type'},
&ui_select("type", $default_stype,
[ list_partition_types($scheme) ]));
}
else {
print &ui_table_row($text{'nslice_type'},
&ui_select("type", 'a5',
[ sort { $a->[1] cmp $b->[1] }
map { [ $_, &fdisk::tag_name($_) ] }
&fdisk::list_tags() ]));
}
# Also create partition? (only for MBR slices with BSD disklabel support)
if (!$is_gpt) {
print &ui_table_row($text{'slice_add'},
&ui_yesno_radio("makepart", 1));
}
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'save'} ] ]);
# Existing slices summary
print &ui_hr();
print &ui_columns_start([$text{'disk_no'}, $text{'disk_type'}, $text{'disk_start'}, $text{'disk_end'}, $text{'disk_size'}], $text{'nslice_existing_header'});
foreach my $s (sort { $a->{'number'} <=> $b->{'number'} } @{$disk->{'slices'}}) {
my $stype = get_type_description($s->{'type'}) || $s->{'type'};
my $szb = bytes_from_blocks($s->{'device'}, $s->{'blocks'});
my $sz = defined $szb ? safe_nice_size($szb) : '-';
print &ui_columns_row([
$s->{'number'},
$stype,
$s->{'startblock'},
$s->{'startblock'} + $s->{'blocks'} - 1,
$sz,
]);
}
print &ui_columns_end();
# Existing partitions summary
my @parts_rows;
foreach my $s (sort { $a->{'number'} <=> $b->{'number'} } @{$disk->{'slices'}}) {
next unless @{$s->{'parts'}||[]};
foreach my $p (@{$s->{'parts'}}) {
my $ptype = get_type_description($p->{'type'}) || $p->{'type'};
my $pb = bytes_from_blocks($p->{'device'}, $p->{'blocks'});
my $psz = defined $pb ? safe_nice_size($pb) : '-';
push @parts_rows, [ $s->{'number'}, uc($p->{'letter'}), $ptype, $p->{'startblock'}, $p->{'startblock'} + $p->{'blocks'} - 1, $psz ];
}
}
if (@parts_rows) {
print &ui_columns_start(['Slice', $text{'slice_letter'}, $text{'slice_type'}, $text{'slice_start'}, $text{'slice_end'}, $text{'slice_size'}], $text{'nslice_existing_parts'});
foreach my $row (@parts_rows) { print &ui_columns_row($row); }
print &ui_columns_end();
}
&ui_print_footer("edit_disk.cgi?device=$in{'device'}",
$text{'disk_return'});