Sync with HEAD:

Makefile: 1.7
	add.c: 1.12, 1.23
	create.c: 1.11
	destroy.c: 1.6
	gpt.8: 1.14, 1.15
	gpt.c: 1.11, 1.12, 1.13
	gpt.h: 1.8, 1.9, 1.10
	label.c: 1.1
	map.c: 1.6
	map.h: 1.6
	migrate.c: 1.14, 1.15, 1.16
	recover.c: 1.8
	remove.c: 1.5, 1.6, 1.7, 1.8
	show.c: 1.12, 1.13
o  New -l and -u options to the show command,
o  New label command to support GPT labels,
o  The remove command doesn't print the total partitions removed,
   as it prints each partition it removes by name already,
o  Added ellipsis to most usage messages.

PR: ia64/83124
Approved by: re (scottl)
This commit is contained in:
marcel 2005-09-06 23:59:01 +00:00
parent ac8c96d5ba
commit fe61c11618
14 changed files with 255 additions and 87 deletions

View File

@ -1,8 +1,8 @@
# $FreeBSD$
PROG= gpt
SRCS= add.c create.c destroy.c gpt.c map.c migrate.c recover.c remove.c \
show.c
SRCS= add.c create.c destroy.c gpt.c label.c map.c migrate.c recover.c \
remove.c show.c
WARNS?= 4
MAN= gpt.8

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*
@ -48,7 +48,7 @@ usage_add(void)
{
fprintf(stderr,
"usage: %s [-b lba] [-i index] [-s lba] [-t uuid] device\n",
"usage: %s [-b lba] [-i index] [-s lba] [-t uuid] device ...\n",
getprogname());
exit(1);
}

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd November 12, 2004
.Dd August 31, 2005
.Os
.Dt GPT 8
.Sh NAME
@ -165,6 +165,71 @@ The
option instructs
.Nm
to destroy the table in a way that it can be recovered.
.\" ==== label ====
.It Xo
.Nm
.Ic label
.Op Fl a
.Aq Fl f Ar file | Fl l Ar label
.Ar device ...
.Xc
.It Xo
.Nm
.Ic label
.Op Fl b Ar number
.Op Fl i Ar index
.Op Fl s Ar count
.Op Fl t Ar type
.Aq Fl f Ar file | Fl l Ar label
.Ar device ...
.Xc
The
.Ic label
command allows the user to label any partitions that match the selection.
At least one of the following selection options must be specified.
.Pp
The
.Fl a
option specifies that all partitions should be labeled.
It is mutually exclusive with all other selection options.
.Pp
The
.Fl b Ar number
option selects the partition that starts at the given block number.
.Pp
The
.Fl i Ar index
option selects the partition with the given partition number.
.Pp
The
.Fl s Ar count
option selects all partitions that have the given size.
This can cause multiple partitions to be removed.
.Pp
The
.Fl t Ar type
option selects all partitions that have the given type.
The type is given as an UUID or by the aliases that the
.Ic add
command accepts.
This can cause multiple partitions to be removed.
.Pp
The
.Fl f Ar file
or
.Fl l Ar label
options specify the new label to be assigned to the selected partitions.
The
.Fl f Ar file
option is used to read the label from the specified file.
Only the first line is read from the file and the trailing newline
character is stripped.
If the file name is the dash or minus sign (-), the label is read from
the standard input.
The
.Fl l Ar label
option is used to specify the label in the command line.
The label is assumed to be encoded in UTF-8.
.\" ==== migrate ====
.It Nm Ic migrate Oo Fl fs Oc Ar device ...
The
@ -188,7 +253,7 @@ option prevents migrating
disk labels into GPT partitions by creating
the GPT equivalent of a slice.
.\" ==== remove ====
.It Nm Ic remove Oo Fl a Oc
.It Nm Ic remove Oo Fl a Oc Ar device ...
.It Xo
.Nm
.Ic remove
@ -200,40 +265,34 @@ the GPT equivalent of a slice.
.Xc
The
.Ic remove
command allows the user to remove any partitions that match the selection.
At least one option must be specified.
.Pp
The
.Fl a
option specifies that all partitions should be removed.
It is mutually exclusive with all other options.
.Pp
The
.Fl b Ar number
option selects the partitions that starts at the given number.
.Pp
The
.Fl i Ar index
option selects the partition with the given partition number.
.Pp
The
.Fl s Ar count
option selects all partitions that have the given size.
This can cause multiple partitions to be removed.
.Pp
The
.Fl t Ar type
option selects all partitions that have the given type.
The type is given as an UUID or by the aliases that the
.Ic add
command accepts.
This can cause multiple partitions to be removed.
command allows the user to remove any and all partitions that match the
selection.
It uses the same selection options as the
.Ic label
command.
See above for a description of these options.
Partitions are removed by clearing the partition type.
No other information is changed.
.\" ==== show ====
.It Nm Ic show Ar device ...
.It Nm Ic show Oo Fl lu Oc Ar device ...
The
.Ic show
command displays the current partitioning on the listed devices and gives
an overall view of the disk contents.
With the
.Fl l
option the GPT partition label will be displayed instead of the GPT partition
type.
The option has no effect on non-GPT partitions.
With the
.Fl u
option the GPT partition type is displayed as an UUID instead of in an
user friendly form.
The
.Fl l
option takes precedence over the
.Fl u
option.
.El
.Sh SEE ALSO
.Xr fdisk 8 ,

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*
@ -118,13 +118,112 @@ crc32(const void *buf, size_t size)
return crc ^ ~0U;
}
void
unicode16(short *dst, const wchar_t *src, size_t len)
uint8_t *
utf16_to_utf8(uint16_t *s16)
{
while (len-- && *src != 0)
*dst++ = *src++;
if (len)
*dst = 0;
static uint8_t *s8 = NULL;
static size_t s8len = 0;
size_t s8idx, s16idx, s16len;
uint32_t utfchar;
unsigned int c;
s16len = 0;
while (s16[s16len++] != 0)
;
if (s8len < s16len * 3) {
if (s8 != NULL)
free(s8);
s8len = s16len * 3;
s8 = calloc(s16len, 3);
}
s8idx = s16idx = 0;
while (s16idx < s16len) {
utfchar = le16toh(s16[s16idx++]);
if ((utfchar & 0xf800) == 0xd800) {
c = le16toh(s16[s16idx]);
if ((utfchar & 0x400) != 0 || (c & 0xfc00) != 0xdc00)
utfchar = 0xfffd;
else
s16idx++;
}
if (utfchar < 0x80) {
s8[s8idx++] = utfchar;
} else if (utfchar < 0x800) {
s8[s8idx++] = 0xc0 | (utfchar >> 6);
s8[s8idx++] = 0x80 | (utfchar & 0x3f);
} else if (utfchar < 0x10000) {
s8[s8idx++] = 0xe0 | (utfchar >> 12);
s8[s8idx++] = 0x80 | ((utfchar >> 6) & 0x3f);
s8[s8idx++] = 0x80 | (utfchar & 0x3f);
} else if (utfchar < 0x200000) {
s8[s8idx++] = 0xf0 | (utfchar >> 18);
s8[s8idx++] = 0x80 | ((utfchar >> 12) & 0x3f);
s8[s8idx++] = 0x80 | ((utfchar >> 6) & 0x3f);
s8[s8idx++] = 0x80 | (utfchar & 0x3f);
}
}
return (s8);
}
void
utf8_to_utf16(const uint8_t *s8, uint16_t *s16, size_t s16len)
{
size_t s16idx, s8idx, s8len;
uint32_t utfchar;
unsigned int c, utfbytes;
s8len = 0;
while (s8[s8len++] != 0)
;
s8idx = s16idx = 0;
utfbytes = 0;
do {
c = s8[s8idx++];
if ((c & 0xc0) != 0x80) {
/* Initial characters. */
if (utfbytes != 0) {
/* Incomplete encoding. */
s16[s16idx++] = 0xfffd;
if (s16idx == s16len) {
s16[--s16idx] = 0;
return;
}
}
if ((c & 0xf8) == 0xf0) {
utfchar = c & 0x07;
utfbytes = 3;
} else if ((c & 0xf0) == 0xe0) {
utfchar = c & 0x0f;
utfbytes = 2;
} else if ((c & 0xe0) == 0xc0) {
utfchar = c & 0x1f;
utfbytes = 1;
} else {
utfchar = c & 0x7f;
utfbytes = 0;
}
} else {
/* Followup characters. */
if (utfbytes > 0) {
utfchar = (utfchar << 6) + (c & 0x3f);
utfbytes--;
} else if (utfbytes == 0)
utfbytes = -1;
}
if (utfbytes == 0) {
if (utfchar >= 0x10000 && s16idx + 2 >= s16len)
utfchar = 0xfffd;
if (utfchar >= 0x10000) {
s16[s16idx++] = 0xd800 | ((utfchar>>10)-0x40);
s16[s16idx++] = 0xdc00 | (utfchar & 0x3ff);
} else
s16[s16idx++] = utfchar;
if (s16idx == s16len) {
s16[--s16idx] = 0;
return;
}
}
} while (c != 0);
}
void
@ -457,6 +556,7 @@ static struct {
{ cmd_create, "create" },
{ cmd_destroy, "destroy" },
{ NULL, "help" },
{ cmd_label, "label" },
{ cmd_migrate, "migrate" },
{ cmd_recover, "recover" },
{ cmd_remove, "remove" },
@ -471,7 +571,7 @@ usage(void)
{
fprintf(stderr,
"usage: %s [-rv] [-p nparts] command [options] device\n",
"usage: %s [-rv] [-p nparts] command [options] device ...\n",
getprogname());
exit(1);
}

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*
@ -70,11 +70,14 @@ void gpt_close(int);
int gpt_open(const char *);
void* gpt_read(int, off_t, size_t);
int gpt_write(int, map_t *);
void unicode16(short *, const wchar_t *, size_t);
uint8_t *utf16_to_utf8(uint16_t *);
void utf8_to_utf16(const uint8_t *, uint16_t *, size_t);
int cmd_add(int, char *[]);
int cmd_create(int, char *[]);
int cmd_destroy(int, char *[]);
int cmd_label(int, char *[]);
int cmd_migrate(int, char *[]);
int cmd_recover(int, char *[]);
int cmd_remove(int, char *[]);

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*
@ -59,7 +59,7 @@ usage_migrate(void)
{
fprintf(stderr,
"usage: %s [-fs] device\n", getprogname());
"usage: %s [-fs] device ...\n", getprogname());
exit(1);
}
@ -100,22 +100,22 @@ migrate_disklabel(int fd, off_t start, struct gpt_ent *ent)
case FS_SWAP: {
uuid_t swap = GPT_ENT_TYPE_FREEBSD_SWAP;
le_uuid_enc(&ent->ent_type, &swap);
unicode16(ent->ent_name,
L"FreeBSD swap partition", 36);
utf8_to_utf16("FreeBSD swap partition",
ent->ent_name, 36);
break;
}
case FS_BSDFFS: {
uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS;
le_uuid_enc(&ent->ent_type, &ufs);
unicode16(ent->ent_name,
L"FreeBSD UFS partition", 36);
utf8_to_utf16("FreeBSD UFS partition",
ent->ent_name, 36);
break;
}
case FS_VINUM: {
uuid_t vinum = GPT_ENT_TYPE_FREEBSD_VINUM;
le_uuid_enc(&ent->ent_type, &vinum);
unicode16(ent->ent_name,
L"FreeBSD vinum partition", 36);
utf8_to_utf16("FreeBSD vinum partition",
ent->ent_name, 36);
break;
}
default:
@ -255,8 +255,8 @@ migrate(int fd)
le_uuid_enc(&ent->ent_type, &freebsd);
ent->ent_lba_start = htole64((uint64_t)start);
ent->ent_lba_end = htole64(start + size - 1LL);
unicode16(ent->ent_name,
L"FreeBSD disklabel partition", 36);
utf8_to_utf16("FreeBSD disklabel partition",
ent->ent_name, 36);
ent++;
} else
ent = migrate_disklabel(fd, start, ent);
@ -267,7 +267,8 @@ migrate(int fd)
le_uuid_enc(&ent->ent_type, &efi_slice);
ent->ent_lba_start = htole64((uint64_t)start);
ent->ent_lba_end = htole64(start + size - 1LL);
unicode16(ent->ent_name, L"EFI system partition", 36);
utf8_to_utf16("EFI system partition",
ent->ent_name, 36);
ent++;
break;
}

