-/* $OpenBSD: cmd.c,v 1.116 2021/06/16 15:40:47 krw Exp $ */
+/* $OpenBSD: cmd.c,v 1.117 2021/06/21 02:05:30 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
GPT_print_parthdr(TERSE);
GPT_print_part(pn, "s", TERSE);
+ if (PRT_protected_guid(&gg->gp_type)) {
+ uuid_dec_le(&gg->gp_type, &guid);
+ printf("can't edit partition type %s\n",
+ PRT_uuid_to_typename(&guid));
+ goto done;
+ }
+
/* Ask for partition type or GUID. */
uuid_dec_le(&gg->gp_type, &guid);
num = ask_pid(PRT_uuid_to_type(&guid), &guid);
if (num <= 0xff)
guid = *(PRT_type_to_uuid(num));
uuid_enc_le(&gg->gp_type, &guid);
+ if (PRT_protected_guid(&gg->gp_type)) {
+ uuid_dec_le(&gg->gp_type, &guid);
+ printf("can't change partition type to %s\n",
+ PRT_uuid_to_typename(&guid));
+ goto done;
+ }
if (uuid_is_nil(&gg->gp_guid, NULL)) {
uuid_create(&guid, &status);
-.\" $OpenBSD: fdisk.8,v 1.100 2021/06/20 19:40:06 jmc Exp $
+.\" $OpenBSD: fdisk.8,v 1.101 2021/06/21 02:05:30 krw Exp $
.\"
.\"
.\" Copyright (c) 1997 Tobias Weingartner
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 20 2021 $
+.Dd $Mdocdate: June 21 2021 $
.Dt FDISK 8
.Os
.Sh NAME
.Nd partition table maintenance program
.Sh SYNOPSIS
.Nm fdisk
-.Op Fl egvy
-.Op Fl i | u
+.Op Fl ey
+.Op Fl i Oo Fl g Oc | Fl u | Fl A | Fl v
.Op Fl b Ar blocks Ns Op @ Ns Ar offset Ns Op : Ns Ar type
-.Op Fl c Ar cylinders Fl h Ar heads Fl s Ar sectors
+.Op Fl l Ar blocks | Fl c Ar cylinders Fl h Ar heads Fl s Ar sectors
.Op Fl f Ar mbrfile
-.Op Fl l Ar blocks
.Ar disk
.Sh DESCRIPTION
.Nm fdisk
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl A
+Allocates the largest chunks of free space in an existing GPT to the
+.Ox
+partition
+and the optional
+.Fl b
+partition.
+The free space is maximized by deleting
+all existing partitions except the boot partitions
+.Sq APFS ISC ,
+.Sq APFS ,
+.Sq APFS Recovry ,
+.Sq HiFive FSBL
+and
+.Sq HiFive BBL .
.It Fl b Ar blocks Ns Op @ Ns Ar offset Ns Op : Ns Ar type
A special boot partition of the specified size, offset and type will be written to disk.
The
.Ox
partition will follow the boot partition and use the remaining space on the disk.
.Pp
-Only valid with
-.Fl i .
-If
-.Fl g
-is specified only the
+Can only be used when initializing a disk with
+.Fl i Op Fl g
+or
+.Fl A .
+If a GPT is being initialized
+only the
.Ar blocks
value will be used, with the boot partition being placed at the first available LBA and
given the type EFI SYS.
.Em /boot
has passed to the kernel.
.Pp
-Only one of
-.Fl chs
-or
-.Fl l
-can be specified.
.It Fl e
Use the
.Nm
partition containing all available space not allocated by a
.Fl b
specification.
-Only valid with
-.Fl i .
.It Fl i
Requests that the partition table data be re-initialized.
In this mode,
MBR partition containing all available space not allocated by a
.Fl b
specification.
-.Pp
-Only one of
-.Fl i
-or
-.Fl u
-can be specified.
.It Fl l Ar blocks
Specify the number of blocks in the disk, and force the MBR to be in LBA
mode only.
-.Pp
-Only one of
-.Fl chs
-or
-.Fl l
-can be specified.
.It Fl u
Update MBR bootcode, preserving existing MBR partition table.
The MBR bootcode extends from offset 0x000 to the start of the MBR partition
equivalent to the DOS command
.Dq FDISK /MBR .
Note that this option will overwrite the NT disk signature, if present.
-.Pp
-Only one of
-.Fl i
-or
-.Fl u
-can be specified.
.It Fl v
Print the contents of the MBR, the Primary GPT and the Secondary GPT.
Also print more detailed GPT header and partition entry information.
-Cannot be used with
.Fl i ,
.Fl u ,
or
-/* $OpenBSD: fdisk.c,v 1.109 2021/06/20 18:44:19 krw Exp $ */
+/* $OpenBSD: fdisk.c,v 1.110 2021/06/21 02:05:30 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
uint32_t b_sectors, b_offset;
uint8_t b_type;
-int y_flag;
+int A_flag, y_flag;
static void
usage(void)
extern char * __progname;
fprintf(stderr, "usage: %s "
- "[-egvy] [-i|-u] [-b #] [-c # -h # -s #] "
- "[-f mbrfile] [-l # ] disk\n"
- "\t-b: specify special boot partition block count; requires -i\n"
- "\t-chs: specify disk geometry; all three must be specified\n"
- "\t-e: interactively edit MBR or GPT\n"
- "\t-f: specify non-standard MBR template\n"
- "\t-g: initialize disk with GPT; requires -i\n"
- "\t-i: initialize disk with MBR unless -g is also specified\n"
- "\t-l: specify LBA block count; cannot be used with -chs\n"
- "\t-u: update MBR code; preserve partition table\n"
- "\t-v: print the MBR, the Primary GPT and the Secondary GPT\n"
- "\t-y: do not ask questions\n"
- "`disk' may be of the forms: sd0 or /dev/rsd0c.\n",
+ "[-evy] [-i [-g] | -u | -A ] [-b blocks[@offset[:type]]]\n"
+ "\t[-l blocks | -c cylinders -h heads -s sectors] [-f mbrfile] disk\n",
__progname);
exit(1);
}
struct dos_mbr dos_mbr;
struct mbr mbr;
- while ((ch = getopt(argc, argv, "iegpuvf:c:h:s:l:b:y")) != -1) {
+ while ((ch = getopt(argc, argv, "Aiegpuvf:c:h:s:l:b:y")) != -1) {
const char *errstr;
switch(ch) {
+ case 'A':
+ A_flag = 1;
+ break;
case 'i':
i_flag = 1;
break;
/* Argument checking */
if (argc != 1 || (i_flag && u_flag) ||
- (i_flag == 0 && (b_sectors || g_flag)) ||
+ (i_flag == 0 && g_flag) ||
+ (b_sectors && !(i_flag || A_flag)) ||
((c_arg | h_arg | s_arg) && !(c_arg && h_arg && s_arg)) ||
((c_arg | h_arg | s_arg) && l_arg))
usage();
disk.name = argv[0];
- DISK_open(i_flag || u_flag || e_flag);
+ DISK_open(A_flag || i_flag || u_flag || e_flag);
/* "proc exec" for man page display */
if (pledge("stdio rpath wpath disklabel proc exec", NULL) == -1)
if (efi != -1)
GPT_read(ANYGPT);
- if (!(i_flag || u_flag || e_flag)) {
+ if (!(A_flag || i_flag || u_flag || e_flag)) {
if (pledge("stdio", NULL) == -1)
err(1, "pledge");
USER_print_disk(verbosity);
MBR_parse(&dos_mbr, 0, 0, &initial_mbr);
query = NULL;
- if (i_flag) {
+ if (A_flag) {
+ if (letoh64(gh.gh_sig) != GPTSIGNATURE)
+ errx(1, "-A requires a valid GPT");
+ else {
+ MBR_init_GPT(&initial_mbr);
+ GPT_init();
+ query = "Do you wish to write new GPT?";
+ }
+ } else if (i_flag) {
if (g_flag) {
MBR_init_GPT(&initial_mbr);
GPT_init();
-/* $OpenBSD: gpt.c,v 1.31 2021/06/20 18:44:19 krw Exp $ */
+/* $OpenBSD: gpt.c,v 1.32 2021/06/21 02:05:30 krw Exp $ */
/*
* Copyright (c) 2015 Markus Muller <mmu@grummel.net>
* Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
init_gp(void)
{
extern uint32_t b_sectors;
+ extern int A_flag;
const uint8_t gpt_uuid_efi_system[] = GPT_UUID_EFI_SYSTEM;
const uint8_t gpt_uuid_openbsd[] = GPT_UUID_OPENBSD;
struct gpt_partition oldgp[NGPTPARTITIONS];
- int rslt;
+ int pn, rslt;
memcpy(&oldgp, &gp, sizeof(oldgp));
- memset(&gp, 0, sizeof(gp));
+ if (A_flag == 0)
+ memset(&gp, 0, sizeof(gp));
+ else {
+ for (pn = 0; pn < NGPTPARTITIONS; pn++) {
+ if (PRT_protected_guid(&gp[pn].gp_type))
+ continue;
+ memset(&gp[pn], 0, sizeof(gp[pn]));
+ }
+ }
rslt = 0;
if (b_sectors > 0) {
-/* $OpenBSD: part.c,v 1.85 2021/06/13 23:53:51 krw Exp $ */
+/* $OpenBSD: part.c,v 1.86 2021/06/21 02:05:30 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
{ 0xFF, "Xenix BBT "}, /* Xenix Bad Block Table */
};
+static const struct protected_guid {
+ char guid[UUID_STR_LEN + 1];
+} protected_guid[] = {
+ { "7c3457ef-0000-11aa-aa11-00306543ecac" }, /* APFS */
+ { "69646961-6700-11aa-aa11-00306543ecac" }, /* APFS ISC */
+ { "52637672-7900-11aa-aa11-00306543ecac" }, /* APFS Recovry */
+ { "5b193300-fc78-40cd-8002-e86c45580b47" }, /* HiFive FSBL */
+ { "2e54b353-1271-4842-806f-e436d6af6985" }, /* HiFive BBL */
+};
+
+#define nitems(_a) ((sizeof(_a)) / sizeof((_a)[0]))
+
+int
+PRT_protected_guid(struct uuid *leuuid)
+{
+ struct uuid uuid;
+ char *str = NULL;
+ int rslt;
+ unsigned int i;
+ uint32_t status;
+
+ uuid_dec_le(leuuid, &uuid);
+ uuid_to_string(&uuid, &str, &status);
+ if (status != uuid_s_ok) {
+ rslt = 1;
+ goto done;
+ }
+
+ rslt = 0;
+ for(i = 0; i < nitems(protected_guid); i++) {
+ if (strncmp(str, protected_guid[i].guid, UUID_STR_LEN) == 0) {
+ rslt = 1;
+ break;
+ }
+ }
+
+ done:
+ free(str);
+ return rslt;
+}
+
void
PRT_printall(void)
{
-/* $OpenBSD: part.h,v 1.23 2021/06/10 16:09:17 krw Exp $ */
+/* $OpenBSD: part.h,v 1.24 2021/06/21 02:05:30 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
char *PRT_uuid_to_typename(struct uuid *);
int PRT_uuid_to_type(struct uuid *);
struct uuid *PRT_type_to_uuid(int);
+int PRT_protected_guid(struct uuid *);
/* This does CHS -> bs/ns */
void PRT_fix_BN(struct prt *, int);