o Save the partition number (=index) in the internal map. The index

starts at 1. No index is represented by 0.
o  Change the show command to display the partition number at the expense
   of the partition end columm. We already display the start and size.
o  Enhance the add command to accept the -i option. The -i option allows
   the user to specify which partition number the new partition should
   get.
o  Update the manpage accordingly.
This commit is contained in:
Marcel Moolenaar 2004-08-07 06:10:45 +00:00
parent e0b47a134b
commit f61bdfe072
6 changed files with 75 additions and 34 deletions

View file

@ -43,13 +43,15 @@
static uuid_t type;
static off_t block, size;
static unsigned int entry;
static void
usage_add(void)
{
fprintf(stderr,
"usage: %s [-b lba] [-s lba] [-t uuid] device\n", getprogname());
"usage: %s [-b lba] [-i index] [-s lba] [-t uuid] device\n",
getprogname());
exit(1);
}
@ -84,10 +86,34 @@ add(int fd)
return;
}
/* Create UFS partitions by default. */
if (uuid_is_nil(&type, NULL)) {
uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS;
type = ufs;
hdr = gpt->map_data;
if (entry > hdr->hdr_entries) {
warnx("%s: error: index %u out of range (%u max)", device_name,
entry, hdr->hdr_entries);
return;
}
if (entry > 0) {
i = entry - 1;
ent = (void*)((char*)tbl->map_data + i * hdr->hdr_entsz);
if (!uuid_is_nil(&ent->ent_type, NULL)) {
warnx("%s: error: entry at index %u is not free",
device_name, entry);
return;
}
} else {
/* Find empty slot in GPT table. */
for (i = 0; i < hdr->hdr_entries; i++) {
ent = (void*)((char*)tbl->map_data + i *
hdr->hdr_entsz);
if (uuid_is_nil(&ent->ent_type, NULL))
break;
}
if (i == hdr->hdr_entries) {
warnx("%s: error: no available table entries",
device_name);
return;
}
}
map = map_alloc(block, size);
@ -96,18 +122,6 @@ add(int fd)
return;
}
/* Find empty slot in GPT table. */
hdr = gpt->map_data;
for (i = 0; i < hdr->hdr_entries; i++) {
ent = (void*)((char*)tbl->map_data + i * hdr->hdr_entsz);
if (uuid_is_nil(&ent->ent_type, NULL))
break;
}
if (i == hdr->hdr_entries) {
warnx("%s: error: no available table entries", device_name);
return;
}
ent->ent_type = type;
ent->ent_lba_start = map->map_start;
ent->ent_lba_end = map->map_start + map->map_size - 1LL;
@ -144,7 +158,7 @@ cmd_add(int argc, char *argv[])
uint32_t status;
/* Get the migrate options */
while ((ch = getopt(argc, argv, "b:s:t:")) != -1) {
while ((ch = getopt(argc, argv, "b:i:s:t:")) != -1) {
switch(ch) {
case 'b':
if (block > 0)
@ -153,6 +167,13 @@ cmd_add(int argc, char *argv[])
if (*p != 0 || block < 1)
usage_add();
break;
case 'i':
if (entry > 0)
usage_add();
entry = strtol(optarg, &p, 10);
if (*p != 0 || entry < 1)
usage_add();
break;
case 's':
if (size > 0)
usage_add();
@ -174,10 +195,10 @@ cmd_add(int argc, char *argv[])
} else if (strcmp(optarg, "ufs") == 0) {
uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS;
type = ufs;
} else if ((strcmp(optarg, "linux") == 0)
|| (strcmp(optarg, "windows") == 0)) {
uuid_t ext = GPT_ENT_TYPE_MS_BASIC_DATA;
type = ext ;
} else if (strcmp(optarg, "linux") == 0 ||
strcmp(optarg, "windows") == 0) {
uuid_t m = GPT_ENT_TYPE_MS_BASIC_DATA;
type = m;
} else
usage_add();
}
@ -190,6 +211,12 @@ cmd_add(int argc, char *argv[])
if (argc == optind)
usage_add();
/* Create UFS partitions by default. */
if (uuid_is_nil(&type, NULL)) {
uuid_t ufs = GPT_ENT_TYPE_FREEBSD_UFS;
type = ufs;
}
while (optind < argc) {
fd = gpt_open(argv[optind++]);
if (fd == -1) {

View file

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 1, 2004
.Dd August 6, 2004
.Os
.Dt GPT 8
.Sh NAME
@ -43,7 +43,7 @@ utility provides the necessary functionality to manipulate GUID partition
tables (GPTs), but see
.Sx BUGS
below for how and where functionality is missing.
The general usage model of the
The basic usage model of the
.Nm
tool follows that of the
.Xr cvs 1
@ -94,6 +94,7 @@ There is no formalized definition of the different levels yet.
.Nm
.Ic add
.Op Fl b Ar number
.Op Fl i Ar index
.Op Fl s Ar count
.Op Fl t Ar type
.Ar device ...
@ -113,6 +114,12 @@ The minimum sector number is 1, but has to fall inside an unused region of
disk space that is covered by the GPT.
.Pp
The
.Fl i Ar index
option allows the user to specify which (free) entry in the GPT table is to
be used for the new partition.
By default the first free entry is selected.
.Pp
The
.Fl s Ar count
option allows the user to specify the size of the partition in sectors.
The minimum size is 1.
@ -122,11 +129,11 @@ The
option allows the user to specify the partition type.
The type is given as an UUID, but
.Nm
has created
accepts
.Cm efi , swap , ufs , linux
and
.Cm windows
as aliases for some most commonly used partition types.
as aliases for the most commonly used partition types.
.\" ==== create ====
.It Xo
.Nm
@ -221,7 +228,7 @@ However, it is believed that the currently present functionality is reliable
and stable enough that this tool can be used without bullet-proof footware if
one thinks one does not make mistakes.
.Pp
It is expected that the generic usage model does not change, but it is
It is expected that the basic usage model does not change, but it is
possible that future versions will not be compatible in the strictest sense
of the word.
For example, the

View file

@ -237,6 +237,7 @@ gpt_mbr(int fd, off_t lba)
m = map_add(start, size, MAP_TYPE_MBR_PART, p);
if (m == NULL)
return (-1);
m->map_index = i + 1;
} else {
if (gpt_mbr(fd, start) == -1)
return (-1);
@ -321,6 +322,7 @@ gpt_gpt(int fd, off_t lba)
m = map_add(ent->ent_lba_start, size, MAP_TYPE_GPT_PART, ent);
if (m == NULL)
return (-1);
m->map_index = i + 1;
}
return (0);

View file

@ -49,6 +49,7 @@ mkmap(off_t start, off_t size, int type)
m->map_size = size;
m->map_next = m->map_prev = NULL;
m->map_type = type;
m->map_index = 0;
m->map_data = NULL;
return (m);
}

View file

@ -44,6 +44,7 @@ typedef struct map {
#define MAP_TYPE_SEC_GPT_TBL 6
#define MAP_TYPE_GPT_PART 7
#define MAP_TYPE_PMBR 8
int map_index;
void *map_data;
} map_t;

View file

@ -90,25 +90,28 @@ friendly(uuid_t *t)
static void
show(int fd __unused)
{
off_t start, end;
off_t start;
map_t *m, *p;
struct mbr *mbr;
struct gpt_ent *ent;
unsigned int i;
printf(" %*s", lbawidth, "start");
printf(" %*s", lbawidth, "end");
printf(" %*s", lbawidth, "size");
printf(" %s\n", "contents");
printf(" index contents\n");
m = map_first();
while (m != NULL) {
end = m->map_start + m->map_size - 1;
printf(" %*llu", lbawidth, (long long)m->map_start);
printf(" %*llu", lbawidth, (long long)end);
printf(" %*llu", lbawidth, (long long)m->map_size);
putchar(' '); putchar(' ');
putchar(' ');
putchar(' ');
if (m->map_index > 0)
printf("%5d", m->map_index);
else
printf(" ");
putchar(' ');
putchar(' ');
switch (m->map_type) {
case MAP_TYPE_MBR:
if (m->map_start != 0)