summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2015-10-26 15:08:27 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2015-10-26 15:08:27 +0000
commit3245efed863c7e6267b46264a1d988f788c2379b (patch)
tree0522ce0000400c4bb8c539d036a8fb53c37a0c40 /sbin
parent1ffa6ac82c072557193ead53f3f15258cb836544 (diff)
Add GPT editing. Based on GSOC 2014 work by Markus Muller.
Diffstat (limited to 'sbin')
-rw-r--r--sbin/fdisk/cmd.c230
-rw-r--r--sbin/fdisk/cmd.h3
-rw-r--r--sbin/fdisk/fdisk.c53
-rw-r--r--sbin/fdisk/gpt.c275
-rw-r--r--sbin/fdisk/gpt.h9
-rw-r--r--sbin/fdisk/mbr.c32
-rw-r--r--sbin/fdisk/mbr.h3
-rw-r--r--sbin/fdisk/misc.c141
-rw-r--r--sbin/fdisk/misc.h7
-rw-r--r--sbin/fdisk/part.c121
-rw-r--r--sbin/fdisk/part.h4
-rw-r--r--sbin/fdisk/user.c46
12 files changed, 759 insertions, 165 deletions
diff --git a/sbin/fdisk/cmd.c b/sbin/fdisk/cmd.c
index 19b5e2f9606..6d445017f49 100644
--- a/sbin/fdisk/cmd.c
+++ b/sbin/fdisk/cmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd.c,v 1.82 2015/04/02 18:00:55 krw Exp $ */
+/* $OpenBSD: cmd.c,v 1.83 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -16,6 +16,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/param.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/disklabel.h>
@@ -26,30 +27,53 @@
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
+#include <uuid.h>
#include "disk.h"
#include "misc.h"
#include "part.h"
#include "mbr.h"
+#include "gpt.h"
#include "user.h"
#include "cmd.h"
int reinited;
+/* Some helper functions for GPT handling. */
+int Xgedit(char *);
+int Xgsetpid(char *);
+
int
Xreinit(char *args, struct mbr *mbr)
{
struct dos_mbr dos_mbr;
+ int dogpt;
+
+ if (strncasecmp(args, "gpt", 3) == 0)
+ dogpt = 1;
+ else if (strncasecmp(args, "mbr", 3) == 0)
+ dogpt = 0;
+ else if (strlen(args) > 0) {
+ printf("Unrecognized modifier '%s'\n", args);
+ return (CMD_CONT);
+ } else if (MBR_protective_mbr(&initial_mbr) == 0)
+ dogpt = 1;
+ else
+ dogpt = 0;
MBR_make(&initial_mbr, &dos_mbr);
MBR_parse(&dos_mbr, mbr->offset, mbr->reloffset, mbr);
- MBR_init(mbr);
+ if (dogpt) {
+ MBR_init_GPT(mbr);
+ GPT_init();
+ GPT_print("s");
+ } else {
+ MBR_init(mbr);
+ MBR_print(mbr, "s");
+ }
reinited = 1;
- /* Tell em we did something */
- printf("In memory copy is initialized to:\n");
- MBR_print(mbr, args);
printf("Use 'write' to update disk.\n");
return (CMD_DIRTY);
@@ -91,8 +115,9 @@ Xswap(char *args, struct mbr *mbr)
{
const char *errstr;
char *from, *to;
- int pf, pt;
+ int pf, pt, maxpn;
struct prt pp;
+ struct gpt_partition gg;
to = args;
from = strsep(&to, " \t");
@@ -102,12 +127,17 @@ Xswap(char *args, struct mbr *mbr)
return (CMD_CONT);
}
- pf = strtonum(from, 0, 3, &errstr);
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE)
+ maxpn = NGPTPARTITIONS - 1;
+ else
+ maxpn = NDOSPART - 1;
+
+ pf = strtonum(from, 0, maxpn, &errstr);
if (errstr) {
printf("partition number is %s: %s\n", errstr, from);
return (CMD_CONT);
}
- pt = strtonum(to, 0, 3, &errstr);
+ pt = strtonum(to, 0, maxpn, &errstr);
if (errstr) {
printf("partition number is %s: %s\n", errstr, to);
return (CMD_CONT);
@@ -118,20 +148,71 @@ Xswap(char *args, struct mbr *mbr)
return (CMD_CONT);
}
- pp = mbr->part[pt];
- mbr->part[pt] = mbr->part[pf];
- mbr->part[pf] = pp;
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE) {
+ gg = gp[pt];
+ gp[pt] = gp[pf];
+ gp[pf] = gg;
+ } else {
+ pp = mbr->part[pt];
+ mbr->part[pt] = mbr->part[pf];
+ mbr->part[pf] = pp;
+ }
return (CMD_DIRTY);
}
int
+Xgedit(char *args)
+{
+ const char *errstr;
+ struct gpt_partition *gg;
+ char *name;
+ u_int64_t bs, ns;
+ int pn, ret;
+
+ pn = strtonum(args, 0, NGPTPARTITIONS - 1, &errstr);
+ if (errstr) {
+ printf("partition number is %s: %s\n", errstr, args);
+ return (CMD_CONT);
+ }
+ gg = &gp[pn];
+
+ /* Edit partition type */
+ ret = Xgsetpid(args);
+
+ /* Unused, so just zero out */
+ if (uuid_is_nil(&gg->gp_type, NULL)) {
+ memset(gg, 0, sizeof(struct gpt_partition));
+ printf("Partition %d is disabled.\n", pn);
+ return (ret);
+ }
+
+ /* Change table entry */
+ bs = getuint64("Partition offset", letoh64(gh.gh_lba_start),
+ letoh64(gh.gh_lba_end));
+ ns = getuint64("Partition size", letoh64(gh.gh_lba_end) - bs + 1,
+ letoh64(gh.gh_lba_end) - bs + 1);
+
+ gg->gp_lba_start = htole64(bs);
+ gg->gp_lba_end = htole64(bs + ns - 1);
+
+ /* Ask for partition name. */
+ name = ask_string("partition name", utf16le_to_string(gg->gp_name));
+ memcpy(gg->gp_name, string_to_utf16le(name), sizeof(gg->gp_name));
+
+ return (ret);
+}
+
+int
Xedit(char *args, struct mbr *mbr)
{
const char *errstr;
int pn, num, ret;
struct prt *pp;
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE)
+ return (Xgedit(args));
+
pn = strtonum(args, 0, 3, &errstr);
if (errstr) {
printf("partition number is %s: %s\n", errstr, args);
@@ -187,12 +268,52 @@ Xedit(char *args, struct mbr *mbr)
}
int
+Xgsetpid(char *args)
+{
+ const char *errstr;
+ struct uuid guid;
+ struct gpt_partition *gg;
+ int pn, num, status;
+
+ pn = strtonum(args, 0, NGPTPARTITIONS - 1, &errstr);
+ if (errstr) {
+ printf("partition number is %s: %s\n", errstr, args);
+ return (CMD_CONT);
+ }
+ gg = &gp[pn];
+
+ /* Print out current table entry */
+ GPT_print_parthdr();
+ GPT_print_part(pn, "s");
+
+ /* Ask for partition type or GUID. */
+ num = ask_pid(0, &guid);
+ if (num <= 0xff)
+ guid = *(PRT_type_to_uuid(num));
+ uuid_enc_le(&gg->gp_type, &guid);
+
+ if (uuid_is_nil(&gg->gp_guid, NULL)) {
+ uuid_create(&guid, &status);
+ if (status != uuid_s_ok) {
+ printf("could not create guid for partition\n");
+ return (CMD_CONT);
+ }
+ uuid_enc_le(&gg->gp_guid, &guid);
+ }
+
+ return (CMD_DIRTY);
+}
+
+int
Xsetpid(char *args, struct mbr *mbr)
{
const char *errstr;
int pn, num;
struct prt *pp;
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE)
+ return (Xgsetpid(args));
+
pn = strtonum(args, 0, 3, &errstr);
if (errstr) {
printf("partition number is %s: %s\n", errstr, args);
@@ -205,7 +326,7 @@ Xsetpid(char *args, struct mbr *mbr)
PRT_print(pn, pp, NULL);
/* Ask for MBR partition type */
- num = ask_pid(pp->id, 0x01, 0xff);
+ num = ask_pid(pp->id, NULL);
if (num == pp->id)
return (CMD_CONT);
@@ -258,8 +379,10 @@ int
Xprint(char *args, struct mbr *mbr)
{
- DISK_printgeometry(args);
- MBR_print(mbr, args);
+ if (MBR_protective_mbr(mbr) == 0 && letoh64(gh.gh_sig) == GPTSIGNATURE)
+ GPT_print(args);
+ else
+ MBR_print(mbr, args);
return (CMD_CONT);
}
@@ -291,9 +414,19 @@ Xwrite(char *args, struct mbr *mbr)
return (CMD_CONT);
}
- /* Make sure GPT doesn't get in the way. */
- if (reinited)
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE) {
+ printf("Writing GPT.\n");
+ if (GPT_write(fd) == -1) {
+ int saved_errno = errno;
+ warn("error writing GPT");
+ close(fd);
+ errno = saved_errno;
+ return (CMD_CONT);
+ }
+ } else if (reinited) {
+ /* Make sure GPT doesn't get in the way. */
MBR_zapgpt(fd, &dos_mbr, DL_GETDSIZE(&dl) - 1);
+ }
/* Refresh in memory copy to reflect what was just written. */
MBR_parse(&dos_mbr, mbr->offset, mbr->reloffset, mbr);
@@ -324,10 +457,26 @@ Xexit(char *args, struct mbr *mbr)
int
Xhelp(char *args, struct mbr *mbr)
{
+ char *mbrstr, *gpthelp;
int i;
- for (i = 0; cmd_table[i].cmd != NULL; i++)
+ for (i = 0; cmd_table[i].cmd != NULL; i++) {
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE) {
+ if (cmd_table[i].gpt == 0)
+ continue;
+ gpthelp = strdup(cmd_table[i].help);
+ mbrstr = strstr(gpthelp, "MBR");
+ if (mbrstr) {
+ memcpy(mbrstr, "GPT", 3);
+ printf("\t%s\t\t%s\n", cmd_table[i].cmd,
+ gpthelp);
+ free(gpthelp);
+ continue;
+ }
+ }
printf("\t%s\t\t%s\n", cmd_table[i].cmd, cmd_table[i].help);
+ }
+
return (CMD_CONT);
}
@@ -345,38 +494,57 @@ int
Xflag(char *args, struct mbr *mbr)
{
const char *errstr;
- int i, pn = -1, val = -1;
+ int i, maxpn, pn = -1;
+ long long val = -1;
char *part, *flag;
flag = args;
part = strsep(&flag, " \t");
- pn = strtonum(part, 0, 3, &errstr);
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE)
+ maxpn = NGPTPARTITIONS - 1;
+ else
+ maxpn = NDOSPART - 1;
+
+ pn = strtonum(part, 0, maxpn, &errstr);
if (errstr) {
printf("partition number is %s: %s.\n", errstr, part);
return (CMD_CONT);
}
if (flag != NULL) {
- val = (int)strtonum(flag, 0, 0xff, &errstr);
+ /* Set flag to value provided. */
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE)
+ val = strtonum(flag, 0, LLONG_MAX, &errstr);
+ else
+ val = strtonum(flag, 0, 0xff, &errstr);
if (errstr) {
printf("flag value is %s: %s.\n", errstr, flag);
return (CMD_CONT);
}
- }
-
- if (val == -1) {
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE)
+ gp[pn].gp_attrs = htole64(val);
+ else
+ mbr->part[pn].flag = val;
+ printf("Partition %d flag value set to 0x%llx.\n", pn, val);
+ } else {
/* Set active flag */
- for (i = 0; i < 4; i++) {
- if (i == pn)
- mbr->part[i].flag = DOSACTIVE;
- else
- mbr->part[i].flag = 0x00;
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE) {
+ for (i = 0; i < NGPTPARTITIONS; i++) {
+ if (i == pn)
+ gp[i].gp_attrs = htole64(GPTDOSACTIVE);
+ else
+ gp[i].gp_attrs = htole64(0);
+ }
+ } else {
+ for (i = 0; i < NDOSPART; i++) {
+ if (i == pn)
+ mbr->part[i].flag = DOSACTIVE;
+ else
+ mbr->part[i].flag = 0x00;
+ }
}
printf("Partition %d marked active.\n", pn);
- } else {
- mbr->part[pn].flag = val;
- printf("Partition %d flag value set to 0x%x.\n", pn, val);
}
return (CMD_DIRTY);
diff --git a/sbin/fdisk/cmd.h b/sbin/fdisk/cmd.h
index 9d478b64668..af3e7675519 100644
--- a/sbin/fdisk/cmd.h
+++ b/sbin/fdisk/cmd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd.h,v 1.17 2015/03/18 14:46:59 krw Exp $ */
+/* $OpenBSD: cmd.h,v 1.18 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -27,6 +27,7 @@
struct cmd {
char *cmd;
+ int gpt;
int (*fcn)(char *, struct mbr *);
char *help;
};
diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c
index f1605c2f94c..450d41edd19 100644
--- a/sbin/fdisk/fdisk.c
+++ b/sbin/fdisk/fdisk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fdisk.c,v 1.78 2015/10/05 01:39:08 krw Exp $ */
+/* $OpenBSD: fdisk.c,v 1.79 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -71,8 +71,8 @@ int
main(int argc, char *argv[])
{
ssize_t len;
- int ch, fd;
- int i_flag = 0, e_flag = 0, u_flag = 0;
+ int ch, fd, error;
+ int i_flag = 0, e_flag = 0, f_flag = 0, u_flag = 0;
int c_arg = 0, h_arg = 0, s_arg = 0;
u_int32_t l_arg = 0;
char *query;
@@ -97,6 +97,7 @@ main(int argc, char *argv[])
e_flag = 1;
break;
case 'f':
+ f_flag = 1;
mbrfile = optarg;
break;
case 'c':
@@ -148,18 +149,24 @@ main(int argc, char *argv[])
else
disk.name = argv[0];
- if (g_flag != 0 && i_flag == 0) {
- warnx("-g specified without -i");
- usage();
- }
+ /* Start with the disklabel geometry and get the sector size. */
+ DISK_getlabelgeometry();
if (b_arg > 0 && i_flag == 0) {
warnx("-b specified without -i");
usage();
}
- /* Start with the disklabel geometry and get the sector size. */
- DISK_getlabelgeometry();
+ if (g_flag != 0 && i_flag == 0) {
+ warnx("-g specified without -i");
+ usage();
+ }
+
+ /* Get the GPT if present. */
+ if (GPT_get_gpt()) {
+ memset(&gh, 0, sizeof(gh));
+ memset(&gp, 0, sizeof(gp));
+ }
if (c_arg | h_arg | s_arg) {
/* Use supplied geometry if it is completely specified. */
@@ -188,13 +195,25 @@ main(int argc, char *argv[])
USER_print_disk();
/* Create initial/default MBR. */
+ if (i_flag == 0) {
+ fd = DISK_open(disk.name, O_RDONLY);
+ error = MBR_read(fd, 0, &dos_mbr);
+ close(fd);
+ if (error)
+ errx(1, "Can't read sector 0!");
+ MBR_parse(&dos_mbr, 0, 0, &initial_mbr);
+ }
+
if (mbrfile != NULL && (fd = open(mbrfile, O_RDONLY)) == -1) {
warn("%s", mbrfile);
warnx("using builtin MBR");
+ memset(&initial_mbr, 0, sizeof(initial_mbr));
mbrfile = NULL;
}
if (mbrfile == NULL) {
- memcpy(&dos_mbr, builtin_mbr, sizeof(dos_mbr));
+ if (MBR_protective_mbr(&initial_mbr) != 0) {
+ memcpy(&dos_mbr, builtin_mbr, sizeof(dos_mbr));
+ }
} else {
len = read(fd, &dos_mbr, sizeof(dos_mbr));
if (len == -1)
@@ -204,7 +223,10 @@ main(int argc, char *argv[])
mbrfile);
close(fd);
}
- MBR_parse(&dos_mbr, 0, 0, &initial_mbr);
+ if (f_flag || MBR_protective_mbr(&initial_mbr) != 0) {
+ memset(&gh, 0, sizeof(struct gpt_header));
+ MBR_parse(&dos_mbr, 0, 0, &initial_mbr);
+ }
query = NULL;
if (i_flag) {
@@ -221,15 +243,8 @@ main(int argc, char *argv[])
MBR_pcopy(&initial_mbr);
query = "Do you wish to write new MBR?";
}
- if (query && ask_yn(query)) {
+ if (query && ask_yn(query))
Xwrite(NULL, &initial_mbr);
- if (g_flag) {
- fd = DISK_open(disk.name, O_RDWR);
- if (GPT_write(fd) == -1)
- warn("error writing GPT");
- close(fd);
- }
- }
if (e_flag)
USER_edit(0, 0);
diff --git a/sbin/fdisk/gpt.c b/sbin/fdisk/gpt.c
index 698f8872980..7f37628c16f 100644
--- a/sbin/fdisk/gpt.c
+++ b/sbin/fdisk/gpt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gpt.c,v 1.1 2015/10/05 01:39:08 krw Exp $ */
+/* $OpenBSD: gpt.c,v 1.2 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 2015 Markus Muller <mmu@grummel.net>
* Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
@@ -16,10 +16,14 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/types.h>
#include <sys/param.h>
#include <sys/disklabel.h>
#include <sys/dkio.h>
+#include <sys/fcntl.h>
#include <sys/ioctl.h>
+#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -31,10 +35,274 @@
#include "part.h"
#include "gpt.h"
+#ifdef DEBUG
+#define DPRINTF(x...) printf(x)
+#else
+#define DPRINTF(x...)
+#endif
+
struct gpt_header gh;
struct gpt_partition gp[NGPTPARTITIONS];
int
+GPT_get_header(int fd, off_t where)
+{
+ char *secbuf;
+ uint64_t partlastlba;
+ int partspersec;
+ uint32_t orig_gh_csum, new_gh_csum;
+
+ secbuf = DISK_readsector(fd, where);
+ if (secbuf == 0)
+ return (1);
+
+ memcpy(&gh, secbuf, sizeof(struct gpt_header));
+ free(secbuf);
+
+ if (letoh64(gh.gh_sig) != GPTSIGNATURE) {
+ DPRINTF("gpt signature: expected 0x%llx, got 0x%llx\n",
+ GPTSIGNATURE, letoh64(gh.gh_sig));
+ return (1);
+ }
+
+ if (letoh32(gh.gh_rev) != GPTREVISION) {
+ DPRINTF("gpt revision: expected 0x%x, got 0x%x\n",
+ GPTREVISION, letoh32(gh.gh_rev));
+ return (1);
+ }
+
+ if (letoh64(gh.gh_lba_self) != where) {
+ DPRINTF("gpt self lba: expected %lld, got %llu\n",
+ (long long)where, letoh64(gh.gh_lba_self));
+ return (1);
+ }
+
+ if (letoh32(gh.gh_size) != GPTMINHDRSIZE) {
+ DPRINTF("gpt header size: expected %u, got %u\n",
+ GPTMINHDRSIZE, letoh32(gh.gh_size));
+ return (1);
+ }
+
+ if (letoh32(gh.gh_part_size) != GPTMINPARTSIZE) {
+ DPRINTF("gpt partition size: expected %u, got %u\n",
+ GPTMINPARTSIZE, letoh32(gh.gh_part_size));
+ return (1);
+ }
+
+ if (letoh32(gh.gh_part_num) > NGPTPARTITIONS) {
+ DPRINTF("gpt partition count: expected <= %u, got %u\n",
+ NGPTPARTITIONS, letoh32(gh.gh_part_num));
+ return (1);
+ }
+
+ orig_gh_csum = gh.gh_csum;
+ gh.gh_csum = 0;
+ new_gh_csum = crc32((unsigned char *)&gh, letoh32(gh.gh_size));
+ gh.gh_csum = orig_gh_csum;
+ if (letoh32(orig_gh_csum) != new_gh_csum) {
+ DPRINTF("gpt header checksum: expected 0x%x, got 0x%x\n",
+ orig_gh_csum, new_gh_csum);
+ return (1);
+ }
+
+ if (letoh64(gh.gh_lba_end) >= DL_GETDSIZE(&dl)) {
+ DPRINTF("gpt last usable LBA: expected < %lld, got %llu\n",
+ DL_GETDSIZE(&dl), letoh64(gh.gh_lba_end));
+ return (1);
+ }
+
+ if (letoh64(gh.gh_lba_start) >= letoh64(gh.gh_lba_end)) {
+ DPRINTF("gpt first usable LBA: expected < %llu, got %llu\n",
+ letoh64(gh.gh_lba_start), letoh64(gh.gh_lba_start));
+ return (1);
+ }
+
+ if (letoh64(gh.gh_part_lba) <= letoh64(gh.gh_lba_end) &&
+ letoh64(gh.gh_part_lba) >= letoh64(gh.gh_lba_start)) {
+ DPRINTF("gpt partition table start lba: expected < %llu or "
+ "> %llu, got %llu\n", letoh64(gh.gh_lba_start),
+ letoh64(gh.gh_lba_end), letoh64(gh.gh_part_lba));
+ return (1);
+ }
+
+ partspersec = dl.d_secsize / letoh32(gh.gh_part_size);
+ partlastlba = letoh64(gh.gh_part_lba) +
+ ((letoh32(gh.gh_part_num) + partspersec - 1) / partspersec) - 1;
+ if (partlastlba <= letoh64(gh.gh_lba_end) &&
+ partlastlba >= letoh64(gh.gh_lba_start)) {
+ DPRINTF("gpt partition table last LBA: expected < %llu or "
+ "> %llu, got %llu\n", letoh64(gh.gh_lba_start),
+ letoh64(gh.gh_lba_end), partlastlba);
+ return (1);
+ }
+
+ /*
+ * Other possible paranoia checks:
+ * 1) partition table starts before primary gpt lba.
+ * 2) partition table extends into lowest partition.
+ * 3) alt partition table starts before gh_lba_end.
+ */
+ return (0);
+}
+
+int
+GPT_get_partition_table(int fd, off_t where)
+{
+ ssize_t len;
+ off_t off;
+ int secs;
+ uint32_t checksum, partspersec;
+
+ DPRINTF("gpt partition table being read from LBA %llu\n",
+ letoh64(gh.gh_part_lba));
+
+ partspersec = dl.d_secsize / letoh32(gh.gh_part_size);
+ if (partspersec * letoh32(gh.gh_part_size) != dl.d_secsize) {
+ DPRINTF("gpt partition table entry invalid size. %u\n",
+ letoh32(gh.gh_part_size));
+ return (1);
+ }
+ secs = (letoh32(gh.gh_part_num) + partspersec - 1) / partspersec;
+
+ memset(&gp, 0, sizeof(gp));
+
+ where *= dl.d_secsize;
+ off = lseek(fd, where, SEEK_SET);
+ if (off == -1) {
+ DPRINTF("seek to gpt partition table @ sector %llu failed\n",
+ (unsigned long long)where / dl.d_secsize);
+ return (1);
+ }
+ len = read(fd, &gp, secs * dl.d_secsize);
+ if (len == -1 || len != secs * dl.d_secsize) {
+ DPRINTF("gpt partition table read failed.\n");
+ return (1);
+ }
+
+ checksum = crc32((unsigned char *)&gp, letoh32(gh.gh_part_num) *
+ letoh32(gh.gh_part_size));
+ if (checksum != letoh32(gh.gh_part_csum)) {
+ DPRINTF("gpt partition table checksum: expected %x, got %x\n",
+ checksum, letoh32(gh.gh_part_csum));
+ return (1);
+ }
+
+ return (0);
+}
+
+int
+GPT_get_gpt(void)
+{
+ int fd, privalid, altvalid;
+
+ fd = DISK_open(disk.name, O_RDONLY);
+
+ /*
+ * primary header && primary partition table ||
+ * alt header && alt partition table
+ */
+ privalid = GPT_get_header(fd, GPTSECTOR);
+ if (privalid == 0)
+ privalid = GPT_get_partition_table(fd, gh.gh_part_lba);
+ if (privalid == 0) {
+ close(fd);
+ return (0);
+ }
+
+ altvalid = GPT_get_header(fd, DL_GETDSIZE(&dl) - 1);
+ if (altvalid == 0)
+ altvalid = GPT_get_partition_table(fd, gh.gh_part_lba);
+ if (altvalid == 0) {
+ close(fd);
+ return (0);
+ }
+
+ close(fd);
+
+ return (1);
+}
+
+void
+GPT_print(char *units)
+{
+ const int secsize = unit_types[SECTORS].conversion;
+ struct uuid guid;
+ char *guidstr = NULL;
+ double size;
+ int i, u, status;
+
+ printf("Disk: %s ", disk.name);
+
+ uuid_dec_le(&gh.gh_guid, &guid);
+ uuid_to_string(&guid, &guidstr, &status);
+ if (status == uuid_s_ok)
+ printf("%s ", guidstr);
+ else
+ printf("<invalid header guid> ");
+ free(guidstr);
+
+ u = unit_lookup(units);
+ size = ((double)disk.size * secsize) / unit_types[u].conversion;
+ printf("[%.0f ", size);
+ if (u == SECTORS && secsize != DEV_BSIZE)
+ printf("%d-byte ", secsize);
+ printf("%s]\n", unit_types[u].lname);
+
+ GPT_print_parthdr();
+
+ for (i = 0; i < letoh32(gh.gh_part_num); i++) {
+ if (uuid_is_nil(&gp[i].gp_type, NULL))
+ continue;
+ GPT_print_part(i, units);
+ }
+}
+
+void
+GPT_print_parthdr()
+{
+ printf(" First usable LBA: %llu Last usable LBA: %llu\n",
+ letoh64(gh.gh_lba_start), letoh64(gh.gh_lba_end));
+
+ printf(" #: uuid "
+ "lba size \n");
+ printf(" type name\n");
+ printf("----------------------------------------------------"
+ "-----------------\n");
+}
+
+void
+GPT_print_part(int n, char *units)
+{
+ struct uuid guid;
+ const int secsize = unit_types[SECTORS].conversion;
+ struct gpt_partition *partn = &gp[n];
+ char *guidstr = NULL;
+ double size;
+ int u, status;
+
+ printf("%c%3d: ", (letoh64(partn->gp_attrs) & GPTDOSACTIVE)?'*':' ', n);
+
+ uuid_dec_le(&partn->gp_guid, &guid);
+ uuid_to_string(&guid, &guidstr, &status);
+ if (status != uuid_s_ok)
+ printf("<invalid partition guid> ");
+ else
+ printf("%36s ", guidstr);
+ free(guidstr);
+
+ printf("%12lld ", letoh64(partn->gp_lba_start));
+
+ u = unit_lookup(units);
+ size = letoh64(partn->gp_lba_end) - letoh64(partn->gp_lba_start) + 1;
+ size = (size * secsize) / unit_types[u].conversion;
+ printf("%12.0f%s\n", size, unit_types[u].abbr);
+
+ uuid_dec_le(&partn->gp_type, &guid);
+ printf(" %-36s %-36s\n", PRT_uuid_to_type(&guid),
+ utf16le_to_string(partn->gp_name));
+}
+
+int
GPT_init(void)
{
extern u_int32_t b_arg;
@@ -83,6 +351,8 @@ GPT_init(void)
uuid_enc_le(&gp[1].gp_guid, &guid);
gp[1].gp_lba_start = gh.gh_lba_start;
gp[1].gp_lba_end = htole64(letoh64(gh.gh_lba_start)+b_arg - 1);
+ memcpy(gp[1].gp_name, string_to_utf16le("EFI System Area"),
+ sizeof(gp[1].gp_name));
}
#endif
uuid_dec_be(gpt_uuid_openbsd, &guid);
@@ -103,6 +373,9 @@ GPT_init(void)
}
#endif
gp[3].gp_lba_end = gh.gh_lba_end;
+ memcpy(gp[3].gp_name, string_to_utf16le("OpenBSD Area"),
+ sizeof(gp[3].gp_name));
+
gh.gh_part_csum = crc32((unsigned char *)&gp, sizeof(gp));
gh.gh_csum = crc32((unsigned char *)&gh, sizeof(gh));
diff --git a/sbin/fdisk/gpt.h b/sbin/fdisk/gpt.h
index 2d4607c3667..1caca02305b 100644
--- a/sbin/fdisk/gpt.h
+++ b/sbin/fdisk/gpt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: gpt.h,v 1.1 2015/10/05 01:39:08 krw Exp $ */
+/* $OpenBSD: gpt.h,v 1.2 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 2015 Markus Muller <mmu@grummel.net>
* Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
@@ -16,8 +16,15 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+int GPT_get_hdr(int, off_t);
+int GPT_get_partition_table(int, off_t);
+int GPT_get_gpt(void);
int GPT_init(void);
int GPT_write(int);
+void GPT_print(char *);
+void GPT_print_part(int, char *);
+void GPT_print_parthdr(void);
+
extern struct gpt_header gh;
extern struct gpt_partition gp[NGPTPARTITIONS];
diff --git a/sbin/fdisk/mbr.c b/sbin/fdisk/mbr.c
index b9eb693a3d1..211ed3f5190 100644
--- a/sbin/fdisk/mbr.c
+++ b/sbin/fdisk/mbr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mbr.c,v 1.55 2015/10/05 01:39:08 krw Exp $ */
+/* $OpenBSD: mbr.c,v 1.56 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdint.h>
#include <memory.h>
#include "disk.h"
@@ -37,6 +38,33 @@
struct mbr initial_mbr;
+int
+MBR_protective_mbr(struct mbr *mbr)
+{
+ u_int64_t dsize;
+ int efi, found, i;
+ u_int32_t psize;
+
+ found = efi = 0;
+ for (i = 0; i < NDOSPART; i++) {
+ if (mbr->part[i].id == DOSPTYP_UNUSED)
+ continue;
+ found++;
+ if (mbr->part[i].id != DOSPTYP_EFI)
+ continue;
+ dsize = DL_GETDSIZE(&dl);
+ psize = mbr->part[i].ns;
+ if (psize == (dsize - 1) || psize == UINT32_MAX) {
+ if (mbr->part[i].bs == 1)
+ efi++;
+ }
+ }
+ if (found == 1 && efi == 1)
+ return (0);
+
+ return (1);
+}
+
void
MBR_init_GPT(struct mbr *mbr)
{
@@ -167,6 +195,8 @@ MBR_print(struct mbr *mbr, char *units)
{
int i;
+ DISK_printgeometry(NULL);
+
/* Header */
printf("Offset: %lld\t", (long long)mbr->offset);
printf("Signature: 0x%X\n", (int)mbr->signature);
diff --git a/sbin/fdisk/mbr.h b/sbin/fdisk/mbr.h
index 294dea61114..0673f87fb45 100644
--- a/sbin/fdisk/mbr.h
+++ b/sbin/fdisk/mbr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mbr.h,v 1.25 2015/10/05 01:39:08 krw Exp $ */
+/* $OpenBSD: mbr.h,v 1.26 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -39,5 +39,6 @@ int MBR_write(int, off_t, struct dos_mbr *);
void MBR_pcopy(struct mbr *);
void MBR_zapgpt(int, struct dos_mbr *, uint64_t);
void MBR_init_GPT(struct mbr *);
+int MBR_protective_mbr(struct mbr *);
#endif /* _MBR_H */
diff --git a/sbin/fdisk/misc.c b/sbin/fdisk/misc.c
index e6416147c7d..cc95a29875e 100644
--- a/sbin/fdisk/misc.c
+++ b/sbin/fdisk/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.53 2015/10/07 00:04:57 krw Exp $ */
+/* $OpenBSD: misc.c,v 1.54 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -24,6 +24,7 @@
#include <string.h>
#include <err.h>
#include <errno.h>
+#include <uuid.h>
#include "disk.h"
#include "misc.h"
@@ -60,18 +61,38 @@ unit_lookup(char *units)
}
int
+string_from_line(char *buf, size_t buflen)
+{
+ char *line;
+ size_t sz;
+
+ line = fgetln(stdin, &sz);
+ if (line == NULL)
+ return (1);
+
+ if (line[sz - 1] == '\n')
+ line[--sz] = '\0';
+
+ if (sz < buflen) {
+ memcpy(buf, line, sz);
+ buf[sz] = '\0';
+ } else {
+ memcpy(buf, line, buflen - 1);
+ buf[buflen - 1] = '\0';
+ }
+
+ return (0);
+}
+
+int
ask_cmd(char **cmd, char **args)
{
static char lbuf[100];
char *cp, *buf;
- size_t lbuflen;
/* Get input */
- if (fgets(lbuf, sizeof lbuf, stdin) == NULL)
+ if (string_from_line(lbuf, sizeof(lbuf)))
errx(1, "eof");
- lbuflen = strlen(lbuf);
- if (lbuflen > 0 && lbuf[lbuflen - 1] == '\n')
- lbuf[lbuflen - 1] = '\0';
/* Parse input */
buf = lbuf;
@@ -89,7 +110,6 @@ ask_num(const char *str, int dflt, int low, int high)
{
char lbuf[100];
const char *errstr;
- size_t lbuflen;
int num;
if (dflt < low)
@@ -100,13 +120,9 @@ ask_num(const char *str, int dflt, int low, int high)
do {
printf("%s [%d - %d]: [%d] ", str, low, high, dflt);
- if (fgets(lbuf, sizeof lbuf, stdin) == NULL)
+ if (string_from_line(lbuf, sizeof(lbuf)))
errx(1, "eof");
- lbuflen = strlen(lbuf);
- if (lbuflen > 0 && lbuf[lbuflen - 1] == '\n')
- lbuf[lbuflen - 1] = '\0';
-
if (lbuf[0] == '\0') {
num = dflt;
errstr = NULL;
@@ -121,36 +137,29 @@ ask_num(const char *str, int dflt, int low, int high)
}
int
-ask_pid(int dflt, int low, int high)
+ask_pid(int dflt, struct uuid *guid)
{
char lbuf[100], *cp;
- size_t lbuflen;
- int num = -1;
-
- if (low == 1)
- low = 0; /* Show continguous range */
-
- if (dflt < low)
- dflt = low;
- else if (dflt > high)
- dflt = high;
+ int num = -1, status;
do {
- printf("Partition id ('0' to disable) [%X - %X]: [%X] ", low,
- high, dflt);
+ printf("Partition id ('0' to disable) [01 - FF]: [%X] ", dflt);
printf("(? for help) ");
- if (fgets(lbuf, sizeof lbuf, stdin) == NULL)
+ if (string_from_line(lbuf, sizeof(lbuf)))
errx(1, "eof");
- lbuflen = strlen(lbuf);
- if (lbuflen > 0 && lbuf[lbuflen - 1] == '\n')
- lbuf[lbuflen - 1] = '\0';
if (lbuf[0] == '?') {
PRT_printall();
continue;
}
+ if (guid) {
+ uuid_from_string(lbuf, guid, &status);
+ if (status == uuid_s_ok)
+ return (0x100);
+ }
+
/* Convert */
cp = lbuf;
num = strtol(lbuf, &cp, 16);
@@ -160,13 +169,13 @@ ask_pid(int dflt, int low, int high)
num = dflt;
if (*cp != '\0') {
printf("'%s' is not a valid number.\n", lbuf);
- num = low - 1;
+ num = -1;
} else if (num == 0) {
break;
- } else if (num < low || num > high) {
+ } else if (num < 0 || num > 0xff) {
printf("'%x' is out of range.\n", num);
}
- } while (num < low || num > high);
+ } while (num < 0 || num > 0xff);
return (num);
}
@@ -215,13 +224,9 @@ getuint64(char *prompt, u_int64_t oval, u_int64_t maxval)
do {
printf("%s: [%llu] ", prompt, oval);
- if (fgets(buf, sizeof(buf), stdin) == NULL)
+ if (string_from_line(buf, sizeof(buf)))
errx(1, "eof");
- n = strlen(buf);
- if (n > 0 && buf[n-1] == '\n')
- buf[--n] = '\0';
-
if (buf[0] == '\0') {
return (oval);
} else if (buf[0] == '*' && buf[1] == '\0') {
@@ -229,6 +234,7 @@ getuint64(char *prompt, u_int64_t oval, u_int64_t maxval)
}
/* deal with units */
+ n = strlen(buf);
switch (tolower((unsigned char)buf[n-1])) {
case 'c':
unit = 'c';
@@ -318,28 +324,17 @@ getuint64(char *prompt, u_int64_t oval, u_int64_t maxval)
char *
ask_string(const char *prompt, const char *oval)
{
- static char buf[BUFSIZ];
- int n;
+ static char buf[37];
buf[0] = '\0';
- do {
- printf("%s: [%s] ", prompt, oval ? oval : "");
- if (fgets(buf, sizeof(buf), stdin) == NULL) {
- buf[0] = '\0';
- if (feof(stdin)) {
- clearerr(stdin);
- putchar('\n');
- return(NULL);
- }
- }
- n = strlen(buf);
- if (n > 0 && buf[n-1] == '\n')
- buf[--n] = '\0';
- else if (oval != NULL && buf[0] == '\0')
- strlcpy(buf, oval, sizeof(buf));
- } while (buf[0] == '?');
+ printf("%s: [%s] ", prompt, oval ? oval : "");
+ if (string_from_line(buf, sizeof(buf)))
+ errx(1, "eof");
- return(&buf[0]);
+ if (buf[0] == '\0' && oval)
+ strlcpy(buf, oval, sizeof(buf));
+
+ return(buf);
}
/*
@@ -372,3 +367,37 @@ crc32(const u_char *buf, const u_int32_t size)
return ~crc;
}
+
+char *
+utf16le_to_string(u_int16_t *utf)
+{
+ static char name[36];
+ int i;
+
+ for (i = 0; i < sizeof(name); i++) {
+ name[i] = letoh16(utf[i]) & 0x7F;
+ if (name[i] == '\0')
+ break;
+ }
+ if (i == sizeof(name))
+ name[i - 1] = '\0';
+
+ return (name);
+}
+
+u_int16_t *
+string_to_utf16le(char *ch)
+{
+ static u_int16_t utf[36];
+ int i;
+
+ for (i = 0; i < sizeof(utf); i++) {
+ utf[i] = htole16((unsigned int)ch[i]);
+ if (utf[i] == 0)
+ break;
+ }
+ if (i == sizeof(utf))
+ utf[i - 1] = 0;
+
+ return (utf);
+}
diff --git a/sbin/fdisk/misc.h b/sbin/fdisk/misc.h
index 04d95c5865d..263fbd2d5c5 100644
--- a/sbin/fdisk/misc.h
+++ b/sbin/fdisk/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.30 2015/03/30 17:11:49 krw Exp $ */
+/* $OpenBSD: misc.h,v 1.31 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -29,12 +29,15 @@ extern struct unit_type unit_types[];
/* Prototypes */
int unit_lookup(char *);
+int string_from_line(char *, size_t);
int ask_cmd(char **, char **);
int ask_num(const char *, int, int, int);
-int ask_pid(int, int, int);
+int ask_pid(int, struct uuid *);
char *ask_string(const char *, const char *);
int ask_yn(const char *);
u_int64_t getuint64(char *, u_int64_t, u_int64_t);
u_int32_t crc32(const u_char *, const u_int32_t);
+char *utf16le_to_string(u_int16_t *);
+u_int16_t *string_to_utf16le(char *);
#endif /* _MISC_H */
diff --git a/sbin/fdisk/part.c b/sbin/fdisk/part.c
index 1ad2a85f5b9..04ce07a7d18 100644
--- a/sbin/fdisk/part.c
+++ b/sbin/fdisk/part.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: part.c,v 1.72 2015/03/27 16:06:00 krw Exp $ */
+/* $OpenBSD: part.c,v 1.73 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -20,7 +20,9 @@
#include <sys/disklabel.h>
#include <err.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <uuid.h>
#include "disk.h"
#include "misc.h"
@@ -31,39 +33,40 @@ int PRT_check_chs(struct prt *partn);
static const struct part_type {
int type;
char sname[14];
+ char guid[37];
} part_types[] = {
- { 0x00, "unused "}, /* unused */
- { 0x01, "DOS FAT-12 "}, /* Primary DOS with 12 bit FAT */
+ { 0x00, "unused ", "00000000-0000-0000-0000-000000000000" },
+ { 0x01, "DOS FAT-12 ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
{ 0x02, "XENIX / "}, /* XENIX / filesystem */
{ 0x03, "XENIX /usr "}, /* XENIX /usr filesystem */
- { 0x04, "DOS FAT-16 "}, /* Primary DOS with 16 bit FAT */
+ { 0x04, "DOS FAT-16 ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
{ 0x05, "Extended DOS"}, /* Extended DOS */
- { 0x06, "DOS > 32MB "}, /* Primary 'big' DOS (> 32MB) */
- { 0x07, "NTFS "}, /* NTFS */
+ { 0x06, "DOS > 32MB ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
+ { 0x07, "NTFS ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
{ 0x08, "AIX fs "}, /* AIX filesystem */
{ 0x09, "AIX/Coherent"}, /* AIX boot partition or Coherent */
{ 0x0A, "OS/2 Bootmgr"}, /* OS/2 Boot Manager or OPUS */
- { 0x0B, "Win95 FAT-32"}, /* Primary Win95 w/ 32-bit FAT */
- { 0x0C, "Win95 FAT32L"}, /* Primary Win95 w/ 32-bit FAT LBA-mapped */
- { 0x0E, "DOS FAT-16 "}, /* Primary DOS w/ 16-bit FAT, CHS-mapped */
+ { 0x0B, "Win95 FAT-32", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
+ { 0x0C, "Win95 FAT32L", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
+ { 0x0E, "DOS FAT-16 ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
{ 0x0F, "Extended LBA"}, /* Extended DOS LBA-mapped */
{ 0x10, "OPUS "}, /* OPUS */
- { 0x11, "OS/2 hidden "}, /* OS/2 BM: hidden DOS 12-bit FAT */
+ { 0x11, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
{ 0x12, "Compaq Diag."}, /* Compaq Diagnostics */
- { 0x14, "OS/2 hidden "}, /* OS/2 BM: hidden DOS 16-bit FAT <32M or Novell DOS 7.0 bug */
- { 0x16, "OS/2 hidden "}, /* OS/2 BM: hidden DOS 16-bit FAT >=32M */
- { 0x17, "OS/2 hidden "}, /* OS/2 BM: hidden IFS */
+ { 0x14, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
+ { 0x16, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
+ { 0x17, "OS/2 hidden ", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
{ 0x18, "AST swap "}, /* AST Windows swapfile */
{ 0x19, "Willowtech "}, /* Willowtech Photon coS */
- { 0x1C, "ThinkPad Rec"}, /* IBM ThinkPad recovery partition */
- { 0x20, "Willowsoft "}, /* Willowsoft OFS1 */
+ { 0x1C, "ThinkPad Rec", "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
{ 0x24, "NEC DOS "}, /* NEC DOS */
- { 0x27, "Win Recovery"}, /* Windows hidden Recovery Partition */
+ { 0x27, "Win Recovery", "de94bba4-06d1-4d40-a16a-bfd50179d6ac" },
+ { 0x20, "Willowsoft "}, /* Willowsoft OFS1 */
{ 0x38, "Theos "}, /* Theos */
{ 0x39, "Plan 9 "}, /* Plan 9 */
{ 0x40, "VENIX 286 "}, /* VENIX 286 or LynxOS */
{ 0x41, "Lin/Minux DR"}, /* Linux/MINIX (sharing disk with DRDOS) or Personal RISC boot */
- { 0x42, "LinuxSwap DR"}, /* SFS or Linux swap (sharing disk with DRDOS) */
+ { 0x42, "LinuxSwap DR", "af9b60a0-1431-4f62-bc68-3311714a69ad" },
{ 0x43, "Linux DR "}, /* Linux native (sharing disk with DRDOS) */
{ 0x4D, "QNX 4.2 Pri "}, /* QNX 4.2 Primary */
{ 0x4E, "QNX 4.2 Sec "}, /* QNX 4.2 Secondary */
@@ -86,30 +89,31 @@ static const struct part_type {
{ 0x69, "Novell "}, /* Novell */
{ 0x70, "DiskSecure "}, /* DiskSecure Multi-Boot */
{ 0x75, "PCIX "}, /* PCIX */
+ { 0x7f, "ChromeKernel", "fe3a2a5d-4f32-41a7-b725-accc3285a309" },
{ 0x80, "Minix (old) "}, /* Minix 1.1 ... 1.4a */
{ 0x81, "Minix (new) "}, /* Minix 1.4b ... 1.5.10 */
- { 0x82, "Linux swap "}, /* Linux swap */
- { 0x83, "Linux files*"}, /* Linux filesystem */
+ { 0x82, "Linux swap ", "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f" },
+ { 0x83, "Linux files*", "0fc63daf-8483-4772-8e79-3d69d8477de4" },
{ 0x84, "OS/2 hidden "}, /* OS/2 hidden C: drive */
{ 0x85, "Linux ext. "}, /* Linux extended */
{ 0x86, "NT FAT VS "}, /* NT FAT volume set */
{ 0x87, "NTFS VS "}, /* NTFS volume set or HPFS mirrored */
- { 0x8E, "Linux LVM "}, /* Linux LVM */
+ { 0x8E, "Linux LVM ", "e6d6d379-f507-44c2-a23c-238f2a3df928" },
{ 0x93, "Amoeba FS "}, /* Amoeba filesystem */
{ 0x94, "Amoeba BBT "}, /* Amoeba bad block table */
{ 0x99, "Mylex "}, /* Mylex EISA SCSI */
{ 0x9F, "BSDI "}, /* BSDI BSD/OS */
{ 0xA0, "NotebookSave"}, /* Phoenix NoteBIOS save-to-disk */
- { 0xA5, "FreeBSD "}, /* FreeBSD */
- { 0xA6, "OpenBSD "}, /* OpenBSD */
+ { 0xA5, "FreeBSD ", "516e7cb4-6ecf-11d6-8ff8-00022d09712b" },
+ { 0xA6, "OpenBSD ", "824cc7a0-36a8-11e3-890a-952519ad3f61" },
{ 0xA7, "NEXTSTEP "}, /* NEXTSTEP */
- { 0xA8, "MacOS X "}, /* MacOS X main partition */
- { 0xA9, "NetBSD "}, /* NetBSD */
- { 0xAB, "MacOS X boot"}, /* MacOS X boot partition */
- { 0xAF, "MacOS X HFS+"}, /* MacOS X HFS+ partition */
+ { 0xA8, "MacOS X ", "55465300-0000-11aa-aa11-00306543ecac" },
+ { 0xA9, "NetBSD ", "516e7cb4-6ecf-11d6-8ff8-00022d09712b" },
+ { 0xAB, "MacOS X boot", "426f6f74-0000-11aa-aa11-00306543ecac" },
+ { 0xAF, "MacOS X HFS+", "48465300-0000-11aa-aa11-00306543ecac" },
{ 0xB7, "BSDI filesy*"}, /* BSDI BSD/386 filesystem */
{ 0xB8, "BSDI swap "}, /* BSDI BSD/386 swap */
- { 0xBF, "Solaris "}, /* Solaris */
+ { 0xBF, "Solaris ", "6a85cf4d-1dd2-11b2-99a6-080020736631" },
{ 0xC0, "CTOS "}, /* CTOS */
{ 0xC1, "DRDOSs FAT12"}, /* DRDOS/sec (FAT-12) */
{ 0xC4, "DRDOSs < 32M"}, /* DRDOS/sec (FAT-16, < 32M) */
@@ -120,9 +124,9 @@ static const struct part_type {
{ 0xE1, "SpeedStor "}, /* DOS access or SpeedStor 12-bit FAT extended partition */
{ 0xE3, "SpeedStor "}, /* DOS R/O or SpeedStor or Storage Dimensions */
{ 0xE4, "SpeedStor "}, /* SpeedStor 16-bit FAT extended partition < 1024 cyl. */
- { 0xEB, "BeOS/i386 "}, /* BeOS for Intel */
+ { 0xEB, "BeOS/i386 ", "42465331-3ba3-10f1-802a-4861696b7521" },
{ 0xEE, "EFI GPT "}, /* EFI Protective Partition */
- { 0xEF, "EFI Sys "}, /* EFI System Partition */
+ { 0xEF, "EFI Sys ", "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" },
{ 0xF1, "SpeedStor "}, /* SpeedStor or Storage Dimensions */
{ 0xF2, "DOS 3.3+ Sec"}, /* DOS 3.3+ Secondary */
{ 0xF4, "SpeedStor "}, /* SpeedStor >1024 cyl. or LANstep or IBM PS/2 IML */
@@ -268,6 +272,7 @@ PRT_make(struct prt *partn, off_t offset, off_t reloff,
void
PRT_print(int num, struct prt *partn, char *units)
{
+ const int secsize = unit_types[SECTORS].conversion;
double size;
int i;
@@ -281,8 +286,7 @@ PRT_print(int num, struct prt *partn, char *units)
printf("---------------------------------------"
"----------------------------------------\n");
} else {
- size = ((double)partn->ns * unit_types[SECTORS].conversion) /
- unit_types[i].conversion;
+ size = ((double)partn->ns * secsize) / unit_types[i].conversion;
printf("%c%1d: %.2X %6u %3u %3u - %6u %3u %3u "
"[%12llu:%12.0f%s] %s\n",
(partn->flag == DOSACTIVE)?'*':' ',
@@ -369,3 +373,58 @@ PRT_fix_CHS(struct prt *part)
part->ehead = head;
part->esect = sect;
}
+
+char *
+PRT_uuid_to_type(struct uuid *uuid)
+{
+ static char partition_type[37]; /* Room for a GUID if needed. */
+ char *uuidstr = NULL;
+ int i, entries, status;
+
+ memset(partition_type, 0, sizeof(partition_type));
+
+ uuid_to_string(uuid, &uuidstr, &status);
+ if (status != uuid_s_ok)
+ goto done;
+
+ entries = sizeof(part_types) / sizeof(struct part_type);
+
+ for (i = 0; i < entries; i++) {
+ if (memcmp(part_types[i].guid, uuidstr,
+ sizeof(part_types[i].guid)) == 0)
+ break;
+ }
+
+ if (i < entries)
+ strlcpy(partition_type, part_types[i].sname,
+ sizeof(partition_type));
+ else
+ strlcpy(partition_type, uuidstr, sizeof(partition_type));
+
+done:
+ free(uuidstr);
+
+ return (partition_type);
+}
+
+struct uuid *
+PRT_type_to_uuid(int type)
+{
+ static struct uuid guid;
+ int i, entries, status = uuid_s_ok;
+
+ memset(&guid, 0, sizeof(guid));
+
+ entries = sizeof(part_types) / sizeof(struct part_type);
+
+ for (i = 0; i < entries; i++) {
+ if (part_types[i].type == type)
+ break;
+ }
+ if (i < entries)
+ uuid_from_string(part_types[i].guid, &guid, &status);
+ if (i == entries || status != uuid_s_ok)
+ uuid_from_string(part_types[0].guid, &guid, &status);
+
+ return (&guid);
+}
diff --git a/sbin/fdisk/part.h b/sbin/fdisk/part.h
index 645c1c8c2df..c1b2299f0ed 100644
--- a/sbin/fdisk/part.h
+++ b/sbin/fdisk/part.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: part.h,v 1.19 2015/03/26 14:08:12 krw Exp $ */
+/* $OpenBSD: part.h,v 1.20 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -34,6 +34,8 @@ void PRT_parse(struct dos_partition *, off_t, off_t,
struct prt *);
void PRT_make(struct prt *, off_t, off_t, struct dos_partition *);
void PRT_print(int, struct prt *, char *);
+char *PRT_uuid_to_type(struct uuid *);
+struct uuid *PRT_type_to_uuid(int);
/* This does CHS -> bs/ns */
void PRT_fix_BN(struct prt *, int);
diff --git a/sbin/fdisk/user.c b/sbin/fdisk/user.c
index 65d995e9b4e..40d40a73253 100644
--- a/sbin/fdisk/user.c
+++ b/sbin/fdisk/user.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: user.c,v 1.44 2015/04/02 18:00:55 krw Exp $ */
+/* $OpenBSD: user.c,v 1.45 2015/10/26 15:08:26 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -30,25 +30,26 @@
#include "misc.h"
#include "cmd.h"
#include "user.h"
+#include "gpt.h"
/* Our command table */
struct cmd cmd_table[] = {
- {"help", Xhelp, "Command help list"},
- {"manual", Xmanual, "Show entire OpenBSD man page for fdisk"},
- {"reinit", Xreinit, "Re-initialize loaded MBR (to defaults)"},
- {"setpid", Xsetpid, "Set the identifier of a given table entry"},
- {"disk", Xdisk, "Edit current drive stats"},
- {"edit", Xedit, "Edit given table entry"},
- {"flag", Xflag, "Flag given table entry as bootable"},
- {"update", Xupdate, "Update machine code in loaded MBR"},
- {"select", Xselect, "Select extended partition table entry MBR"},
- {"swap", Xswap, "Swap two partition entries"},
- {"print", Xprint, "Print loaded MBR partition table"},
- {"write", Xwrite, "Write loaded MBR to disk"},
- {"exit", Xexit, "Exit edit of current MBR, without saving changes"},
- {"quit", Xquit, "Quit edit of current MBR, saving current changes"},
- {"abort", Xabort, "Abort program without saving current changes"},
- {NULL, NULL, NULL}
+ {"help", 1, Xhelp, "Command help list"},
+ {"manual", 1, Xmanual, "Show entire OpenBSD man page for fdisk"},
+ {"reinit", 1, Xreinit, "Re-initialize loaded MBR (to defaults)"},
+ {"setpid", 1, Xsetpid, "Set the identifier of a given table entry"},
+ {"disk", 0, Xdisk, "Edit current drive stats"},
+ {"edit", 1, Xedit, "Edit given table entry"},
+ {"flag", 1, Xflag, "Flag given table entry as bootable"},
+ {"update", 0, Xupdate, "Update machine code in loaded MBR"},
+ {"select", 0, Xselect, "Select extended partition table entry MBR"},
+ {"swap", 1, Xswap, "Swap two partition entries"},
+ {"print", 1, Xprint, "Print loaded MBR partition table"},
+ {"write", 1, Xwrite, "Write loaded MBR to disk"},
+ {"exit", 1, Xexit, "Exit edit of current MBR, without saving changes"},
+ {"quit", 1, Xquit, "Quit edit of current MBR, saving current changes"},
+ {"abort", 1, Xabort, "Abort program without saving current changes"},
+ {NULL, 0, NULL, NULL}
};
@@ -96,7 +97,8 @@ again:
i = 0;
/* Check for valid command */
- if (cmd_table[i].cmd == NULL) {
+ if ((cmd_table[i].cmd == NULL) || (letoh64(gh.gh_sig) ==
+ GPTSIGNATURE && cmd_table[i].gpt == 0)) {
printf("Invalid command '%s'. Try 'help'.\n", cmd);
continue;
}
@@ -141,13 +143,17 @@ USER_print_disk(void)
fd = DISK_open(disk.name, O_RDONLY);
offset = firstoff = 0;
- DISK_printgeometry(NULL);
-
do {
error = MBR_read(fd, offset, &dos_mbr);
if (error == -1)
break;
MBR_parse(&dos_mbr, offset, firstoff, &mbr);
+ if (offset == 0 && MBR_protective_mbr(&mbr) == 0) {
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE) {
+ GPT_print("s");
+ break;
+ }
+ }
MBR_print(&mbr, NULL);