#!/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 "
$text{'nslice_enospace'}
\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 ? " ".$text{'nslice_autonext'}."" : &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'});