Module Name: src
Committed By: christos
Date: Tue Dec 1 19:25:24 UTC 2015
Modified Files:
src/sbin/gpt: add.c create.c gpt.c gpt.h label.c migrate.c remove.c
resize.c resizedisk.c set.c type.c unset.c
Log Message:
refactor more duplicated code.
To generate a diff of this commit:
cvs rdiff -u -r1.32 -r1.33 src/sbin/gpt/add.c
cvs rdiff -u -r1.15 -r1.16 src/sbin/gpt/create.c
cvs rdiff -u -r1.50 -r1.51 src/sbin/gpt/gpt.c
cvs rdiff -u -r1.24 -r1.25 src/sbin/gpt/gpt.h src/sbin/gpt/migrate.c
cvs rdiff -u -r1.21 -r1.22 src/sbin/gpt/label.c
cvs rdiff -u -r1.19 -r1.20 src/sbin/gpt/remove.c
cvs rdiff -u -r1.16 -r1.17 src/sbin/gpt/resize.c
cvs rdiff -u -r1.9 -r1.10 src/sbin/gpt/resizedisk.c src/sbin/gpt/type.c
cvs rdiff -u -r1.8 -r1.9 src/sbin/gpt/set.c src/sbin/gpt/unset.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sbin/gpt/add.c
diff -u src/sbin/gpt/add.c:1.32 src/sbin/gpt/add.c:1.33
--- src/sbin/gpt/add.c:1.32 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/add.c Tue Dec 1 14:25:24 2015
@@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: add.c,v 1.32 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: add.c,v 1.33 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@@ -79,6 +79,7 @@ add(gpt_t gpt)
struct gpt_ent *ent, e;
unsigned int i;
off_t alignsecs;
+ char buf[128];
if ((hdr = gpt_hdr(gpt)) == NULL)
return -1;
@@ -141,29 +142,20 @@ add(gpt_t gpt)
memcpy(ent, &e, sizeof(e));
gpt_write_backup(gpt);
- gpt_msg(gpt, "Partition %d added: %s %" PRIu64 " %" PRIu64 "\n", i + 1,
- type, map->map_start, map->map_size);
+ gpt_uuid_snprintf(buf, sizeof(buf), "%d", type);
+ gpt_msg(gpt, "Partition %d added: %s %" PRIu64 " %" PRIu64, i + 1,
+ buf, map->map_start, map->map_size);
return 0;
}
static int
cmd_add(gpt_t gpt, int argc, char *argv[])
{
- char *p;
int ch;
int64_t human_num;
- while ((ch = getopt(argc, argv, "a:b:i:l:s:t:")) != -1) {
+ while ((ch = getopt(argc, argv, GPT_AIS "bl:t:")) != -1) {
switch(ch) {
- case 'a':
- if (alignment > 0)
- return usage();
- if (dehumanize_number(optarg, &human_num) < 0)
- return usage();
- alignment = human_num;
- if (alignment < 1)
- return usage();
- break;
case 'b':
if (block > 0)
return usage();
@@ -173,45 +165,11 @@ cmd_add(gpt_t gpt, int argc, char *argv[
if (block < 1)
return usage();
break;
- case 'i':
- if (entry > 0)
- usage();
- entry = strtoul(optarg, &p, 10);
- if (*p != 0 || entry < 1)
- return usage();
- break;
case 'l':
if (name != NULL)
return usage();
name = (uint8_t *)strdup(optarg);
break;
- case 's':
- if (sectors > 0 || size > 0)
- return usage();
- sectors = strtoll(optarg, &p, 10);
- if (sectors < 1)
- return usage();
- if (*p == '\0')
- break;
- if (*p == 's' || *p == 'S') {
- if (*(p + 1) == '\0')
- break;
- else
- return usage();
- }
- if (*p == 'b' || *p == 'B') {
- if (*(p + 1) == '\0') {
- size = sectors;
- sectors = 0;
- break;
- } else
- return usage();
- }
- if (dehumanize_number(optarg, &human_num) < 0)
- return usage();
- size = human_num;
- sectors = 0;
- break;
case 't':
if (!gpt_uuid_is_nil(type))
return usage();
@@ -219,11 +177,14 @@ cmd_add(gpt_t gpt, int argc, char *argv[
return usage();
break;
default:
- return usage();
+ if (gpt_add_ais(gpt, &alignment, &entry, &size, ch)
+ == -1)
+ return usage();
+ break;
}
}
- if (argc == optind)
+ if (argc != optind)
return usage();
/* Create NetBSD FFS partitions by default. */
@@ -234,7 +195,7 @@ cmd_add(gpt_t gpt, int argc, char *argv[
if (optind != argc)
return usage();
- if ((sectors = gpt_check(gpt, alignment, size)) == -1)
+ if ((sectors = gpt_check_ais(gpt, alignment, entry, size)) == -1)
return -1;
return add(gpt);
Index: src/sbin/gpt/create.c
diff -u src/sbin/gpt/create.c:1.15 src/sbin/gpt/create.c:1.16
--- src/sbin/gpt/create.c:1.15 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/create.c Tue Dec 1 14:25:24 2015
@@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/create.c,v 1.11 2005/08/31 01:47:19 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: create.c,v 1.15 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: create.c,v 1.16 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@@ -74,21 +74,10 @@ struct gpt_cmd c_create = {
static int
create(gpt_t gpt)
{
- off_t blocks, last;
+ off_t last = gpt_last(gpt);
map_t map;
struct mbr *mbr;
- struct gpt_hdr *hdr;
- struct gpt_ent *ent;
- unsigned int i;
- void *p;
-
- last = gpt->mediasz / gpt->secsz - 1LL;
-
- if (map_find(gpt, MAP_TYPE_PRI_GPT_HDR) != NULL ||
- map_find(gpt, MAP_TYPE_SEC_GPT_HDR) != NULL) {
- gpt_warnx(gpt, "Device already contains a GPT");
- return -1;
- }
+
map = map_find(gpt, MAP_TYPE_MBR);
if (map != NULL) {
if (!force) {
@@ -117,110 +106,21 @@ create(gpt_t gpt)
gpt_create_pmbr_part(mbr->mbr_part, last);
map = map_add(gpt, 0LL, 1LL, MAP_TYPE_PMBR, mbr);
- gpt_write(gpt, map);
- }
-
- /* Get the amount of free space after the MBR */
- blocks = map_free(gpt, 1LL, 0LL);
- if (blocks == 0LL) {
- gpt_warnx(gpt, "No room for the GPT header");
- return -1;
- }
-
- /* Don't create more than parts entries. */
- if ((uint64_t)(blocks - 1) * gpt->secsz >
- parts * sizeof(struct gpt_ent)) {
- blocks = (parts * sizeof(struct gpt_ent)) / gpt->secsz;
- if ((parts * sizeof(struct gpt_ent)) % gpt->secsz)
- blocks++;
- blocks++; /* Don't forget the header itself */
- }
-
- /* Never cross the median of the device. */
- if ((blocks + 1LL) > ((last + 1LL) >> 1))
- blocks = ((last + 1LL) >> 1) - 1LL;
-
- /*
- * Get the amount of free space at the end of the device and
- * calculate the size for the GPT structures.
- */
- map = map_last(gpt);
- if (map->map_type != MAP_TYPE_UNUSED) {
- gpt_warnx(gpt, "No room for the backup header");
- return -1;
- }
-
- if (map->map_size < blocks)
- blocks = map->map_size;
- if (blocks == 1LL) {
- gpt_warnx(gpt, "No room for the GPT table");
- return -1;
+ if (gpt_write(gpt, map) == -1) {
+ gpt_warn(gpt, "Can't write PMBR");
+ return -1;
+ }
}
- if ((p = calloc(1, gpt->secsz)) == NULL) {
- gpt_warnx(gpt, "Can't allocate the GPT");
- return -1;
- }
- if ((gpt->gpt = map_add(gpt, 1LL, 1LL,
- MAP_TYPE_PRI_GPT_HDR, p)) == NULL) {
- free(p);
- gpt_warnx(gpt, "Can't add the GPT");
+ if (gpt_create(gpt, last, parts, primary_only) == -1)
return -1;
- }
- blocks--; /* Number of blocks in the GPT table. */
- if ((p = calloc(blocks, gpt->secsz)) == NULL) {
- gpt_warnx(gpt, "Can't allocate the GPT table");
- return -1;
- }
- if ((gpt->tbl = map_add(gpt, 2LL, blocks,
- MAP_TYPE_PRI_GPT_TBL, p)) == NULL) {
- free(p);
- gpt_warnx(gpt, "Can't add the GPT table");
+ if (gpt_write_primary(gpt) == -1)
return -1;
- }
-
- hdr = gpt->gpt->map_data;
- memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
- hdr->hdr_revision = htole32(GPT_HDR_REVISION);
- hdr->hdr_size = htole32(GPT_HDR_SIZE);
- hdr->hdr_lba_self = htole64(gpt->gpt->map_start);
- hdr->hdr_lba_alt = htole64(last);
- hdr->hdr_lba_start = htole64(gpt->tbl->map_start + blocks);
- hdr->hdr_lba_end = htole64(last - blocks - 1LL);
- gpt_uuid_generate(hdr->hdr_guid);
- hdr->hdr_lba_table = htole64(gpt->tbl->map_start);
- hdr->hdr_entries = htole32((blocks * gpt->secsz) /
- sizeof(struct gpt_ent));
- if (le32toh(hdr->hdr_entries) > parts)
- hdr->hdr_entries = htole32(parts);
- hdr->hdr_entsz = htole32(sizeof(struct gpt_ent));
-
- ent = gpt->tbl->map_data;
- for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
- gpt_uuid_generate(ent[i].ent_guid);
- }
- if (gpt_write_primary(gpt) == -1)
+ if (!primary_only && gpt_write_backup(gpt) == -1)
return -1;
- /*
- * Create backup GPT if the user didn't suppress it.
- */
- if (!primary_only) {
- // XXX: error checks
- gpt->tpg = map_add(gpt, last, 1LL, MAP_TYPE_SEC_GPT_HDR,
- calloc(1, gpt->secsz));
- gpt->lbt = map_add(gpt, last - blocks, blocks,
- MAP_TYPE_SEC_GPT_TBL, gpt->tbl->map_data);
- memcpy(gpt->tpg->map_data, gpt->gpt->map_data, gpt->secsz);
- hdr = gpt->tpg->map_data;
- hdr->hdr_lba_self = htole64(gpt->tpg->map_start);
- hdr->hdr_lba_alt = htole64(gpt->gpt->map_start);
- hdr->hdr_lba_table = htole64(gpt->lbt->map_start);
- if (gpt_write_backup(gpt) == -1)
- return -1;
- }
return 0;
}
Index: src/sbin/gpt/gpt.c
diff -u src/sbin/gpt/gpt.c:1.50 src/sbin/gpt/gpt.c:1.51
--- src/sbin/gpt/gpt.c:1.50 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/gpt.c Tue Dec 1 14:25:24 2015
@@ -35,7 +35,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/gpt.c,v 1.16 2006/07/07 02:44:23 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: gpt.c,v 1.50 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: gpt.c,v 1.51 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/param.h>
@@ -712,24 +712,7 @@ gpt_create_pmbr_part(struct mbr_part *pa
}
}
-off_t
-gpt_check(gpt_t gpt, off_t alignment, off_t size)
-{
- if (alignment % gpt->secsz != 0) {
- gpt_warnx(gpt, "Alignment (%#jx) must be a multiple of "
- "sector size (%#x)", (uintmax_t)alignment, gpt->secsz);
- return -1;
- }
- if (size % gpt->secsz != 0) {
- gpt_warnx(gpt, "Size (%#jx) must be a multiple of "
- "sector size (%#x)", (uintmax_t)size, gpt->secsz);
- return -1;
- }
- if (size > 0)
- return size / gpt->secsz;
- return 0;
-}
struct gpt_ent *
gpt_ent(map_t map, map_t tbl, unsigned int i)
{
@@ -770,3 +753,392 @@ gpt_usage(const char *prefix, const stru
}
return -1;
}
+
+off_t
+gpt_last(gpt_t gpt)
+{
+ return gpt->mediasz / gpt->secsz - 1LL;
+}
+
+int
+gpt_create(gpt_t gpt, off_t last, u_int parts, int primary_only)
+{
+ off_t blocks;
+ map_t map;
+ struct gpt_hdr *hdr;
+ struct gpt_ent *ent;
+ unsigned int i;
+ void *p;
+
+ if (map_find(gpt, MAP_TYPE_PRI_GPT_HDR) != NULL ||
+ map_find(gpt, MAP_TYPE_SEC_GPT_HDR) != NULL) {
+ gpt_warnx(gpt, "Device already contains a GPT");
+ return -1;
+ }
+
+ /* Get the amount of free space after the MBR */
+ blocks = map_free(gpt, 1LL, 0LL);
+ if (blocks == 0LL) {
+ gpt_warnx(gpt, "No room for the GPT header");
+ return -1;
+ }
+
+ /* Don't create more than parts entries. */
+ if ((uint64_t)(blocks - 1) * gpt->secsz >
+ parts * sizeof(struct gpt_ent)) {
+ blocks = (parts * sizeof(struct gpt_ent)) / gpt->secsz;
+ if ((parts * sizeof(struct gpt_ent)) % gpt->secsz)
+ blocks++;
+ blocks++; /* Don't forget the header itself */
+ }
+
+ /* Never cross the median of the device. */
+ if ((blocks + 1LL) > ((last + 1LL) >> 1))
+ blocks = ((last + 1LL) >> 1) - 1LL;
+
+ /*
+ * Get the amount of free space at the end of the device and
+ * calculate the size for the GPT structures.
+ */
+ map = map_last(gpt);
+ if (map->map_type != MAP_TYPE_UNUSED) {
+ gpt_warnx(gpt, "No room for the backup header");
+ return -1;
+ }
+
+ if (map->map_size < blocks)
+ blocks = map->map_size;
+ if (blocks == 1LL) {
+ gpt_warnx(gpt, "No room for the GPT table");
+ return -1;
+ }
+
+ blocks--; /* Number of blocks in the GPT table. */
+
+ if ((p = calloc(1, gpt->secsz)) == NULL) {
+ gpt_warnx(gpt, "Can't allocate the primary GPT");
+ return -1;
+ }
+ if ((gpt->gpt = map_add(gpt, 1LL, 1LL,
+ MAP_TYPE_PRI_GPT_HDR, p)) == NULL) {
+ free(p);
+ gpt_warnx(gpt, "Can't add the primary GPT");
+ return -1;
+ }
+
+ if ((p = calloc(blocks, gpt->secsz)) == NULL) {
+ gpt_warnx(gpt, "Can't allocate the primary GPT table");
+ return -1;
+ }
+ if ((gpt->tbl = map_add(gpt, 2LL, blocks,
+ MAP_TYPE_PRI_GPT_TBL, p)) == NULL) {
+ free(p);
+ gpt_warnx(gpt, "Can't add the primary GPT table");
+ return -1;
+ }
+
+ hdr = gpt->gpt->map_data;
+ memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
+
+ /*
+ * XXX struct gpt_hdr is not a multiple of 8 bytes in size and thus
+ * contains padding we must not include in the size.
+ */
+ hdr->hdr_revision = htole32(GPT_HDR_REVISION);
+ hdr->hdr_size = htole32(GPT_HDR_SIZE);
+ hdr->hdr_lba_self = htole64(gpt->gpt->map_start);
+ hdr->hdr_lba_alt = htole64(last);
+ hdr->hdr_lba_start = htole64(gpt->tbl->map_start + blocks);
+ hdr->hdr_lba_end = htole64(last - blocks - 1LL);
+ gpt_uuid_generate(hdr->hdr_guid);
+ hdr->hdr_lba_table = htole64(gpt->tbl->map_start);
+ hdr->hdr_entries = htole32((blocks * gpt->secsz) /
+ sizeof(struct gpt_ent));
+ if (le32toh(hdr->hdr_entries) > parts)
+ hdr->hdr_entries = htole32(parts);
+ hdr->hdr_entsz = htole32(sizeof(struct gpt_ent));
+
+ ent = gpt->tbl->map_data;
+ for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
+ gpt_uuid_generate(ent[i].ent_guid);
+ }
+
+ /*
+ * Create backup GPT if the user didn't suppress it.
+ */
+ if (primary_only)
+ return last;
+
+ if ((p = calloc(1, gpt->secsz)) == NULL) {
+ gpt_warnx(gpt, "Can't allocate the secondary GPT");
+ return -1;
+ }
+
+ if ((gpt->tpg = map_add(gpt, last, 1LL,
+ MAP_TYPE_SEC_GPT_HDR, p)) == NULL) {
+ gpt_warnx(gpt, "Can't add the secondary GPT");
+ return -1;
+ }
+
+ if ((gpt->lbt = map_add(gpt, last - blocks, blocks,
+ MAP_TYPE_SEC_GPT_TBL, gpt->tbl->map_data)) == NULL) {
+ gpt_warnx(gpt, "Can't add the secondary GPT table");
+ return -1;
+ }
+
+ memcpy(gpt->tpg->map_data, gpt->gpt->map_data, gpt->secsz);
+
+ hdr = gpt->tpg->map_data;
+ hdr->hdr_lba_self = htole64(gpt->tpg->map_start);
+ hdr->hdr_lba_alt = htole64(gpt->gpt->map_start);
+ hdr->hdr_lba_table = htole64(gpt->lbt->map_start);
+ return last;
+}
+
+int
+gpt_add_find(gpt_t gpt, struct gpt_find *find, int ch)
+{
+ int64_t human_num;
+ char *p;
+
+ switch (ch) {
+ case 'a':
+ if (find->all > 0)
+ return -1;
+ find->all = 1;
+ break;
+ case 'b':
+ if (find->block > 0)
+ return -1;
+ if (dehumanize_number(optarg, &human_num) < 0)
+ return -1;
+ find->block = human_num;
+ if (find->block < 1)
+ return -1;
+ break;
+ case 'i':
+ if (find->entry > 0)
+ return -1;
+ find->entry = strtoul(optarg, &p, 10);
+ if (*p != 0 || find->entry < 1)
+ return -1;
+ break;
+ case 'L':
+ if (find->label != NULL)
+ return -1;
+ find->label = (uint8_t *)strdup(optarg);
+ break;
+ case 's':
+ if (find->size > 0)
+ return -1;
+ find->size = strtoll(optarg, &p, 10);
+ if (*p != 0 || find->size < 1)
+ return -1;
+ break;
+ case 't':
+ if (!gpt_uuid_is_nil(find->type))
+ return -1;
+ if (gpt_uuid_parse(optarg, find->type) != 0)
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+int
+gpt_change_ent(gpt_t gpt, const struct gpt_find *find,
+ void (*cfn)(struct gpt_ent *, void *), void *v)
+{
+ map_t m;
+ struct gpt_hdr *hdr;
+ struct gpt_ent *ent;
+ unsigned int i;
+
+ if (!find->all ^
+ (find->block > 0 || find->entry > 0 || find->label != NULL
+ || find->size > 0 || !gpt_uuid_is_nil(find->type)))
+ return -1;
+
+ if ((hdr = gpt_hdr(gpt)) == NULL)
+ return -1;
+
+ /* Relabel all matching entries in the map. */
+ for (m = map_first(gpt); m != NULL; m = m->map_next) {
+ if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
+ continue;
+ if (find->entry > 0 && find->entry != m->map_index)
+ continue;
+ if (find->block > 0 && find->block != m->map_start)
+ continue;
+ if (find->size > 0 && find->size != m->map_size)
+ continue;
+
+ i = m->map_index - 1;
+
+ ent = gpt_ent_primary(gpt, i);
+ if (find->label != NULL)
+ if (strcmp((char *)find->label,
+ (char *)utf16_to_utf8(ent->ent_name)) != 0)
+ continue;
+
+ if (!gpt_uuid_is_nil(find->type) &&
+ !gpt_uuid_equal(find->type, ent->ent_type))
+ continue;
+
+ /* Change the primary entry. */
+ (*cfn)(ent, v);
+
+ if (gpt_write_primary(gpt) == -1)
+ return -1;
+
+ ent = gpt_ent_backup(gpt, i);
+ /* Change the secondary entry. */
+ (*cfn)(ent, v);
+
+ if (gpt_write_backup(gpt) == -1)
+ return -1;
+
+ gpt_msg(gpt, "Partition %d %s", m->map_index, find->msg);
+ }
+ return 0;
+}
+
+int
+gpt_add_ais(gpt_t gpt, off_t *alignment, u_int *entry, off_t *size, int ch)
+{
+ int64_t human_num;
+ off_t sectors;
+ char *p;
+
+ switch (ch) {
+ case 'a':
+ if (*alignment > 0)
+ return -1;
+ if (dehumanize_number(optarg, &human_num) < 0)
+ return -1;
+ *alignment = human_num;
+ if (*alignment < 1)
+ return -1;
+ return 0;
+ case 'i':
+ if (*entry > 0)
+ return -1;
+ *entry = strtoul(optarg, &p, 10);
+ if (*p != 0 || *entry < 1)
+ return -1;
+ return 0;
+ case 's':
+ if (*size > 0)
+ return -1;
+ sectors = strtoll(optarg, &p, 10);
+ if (sectors < 1)
+ return -1;
+ if (*p == '\0' || ((*p == 's' || *p == 'S') && p[1] == '\0')) {
+ *size = sectors * gpt->secsz;
+ return 0;
+ }
+ if ((*p == 'b' || *p == 'B') && p[1] == '\0') {
+ *size = sectors;
+ return 0;
+ }
+ if (dehumanize_number(optarg, &human_num) < 0)
+ return -1;
+ *size = human_num;
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+off_t
+gpt_check_ais(gpt_t gpt, off_t alignment, u_int entry, off_t size)
+{
+ if (entry == 0) {
+ gpt_warnx(gpt, "Entry not specified");
+ return -1;
+ }
+ if (alignment % gpt->secsz != 0) {
+ gpt_warnx(gpt, "Alignment (%#jx) must be a multiple of "
+ "sector size (%#x)", (uintmax_t)alignment, gpt->secsz);
+ return -1;
+ }
+
+ if (size % gpt->secsz != 0) {
+ gpt_warnx(gpt, "Size (%#jx) must be a multiple of "
+ "sector size (%#x)", (uintmax_t)size, gpt->secsz);
+ return -1;
+ }
+ if (size > 0)
+ return size / gpt->secsz;
+ return 0;
+}
+int
+gpt_attr_get(uint64_t *attributes)
+{
+ if (strcmp(optarg, "biosboot") == 0)
+ *attributes |= GPT_ENT_ATTR_LEGACY_BIOS_BOOTABLE;
+ else if (strcmp(optarg, "bootme") == 0)
+ *attributes |= GPT_ENT_ATTR_BOOTME;
+ else if (strcmp(optarg, "bootonce") == 0)
+ *attributes |= GPT_ENT_ATTR_BOOTONCE;
+ else if (strcmp(optarg, "bootfailed") == 0)
+ *attributes |= GPT_ENT_ATTR_BOOTFAILED;
+ else
+ return -1;
+ return 0;
+}
+int
+gpt_attr_update(gpt_t gpt, u_int entry, uint64_t set, uint64_t clr)
+{
+ struct gpt_hdr *hdr;
+ struct gpt_ent *ent;
+ unsigned int i;
+
+ if (entry == 0 || (set == 0 && clr == 0))
+ return -1;
+
+ if ((hdr = gpt_hdr(gpt)) == NULL)
+ return -1;
+
+ if (entry > le32toh(hdr->hdr_entries)) {
+ gpt_warnx(gpt, "Index %u out of range (%u max)",
+ entry, le32toh(hdr->hdr_entries));
+ return -1;
+ }
+
+ i = entry - 1;
+ ent = gpt_ent_primary(gpt, i);
+ if (gpt_uuid_is_nil(ent->ent_type)) {
+ gpt_warnx(gpt, "Entry at index %u is unused", entry);
+ return -1;
+ }
+
+ ent->ent_attr &= ~clr;
+ ent->ent_attr |= set;
+
+ if (gpt_write_primary(gpt) == -1)
+ return -1;
+
+ ent = gpt_ent_backup(gpt, i);
+ ent->ent_attr &= ~clr;
+ ent->ent_attr |= set;
+
+ if (gpt_write_backup(gpt) == -1)
+ return -1;
+ gpt_msg(gpt, "Partition %d attributes updated", entry);
+ return 0;
+}
+
+int
+gpt_entry_get(u_int *entry)
+{
+ char *p;
+ if (*entry > 0)
+ return -1;
+ *entry = strtoul(optarg, &p, 10);
+ if (*p != 0 || *entry < 1)
+ return -1;
+ return 0;
+}
Index: src/sbin/gpt/gpt.h
diff -u src/sbin/gpt/gpt.h:1.24 src/sbin/gpt/gpt.h:1.25
--- src/sbin/gpt/gpt.h:1.24 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/gpt.h Tue Dec 1 14:25:24 2015
@@ -75,7 +75,14 @@ uint32_t crc32(const void *, size_t);
void gpt_close(gpt_t);
int gpt_gpt(gpt_t, off_t, int);
gpt_t gpt_open(const char *, int, int, off_t, u_int);
+#define GPT_READONLY 1
+#define GPT_MODIFIED 2
+#define GPT_QUIET 4
+#define GPT_NOSYNC 8
+
void* gpt_read(gpt_t, off_t, size_t);
+off_t gpt_last(gpt_t);
+int gpt_create(gpt_t, off_t, u_int, int);
int gpt_write(gpt_t, map_t);
int gpt_write_crc(gpt_t, map_t, map_t);
int gpt_write_primary(gpt_t);
@@ -85,7 +92,6 @@ void gpt_msg(gpt_t, const char *, ...) _
void gpt_warn(gpt_t, const char *, ...) __printflike(2, 3);
void gpt_warnx(gpt_t, const char *, ...) __printflike(2, 3);
void gpt_create_pmbr_part(struct mbr_part *, off_t);
-off_t gpt_check(gpt_t, off_t, off_t);
struct gpt_ent *gpt_ent(map_t, map_t, unsigned int);
struct gpt_ent *gpt_ent_primary(gpt_t, unsigned int);
struct gpt_ent *gpt_ent_backup(gpt_t, unsigned int);
@@ -94,9 +100,26 @@ int gpt_usage(const char *, const struct
uint8_t *utf16_to_utf8(uint16_t *);
void utf8_to_utf16(const uint8_t *, uint16_t *, size_t);
-#define GPT_READONLY 1
-#define GPT_MODIFIED 2
-#define GPT_QUIET 4
-#define GPT_NOSYNC 8
+#define GPT_FIND "ab:i:L:s:t:"
+
+struct gpt_find {
+ int all;
+ gpt_uuid_t type;
+ off_t block, size;
+ unsigned int entry;
+ uint8_t *name, *label;
+ const char *msg;
+};
+int gpt_change_ent(gpt_t, const struct gpt_find *,
+ void (*)(struct gpt_ent *, void *), void *);
+int gpt_add_find(gpt_t, struct gpt_find *, int);
+
+#define GPT_AIS "a:i:s:"
+int gpt_add_ais(gpt_t, off_t *, u_int *, off_t *, int);
+off_t gpt_check_ais(gpt_t, off_t, u_int, off_t);
+
+int gpt_attr_get(uint64_t *);
+int gpt_attr_update(gpt_t, u_int, uint64_t, uint64_t);
+int gpt_entry_get(u_int *);
#endif /* _GPT_H_ */
Index: src/sbin/gpt/migrate.c
diff -u src/sbin/gpt/migrate.c:1.24 src/sbin/gpt/migrate.c:1.25
--- src/sbin/gpt/migrate.c:1.24 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/migrate.c Tue Dec 1 14:25:24 2015
@@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/migrate.c,v 1.16 2005/09/01 02:42:52 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: migrate.c,v 1.24 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: migrate.c,v 1.25 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@@ -262,16 +262,13 @@ migrate_netbsd_disklabel(gpt_t gpt, off_
static int
migrate(gpt_t gpt)
{
- off_t blocks, last;
+ off_t last = gpt_last(gpt);
map_t map;
- struct gpt_hdr *hdr;
struct gpt_ent *ent;
struct mbr *mbr;
uint32_t start, size;
unsigned int i;
- last = gpt->mediasz / gpt->secsz - 1LL;
-
map = map_find(gpt, MAP_TYPE_MBR);
if (map == NULL || map->map_start != 0) {
gpt_warnx(gpt, "No partitions to convert");
@@ -280,86 +277,10 @@ migrate(gpt_t gpt)
mbr = map->map_data;
- if (map_find(gpt, MAP_TYPE_PRI_GPT_HDR) != NULL ||
- map_find(gpt, MAP_TYPE_SEC_GPT_HDR) != NULL) {
- gpt_warnx(gpt, "Device already contains a GPT");
- return -1;
- }
-
- /* Get the amount of free space after the MBR */
- blocks = map_free(gpt, 1LL, 0LL);
- if (blocks == 0LL) {
- gpt_warnx(gpt, "No room for the GPT header");
- return -1;
- }
-
- /* Don't create more than parts entries. */
- if ((uint64_t)(blocks - 1) * gpt->secsz >
- parts * sizeof(struct gpt_ent)) {
- blocks = (parts * sizeof(struct gpt_ent)) / gpt->secsz;
- if ((parts * sizeof(struct gpt_ent)) % gpt->secsz)
- blocks++;
- blocks++; /* Don't forget the header itself */
- }
-
- /* Never cross the median of the device. */
- if ((blocks + 1LL) > ((last + 1LL) >> 1))
- blocks = ((last + 1LL) >> 1) - 1LL;
-
- /*
- * Get the amount of free space at the end of the device and
- * calculate the size for the GPT structures.
- */
- map = map_last(gpt);
- if (map->map_type != MAP_TYPE_UNUSED) {
- gpt_warnx(gpt, "No room for the backup header");
- return -1;
- }
-
- if (map->map_size < blocks)
- blocks = map->map_size;
- if (blocks == 1LL) {
- gpt_warnx(gpt, "No room for the GPT table");
+ if (gpt_create(gpt, last, parts, 0) == -1)
return -1;
- }
-
- blocks--; /* Number of blocks in the GPT table. */
- gpt->gpt = map_add(gpt, 1LL, 1LL, MAP_TYPE_PRI_GPT_HDR,
- calloc(1, gpt->secsz));
- gpt->tbl = map_add(gpt, 2LL, blocks, MAP_TYPE_PRI_GPT_TBL,
- calloc(blocks, gpt->secsz));
- if (gpt->gpt == NULL || gpt->tbl == NULL)
- return -1;
-
- gpt->lbt = map_add(gpt, last - blocks, blocks, MAP_TYPE_SEC_GPT_TBL,
- gpt->tbl->map_data);
- gpt->tpg = map_add(gpt, last, 1LL, MAP_TYPE_SEC_GPT_HDR,
- calloc(1, gpt->secsz));
-
- hdr = gpt->gpt->map_data;
- memcpy(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig));
- hdr->hdr_revision = htole32(GPT_HDR_REVISION);
-
- /*
- * XXX struct gpt_hdr is not a multiple of 8 bytes in size and thus
- * contains padding we must not include in the size.
- */
- hdr->hdr_size = htole32(GPT_HDR_SIZE);
- hdr->hdr_lba_self = htole64(gpt->gpt->map_start);
- hdr->hdr_lba_alt = htole64(gpt->tpg->map_start);
- hdr->hdr_lba_start = htole64(gpt->tbl->map_start + blocks);
- hdr->hdr_lba_end = htole64(gpt->lbt->map_start - 1LL);
- gpt_uuid_generate(hdr->hdr_guid);
- hdr->hdr_lba_table = htole64(gpt->tbl->map_start);
- hdr->hdr_entries = htole32((blocks * gpt->secsz) / sizeof(struct gpt_ent));
- if (le32toh(hdr->hdr_entries) > parts)
- hdr->hdr_entries = htole32(parts);
- hdr->hdr_entsz = htole32(sizeof(struct gpt_ent));
ent = gpt->tbl->map_data;
- for (i = 0; i < le32toh(hdr->hdr_entries); i++) {
- gpt_uuid_generate(ent[i].ent_guid);
- }
/* Mirror partitions. */
for (i = 0; i < 4; i++) {
@@ -408,26 +329,18 @@ migrate(gpt_t gpt)
if (gpt_write_primary(gpt) == -1)
return -1;
- /*
- * Create backup GPT.
- */
- memcpy(gpt->tpg->map_data, gpt->gpt->map_data, gpt->secsz);
- hdr = gpt->tpg->map_data;
- hdr->hdr_lba_self = htole64(gpt->tpg->map_start);
- hdr->hdr_lba_alt = htole64(gpt->gpt->map_start);
- hdr->hdr_lba_table = htole64(gpt->lbt->map_start);
-
if (gpt_write_backup(gpt) == -1)
return -1;
- map = map_find(gpt, MAP_TYPE_MBR);
- mbr = map->map_data;
/*
* Turn the MBR into a Protective MBR.
*/
memset(mbr->mbr_part, 0, sizeof(mbr->mbr_part));
gpt_create_pmbr_part(mbr->mbr_part, last);
- gpt_write(gpt, map);
+ if (gpt_write(gpt, map) == -1) {
+ gpt_warn(gpt, "Cant write PMBR");
+ return -1;
+ }
return 0;
}
Index: src/sbin/gpt/label.c
diff -u src/sbin/gpt/label.c:1.21 src/sbin/gpt/label.c:1.22
--- src/sbin/gpt/label.c:1.21 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/label.c Tue Dec 1 14:25:24 2015
@@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/label.c,v 1.3 2006/10/04 18:20:25 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: label.c,v 1.21 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: label.c,v 1.22 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@@ -50,12 +50,6 @@ __RCSID("$NetBSD: label.c,v 1.21 2015/12
#include "gpt_private.h"
#include "gpt_uuid.h"
-static int all;
-static gpt_uuid_t type;
-static off_t block, size;
-static unsigned int entry;
-static uint8_t *name, *xlabel;
-
static int cmd_label(gpt_t, int, char *[]);
static const char *labelhelp[] = {
@@ -72,65 +66,21 @@ struct gpt_cmd c_label = {
#define usage() gpt_usage(NULL, &c_label)
-static int
-label(gpt_t gpt)
+static void
+change(struct gpt_ent *ent, void *v)
{
- map_t m;
- struct gpt_hdr *hdr;
- struct gpt_ent *ent;
- unsigned int i;
-
- if ((hdr = gpt_hdr(gpt)) == NULL)
- return -1;
-
- /* Relabel all matching entries in the map. */
- for (m = map_first(gpt); m != NULL; m = m->map_next) {
- if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
- continue;
- if (entry > 0 && entry != m->map_index)
- continue;
- if (block > 0 && block != m->map_start)
- continue;
- if (size > 0 && size != m->map_size)
- continue;
-
- i = m->map_index - 1;
-
- ent = gpt_ent_primary(gpt, i);
- if (xlabel != NULL)
- if (strcmp((char *)xlabel,
- (char *)utf16_to_utf8(ent->ent_name)) != 0)
- continue;
-
- if (!gpt_uuid_is_nil(type) &&
- !gpt_uuid_equal(type, ent->ent_type))
- continue;
-
- /* Label the primary entry. */
- utf8_to_utf16(name, ent->ent_name, 36);
-
- if (gpt_write_primary(gpt) == -1)
- return -1;
-
- ent = gpt_ent_backup(gpt, i);
- /* Label the secondary entry. */
- utf8_to_utf16(name, ent->ent_name, 36);
-
- if (gpt_write_backup(gpt) == -1)
- return -1;
-
- gpt_msg(gpt, "Partition %d labeled %s", m->map_index, name);
- }
- return 0;
+ uint8_t *name = v;
+ utf8_to_utf16(name, ent->ent_name, 36);
}
-static void
+static char *
name_from_file(const char *fn)
{
FILE *f;
char *p;
size_t maxlen = 1024;
size_t len;
+ char *name;
if (strcmp(fn, "-") != 0) {
f = fopen(fn, "r");
@@ -149,79 +99,41 @@ name_from_file(const char *fn)
p = strchr((const char *)name, '\n');
if (p != NULL)
*p = '\0';
+ return name;
}
static int
cmd_label(gpt_t gpt, int argc, char *argv[])
{
- char *p;
int ch;
- int64_t human_num;
+ struct gpt_find find;
+ char *name = NULL;
+
+ memset(&find, 0, sizeof(find));
+ find.msg = "label changed";
/* Get the label options */
- while ((ch = getopt(argc, argv, "ab:f:i:L:l:s:t:")) != -1) {
+ while ((ch = getopt(argc, argv, GPT_FIND "f:l:")) != -1) {
switch(ch) {
- case 'a':
- if (all > 0)
- return usage();
- all = 1;
- break;
- case 'b':
- if (block > 0)
- return usage();
- if (dehumanize_number(optarg, &human_num) < 0)
- return usage();
- block = human_num;
- if (block < 1)
- return usage();
- break;
case 'f':
if (name != NULL)
return usage();
- name_from_file(optarg);
- break;
- case 'i':
- if (entry > 0)
- return usage();
- entry = strtoul(optarg, &p, 10);
- if (*p != 0 || entry < 1)
- return usage();
- break;
- case 'L':
- if (xlabel != NULL)
- return usage();
- xlabel = (uint8_t *)strdup(optarg);
+ name = name_from_file(optarg);
break;
case 'l':
if (name != NULL)
return usage();
- name = (uint8_t *)strdup(optarg);
- break;
- case 's':
- if (size > 0)
- return usage();
- size = strtoll(optarg, &p, 10);
- if (*p != 0 || size < 1)
- return usage();
+ name = strdup(optarg);
break;
- case 't':
- if (!gpt_uuid_is_nil(type))
- return usage();
- if (gpt_uuid_parse(optarg, type) != 0)
+ default:
+ if (gpt_add_find(gpt, &find, ch) == -1)
return usage();
break;
- default:
- return usage();
}
}
- if (!all ^
- (block > 0 || entry > 0 || xlabel != NULL || size > 0 ||
- !gpt_uuid_is_nil(type)))
- return usage();
-
if (name == NULL || argc != optind)
return usage();
- return label(gpt);
+ return gpt_change_ent(gpt, &find, change, name);
}
Index: src/sbin/gpt/remove.c
diff -u src/sbin/gpt/remove.c:1.19 src/sbin/gpt/remove.c:1.20
--- src/sbin/gpt/remove.c:1.19 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/remove.c Tue Dec 1 14:25:24 2015
@@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/remove.c,v 1.10 2006/10/04 18:20:25 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: remove.c,v 1.19 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: remove.c,v 1.20 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@@ -49,12 +49,6 @@ __RCSID("$NetBSD: remove.c,v 1.19 2015/1
#include "gpt.h"
#include "gpt_private.h"
-static int all;
-static gpt_uuid_t type;
-static off_t block, size;
-static unsigned int entry;
-static uint8_t *label;
-
static int cmd_remove(gpt_t, int, char *[]);
static const char *removehelp[] = {
@@ -71,119 +65,29 @@ struct gpt_cmd c_remove = {
#define usage() gpt_usage(NULL, &c_remove)
-static int
-rem(gpt_t gpt)
+static void
+change(struct gpt_ent *ent, void *v)
{
- map_t m;
- struct gpt_ent *ent;
- unsigned int i;
-
- if (gpt_hdr(gpt) == NULL)
- return -1;
-
- /* Remove all matching entries in the map. */
- for (m = map_first(gpt); m != NULL; m = m->map_next) {
- if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
- continue;
- if (entry > 0 && entry != m->map_index)
- continue;
- if (block > 0 && block != m->map_start)
- continue;
- if (size > 0 && size != m->map_size)
- continue;
-
- i = m->map_index - 1;
-
- ent = gpt_ent_primary(gpt, i);
-
- if (label != NULL)
- if (strcmp((char *)label,
- (char *)utf16_to_utf8(ent->ent_name)) != 0)
- continue;
-
- if (!gpt_uuid_is_nil(type) &&
- !gpt_uuid_equal(type, ent->ent_type))
- continue;
-
- /* Remove the primary entry by clearing the partition type. */
- gpt_uuid_copy(ent->ent_type, gpt_uuid_nil);
-
- if (gpt_write_primary(gpt) == -1)
- return -1;
-
- ent = gpt_ent_backup(gpt, i);
-
- /* Remove the secondary entry. */
- gpt_uuid_copy(ent->ent_type, gpt_uuid_nil);
-
- if (gpt_write_backup(gpt) == -1)
- return -1;
- gpt_msg(gpt, "partition %d removed", m->map_index);
- }
- return 0;
+ /* Remove the primary entry by clearing the partition type. */
+ gpt_uuid_copy(ent->ent_type, gpt_uuid_nil);
}
static int
cmd_remove(gpt_t gpt, int argc, char *argv[])
{
- char *p;
int ch;
- int64_t human_num;
+ struct gpt_find find;
+
+ memset(&find, 0, sizeof(find));
+ find.msg = "removed";
/* Get the remove options */
- while ((ch = getopt(argc, argv, "ab:i:L:s:t:")) != -1) {
- switch(ch) {
- case 'a':
- if (all > 0)
- return usage();
- all = 1;
- break;
- case 'b':
- if (block > 0)
- return usage();
- if (dehumanize_number(optarg, &human_num) < 0)
- return usage();
- block = human_num;
- if (block < 1)
- return usage();
- break;
- case 'i':
- if (entry > 0)
- return usage();
- entry = strtoul(optarg, &p, 10);
- if (*p != 0 || entry < 1)
- return usage();
- break;
- case 'L':
- if (label != NULL)
- return usage();
- label = (uint8_t *)strdup(optarg);
- break;
- case 's':
- if (size > 0)
- usage();
- size = strtoll(optarg, &p, 10);
- if (*p != 0 || size < 1)
- return usage();
- break;
- case 't':
- if (!gpt_uuid_is_nil(type))
- return usage();
- if (gpt_uuid_parse(optarg, type) != 0)
- return usage();
- break;
- default:
+ while ((ch = getopt(argc, argv, GPT_FIND)) != -1)
+ if (gpt_add_find(gpt, &find, ch) == -1)
return usage();
- }
- }
-
- if (!all ^
- (block > 0 || entry > 0 || label != NULL || size > 0 ||
- !gpt_uuid_is_nil(type)))
- return usage();
if (argc != optind)
return usage();
- return rem(gpt);
+ return gpt_change_ent(gpt, &find, change, NULL);
}
Index: src/sbin/gpt/resize.c
diff -u src/sbin/gpt/resize.c:1.16 src/sbin/gpt/resize.c:1.17
--- src/sbin/gpt/resize.c:1.16 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/resize.c Tue Dec 1 14:25:24 2015
@@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: resize.c,v 1.16 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: resize.c,v 1.17 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@@ -139,67 +139,17 @@ resize(gpt_t gpt)
static int
cmd_resize(gpt_t gpt, int argc, char *argv[])
{
- char *p;
int ch;
- int64_t human_num;
- while ((ch = getopt(argc, argv, "a:i:s:")) != -1) {
- switch(ch) {
- case 'a':
- if (alignment > 0)
- return usage();
- if (dehumanize_number(optarg, &human_num) < 0)
- return usage();
- alignment = human_num;
- if (alignment < 1)
- return usage();
- break;
- case 'i':
- if (entry > 0)
- return usage();
- entry = strtoul(optarg, &p, 10);
- if (*p != 0 || entry < 1)
- return usage();
- break;
- case 's':
- if (sectors > 0 || size > 0)
- return usage();
- sectors = strtoll(optarg, &p, 10);
- if (sectors < 1)
- return usage();
- if (*p == '\0')
- break;
- if (*p == 's' || *p == 'S') {
- if (*(p + 1) == '\0')
- break;
- else
- return usage();
- }
- if (*p == 'b' || *p == 'B') {
- if (*(p + 1) == '\0') {
- size = sectors;
- sectors = 0;
- break;
- } else
- return usage();
- }
- if (dehumanize_number(optarg, &human_num) < 0)
- return usage();
- size = human_num;
- sectors = 0;
- break;
- default:
+ while ((ch = getopt(argc, argv, GPT_AIS)) != -1) {
+ if (gpt_add_ais(gpt, &alignment, &entry, &size, ch) == -1)
return usage();
- }
}
if (argc != optind)
return usage();
- if (entry == 0)
- return usage();
-
- if ((sectors = gpt_check(gpt, alignment, size)) == -1)
+ if ((sectors = gpt_check_ais(gpt, alignment, entry, size)) == -1)
return -1;
return resize(gpt);
Index: src/sbin/gpt/resizedisk.c
diff -u src/sbin/gpt/resizedisk.c:1.9 src/sbin/gpt/resizedisk.c:1.10
--- src/sbin/gpt/resizedisk.c:1.9 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/resizedisk.c Tue Dec 1 14:25:24 2015
@@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: resizedisk.c,v 1.9 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: resizedisk.c,v 1.10 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/bootblock.h>
@@ -223,38 +223,13 @@ resizedisk(gpt_t gpt)
static int
cmd_resizedisk(gpt_t gpt, int argc, char *argv[])
{
- char *p;
int ch;
- int64_t human_num;
while ((ch = getopt(argc, argv, "s:")) != -1) {
switch(ch) {
case 's':
- if (sector > 0 || size > 0)
- return usage();
- sector = strtoll(optarg, &p, 10);
- if (sector < 1)
- return usage();
- if (*p == '\0')
- break;
- if (*p == 's' || *p == 'S') {
- if (*(p + 1) == '\0')
- break;
- else
- return usage();
- }
- if (*p == 'b' || *p == 'B') {
- if (*(p + 1) == '\0') {
- size = sector;
- sector = 0;
- break;
- } else
- return usage();
- }
- if (dehumanize_number(optarg, &human_num) < 0)
- return usage();
- size = human_num;
- sector = 0;
+ if (gpt_add_ais(gpt, NULL, NULL, &size, ch) == -1)
+ return -1;
break;
default:
return usage();
@@ -264,7 +239,7 @@ cmd_resizedisk(gpt_t gpt, int argc, char
if (argc != optind)
return usage();
- if ((sector = gpt_check(gpt, 0, size)) == -1)
+ if ((sector = gpt_check_ais(gpt, 0, ~0, size)) == -1)
return -1;
return resizedisk(gpt);
Index: src/sbin/gpt/type.c
diff -u src/sbin/gpt/type.c:1.9 src/sbin/gpt/type.c:1.10
--- src/sbin/gpt/type.c:1.9 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/type.c Tue Dec 1 14:25:24 2015
@@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/remove.c,v 1.10 2006/10/04 18:20:25 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: type.c,v 1.9 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: type.c,v 1.10 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@@ -49,12 +49,6 @@ __RCSID("$NetBSD: type.c,v 1.9 2015/12/0
#include "gpt.h"
#include "gpt_private.h"
-static int all;
-static gpt_uuid_t type, newtype;
-static off_t block, size;
-static unsigned int entry;
-static uint8_t *label;
-
static int cmd_type(gpt_t, int, char *[]);
static const char *typehelp[] = {
@@ -71,108 +65,26 @@ struct gpt_cmd c_type = {
#define usage() gpt_usage(NULL, &c_type)
-static int
-chtype(gpt_t gpt)
+static void
+change(struct gpt_ent *ent, void *v)
{
- map_t m;
- struct gpt_ent *ent;
- unsigned int i;
-
- if (gpt_hdr(gpt) == NULL)
- return -1;
-
- /* Change type of all matching entries in the map. */
- for (m = map_first(gpt); m != NULL; m = m->map_next) {
- if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1)
- continue;
- if (entry > 0 && entry != m->map_index)
- continue;
- if (block > 0 && block != m->map_start)
- continue;
- if (size > 0 && size != m->map_size)
- continue;
-
- i = m->map_index - 1;
-
- ent = gpt_ent_primary(gpt, i);
-
- if (label != NULL)
- if (strcmp((char *)label,
- (char *)utf16_to_utf8(ent->ent_name)) != 0)
- continue;
-
- if (!gpt_uuid_is_nil(type) &&
- !gpt_uuid_equal(type, ent->ent_type))
- continue;
-
- /* Change the primary entry. */
- gpt_uuid_copy(ent->ent_type, newtype);
-
- if (gpt_write_primary(gpt) == -1)
- return -1;
-
- ent = gpt_ent_backup(gpt, i);
-
- /* Change the secondary entry. */
- gpt_uuid_copy(ent->ent_type, newtype);
-
- if (gpt_write_backup(gpt) == -1)
- return -1;
-
- gpt_msg(gpt, "Partition %d type changed", m->map_index);
- }
- return 0;
+ gpt_uuid_t *newtype = v;
+ gpt_uuid_copy(ent->ent_type, *newtype);
}
static int
cmd_type(gpt_t gpt, int argc, char *argv[])
{
- char *p;
int ch;
- int64_t human_num;
+ gpt_uuid_t newtype;
+ struct gpt_find find;
+
+ memset(&find, 0, sizeof(find));
+ find.msg = "type changed";
/* Get the type options */
- while ((ch = getopt(argc, argv, "ab:i:L:s:t:T:")) != -1) {
+ while ((ch = getopt(argc, argv, GPT_FIND "T:")) != -1) {
switch(ch) {
- case 'a':
- if (all > 0)
- return usage();
- all = 1;
- break;
- case 'b':
- if (block > 0)
- return usage();
- if (dehumanize_number(optarg, &human_num) < 0)
- return usage();
- block = human_num;
- if (block < 1)
- return usage();
- break;
- case 'i':
- if (entry > 0)
- return usage();
- entry = strtoul(optarg, &p, 10);
- if (*p != 0 || entry < 1)
- return usage();
- break;
- case 'L':
- if (label != NULL)
- return usage();
- label = (uint8_t *)strdup(optarg);
- break;
- case 's':
- if (size > 0)
- return usage();
- size = strtoll(optarg, &p, 10);
- if (*p != 0 || size < 1)
- return usage();
- break;
- case 't':
- if (!gpt_uuid_is_nil(type))
- return usage();
- if (gpt_uuid_parse(optarg, type) != 0)
- return usage();
- break;
case 'T':
if (!gpt_uuid_is_nil(newtype))
return usage();
@@ -180,19 +92,14 @@ cmd_type(gpt_t gpt, int argc, char *argv
return usage();
break;
default:
- return usage();
+ if (gpt_add_find(gpt, &find, ch) == -1)
+ return usage();
+ break;
}
}
- if (!all ^
- (block > 0 || entry > 0 || label != NULL || size > 0 ||
- !gpt_uuid_is_nil(type)))
- return usage();
- if (gpt_uuid_is_nil(newtype))
- return usage();
-
- if (argc != optind)
+ if (gpt_uuid_is_nil(newtype) || argc != optind)
return usage();
- return chtype(gpt);
+ return gpt_change_ent(gpt, &find, change, &newtype);
}
Index: src/sbin/gpt/set.c
diff -u src/sbin/gpt/set.c:1.8 src/sbin/gpt/set.c:1.9
--- src/sbin/gpt/set.c:1.8 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/set.c Tue Dec 1 14:25:24 2015
@@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: set.c,v 1.8 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: set.c,v 1.9 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@@ -49,9 +49,6 @@ __RCSID("$NetBSD: set.c,v 1.8 2015/12/01
#include "gpt.h"
#include "gpt_private.h"
-static unsigned int entry;
-static uint64_t attributes;
-
static int cmd_set(gpt_t, int, char *[]);
static const char *sethelp[] = {
@@ -68,70 +65,20 @@ struct gpt_cmd c_set = {
#define usage() gpt_usage(NULL, &c_set)
static int
-set(gpt_t gpt)
-{
- struct gpt_hdr *hdr;
- struct gpt_ent *ent;
- unsigned int i;
-
-
- if ((hdr = gpt_hdr(gpt)) == NULL)
- return -1;
-
-
- if (entry > le32toh(hdr->hdr_entries)) {
- gpt_warnx(gpt, "Index %u out of range (%u max)",
- entry, le32toh(hdr->hdr_entries));
- return -1;
- }
-
- i = entry - 1;
- ent = gpt_ent_primary(gpt, i);
- if (gpt_uuid_is_nil(ent->ent_type)) {
- gpt_warnx(gpt, "Entry at index %u is unused", entry);
- return -1;
- }
-
- ent->ent_attr |= attributes;
-
- if (gpt_write_primary(gpt) == -1)
- return -1;
-
- ent = gpt_ent_backup(gpt, i);
- ent->ent_attr |= attributes;
-
- if (gpt_write_backup(gpt) == -1)
- return -1;
-
- gpt_msg(gpt, "Partition %d attributes updated", entry);
- return 0;
-}
-
-static int
cmd_set(gpt_t gpt, int argc, char *argv[])
{
- char *p;
int ch;
+ unsigned int entry = 0;
+ uint64_t attributes = 0;
while ((ch = getopt(argc, argv, "a:i:")) != -1) {
switch(ch) {
case 'a':
- if (strcmp(optarg, "biosboot") == 0)
- attributes |= GPT_ENT_ATTR_LEGACY_BIOS_BOOTABLE;
- else if (strcmp(optarg, "bootme") == 0)
- attributes |= GPT_ENT_ATTR_BOOTME;
- else if (strcmp(optarg, "bootonce") == 0)
- attributes |= GPT_ENT_ATTR_BOOTONCE;
- else if (strcmp(optarg, "bootfailed") == 0)
- attributes |= GPT_ENT_ATTR_BOOTFAILED;
- else
+ if (gpt_attr_get(&attributes) == -1)
return usage();
break;
case 'i':
- if (entry > 0)
- usage();
- entry = strtoul(optarg, &p, 10);
- if (*p != 0 || entry < 1)
+ if (gpt_entry_get(&entry) == -1)
return usage();
break;
default:
@@ -142,8 +89,5 @@ cmd_set(gpt_t gpt, int argc, char *argv[
if (argc != optind)
return usage();
- if (entry == 0 || attributes == 0)
- return usage();
-
- return set(gpt);
+ return gpt_attr_update(gpt, entry, attributes, 0);
}
Index: src/sbin/gpt/unset.c
diff -u src/sbin/gpt/unset.c:1.8 src/sbin/gpt/unset.c:1.9
--- src/sbin/gpt/unset.c:1.8 Tue Dec 1 11:32:19 2015
+++ src/sbin/gpt/unset.c Tue Dec 1 14:25:24 2015
@@ -33,7 +33,7 @@
__FBSDID("$FreeBSD: src/sbin/gpt/add.c,v 1.14 2006/06/22 22:05:28 marcel Exp $");
#endif
#ifdef __RCSID
-__RCSID("$NetBSD: unset.c,v 1.8 2015/12/01 16:32:19 christos Exp $");
+__RCSID("$NetBSD: unset.c,v 1.9 2015/12/01 19:25:24 christos Exp $");
#endif
#include <sys/types.h>
@@ -49,9 +49,6 @@ __RCSID("$NetBSD: unset.c,v 1.8 2015/12/
#include "gpt.h"
#include "gpt_private.h"
-static unsigned int entry;
-static uint64_t attributes;
-
static int cmd_unset(gpt_t, int, char *[]);
static const char *unsethelp[] = {
@@ -68,68 +65,20 @@ struct gpt_cmd c_unset = {
#define usage() gpt_usage(NULL, &c_unset)
static int
-unset(gpt_t gpt)
-{
- struct gpt_hdr *hdr;
- struct gpt_ent *ent;
- unsigned int i;
-
-
- if ((hdr = gpt_hdr(gpt)) == NULL)
- return -1;
-
- if (entry > le32toh(hdr->hdr_entries)) {
- gpt_warnx(gpt, "Index %u out of range (%u max)",
- entry, le32toh(hdr->hdr_entries));
- return -1;
- }
-
- i = entry - 1;
- ent = gpt_ent_primary(gpt, i);
- if (gpt_uuid_is_nil(ent->ent_type)) {
- gpt_warnx(gpt, "Entry at index %u is unused", entry);
- return -1;
- }
-
- ent->ent_attr &= ~attributes;
-
- if (gpt_write_primary(gpt) == -1)
- return -1;
-
- ent = gpt_ent_backup(gpt, i);
- ent->ent_attr &= ~attributes;
-
- if (gpt_write_backup(gpt) == -1)
- return -1;
- gpt_msg(gpt, "Partition %d attributes updated", entry);
- return 0;
-}
-
-static int
cmd_unset(gpt_t gpt, int argc, char *argv[])
{
- char *p;
int ch;
+ unsigned int entry = 0;
+ uint64_t attributes = 0;
while ((ch = getopt(argc, argv, "a:i:")) != -1) {
switch(ch) {
case 'a':
- if (strcmp(optarg, "biosboot") == 0)
- attributes |= GPT_ENT_ATTR_LEGACY_BIOS_BOOTABLE;
- else if (strcmp(optarg, "bootme") == 0)
- attributes |= GPT_ENT_ATTR_BOOTME;
- else if (strcmp(optarg, "bootonce") == 0)
- attributes |= GPT_ENT_ATTR_BOOTONCE;
- else if (strcmp(optarg, "bootfailed") == 0)
- attributes |= GPT_ENT_ATTR_BOOTFAILED;
- else
+ if (gpt_attr_get(&attributes) == -1)
return usage();
break;
case 'i':
- if (entry > 0)
- return usage();
- entry = strtoul(optarg, &p, 10);
- if (*p != 0 || entry < 1)
+ if (gpt_entry_get(&entry) == -1)
return usage();
break;
default:
@@ -140,8 +89,5 @@ cmd_unset(gpt_t gpt, int argc, char *arg
if (argc != optind)
return usage();
- if (entry == 0 || attributes == 0)
- return usage();
-
- return unset(gpt);
+ return gpt_attr_update(gpt, entry, 0, attributes);
}