View File

@ -1,11 +0,0 @@
#!/bin/sh
# $FreeBSD$
dd if=/dev/zero of=disk count=125307
sudo mdconfig -a -t vnode -f disk -u 4
sudo fdisk -f - md4 <<EOF
g c567 h13 s17
p 1 165 221 124865
EOF
sudo bsdlabel -w -r md4s1 pan60
sudo mdconfig -d -u 4

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
@ -49,8 +49,8 @@ usage_remove(void)
{
fprintf(stderr,
"usage: %s -a device\n"
" %s [-b lba] [-i index] [-s lba] [-t uuid] device\n",
"usage: %s -a device ...\n"
" %s [-b lba] [-i index] [-s lba] [-t uuid] device ...\n",
getprogname(), getprogname());
exit(1);
}
@ -64,7 +64,7 @@ rem(int fd)
map_t *m;
struct gpt_hdr *hdr;
struct gpt_ent *ent;
unsigned int i, removed;
unsigned int i;
gpt = map_find(MAP_TYPE_PRI_GPT_HDR);
if (gpt == NULL) {
@ -87,8 +87,6 @@ rem(int fd)
return;
}
removed = 0;
/* Remove all matching entries in the map. */
for (m = map_first(); m != NULL; m = m->map_next) {
if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
@ -109,6 +107,8 @@ rem(int fd)
if (!uuid_is_nil(&type, NULL) &&
!uuid_equal(&type, &uuid, NULL))
continue;
/* Remove the primary entry by clearing the partition type. */
uuid_create_nil(&ent->ent_type, NULL);
hdr->hdr_crc_table = htole32(crc32(tbl->map_data,
@ -122,6 +122,8 @@ rem(int fd)
hdr = tpg->map_data;
ent = (void*)((char*)lbt->map_data + i *
le32toh(hdr->hdr_entsz));
/* Remove the secundary entry. */
uuid_create_nil(&ent->ent_type, NULL);
hdr->hdr_crc_table = htole32(crc32(lbt->map_data,
@ -133,11 +135,7 @@ rem(int fd)
gpt_write(fd, tpg);
printf("%sp%u removed\n", device_name, m->map_index);
removed++;
}
warnx("%s: %d partition(s) removed", device_name, removed);
}
int

View File

@ -1,4 +1,4 @@
/*
/*-
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
*
@ -39,12 +39,15 @@ __FBSDID("$FreeBSD$");
#include "map.h"
#include "gpt.h"
static int show_label = 0;
static int show_uuid = 0;
static void
usage_show(void)
{
fprintf(stderr,
"usage: %s device ...\n", getprogname());
"usage: %s [-lu] device ...\n", getprogname());
exit(1);
}
@ -62,6 +65,9 @@ friendly(uuid_t *t)
static char buf[80];
char *s;
if (show_uuid)
goto unfriendly;
if (uuid_equal(t, &efi_slice, NULL))
return ("EFI System");
if (uuid_equal(t, &swap, NULL))
@ -80,6 +86,7 @@ friendly(uuid_t *t)
if (uuid_equal(t, &msr, NULL))
return ("Windows reserved");
unfriendly:
uuid_to_string(t, &s, NULL);
strlcpy(buf, s, sizeof buf);
free(s);
@ -148,8 +155,13 @@ show(int fd __unused)
case MAP_TYPE_GPT_PART:
printf("GPT part ");
ent = m->map_data;
le_uuid_dec(&ent->ent_type, &type);
printf("- %s", friendly(&type));
if (show_label) {
printf("- \"%s\"",
utf16_to_utf8(ent->ent_name));
} else {
le_uuid_dec(&ent->ent_type, &type);
printf("- %s", friendly(&type));
}
break;
case MAP_TYPE_PMBR:
printf("PMBR");
@ -165,8 +177,14 @@ cmd_show(int argc, char *argv[])
{
int ch, fd;
while ((ch = getopt(argc, argv, "")) != -1) {
while ((ch = getopt(argc, argv, "lu")) != -1) {
switch(ch) {
case 'l':
show_label = 1;
break;
case 'u':
show_uuid = 1;
break;
default:
usage_show();
}