refactor more duplicated code.
This commit is contained in:
parent
4f3e6067a8
commit
bbb4a8ab26
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
if (gpt_write(gpt, map) == -1) {
|
||||
gpt_warn(gpt, "Can't write PMBR");
|
||||
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");
|
||||
if (gpt_create(gpt, last, parts, primary_only) == -1)
|
||||
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 ((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");
|
||||
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");
|
||||
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)
|
||||
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;
|
||||
}
|
||||
if (!primary_only && gpt_write_backup(gpt) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
408
sbin/gpt/gpt.c
408
sbin/gpt/gpt.c
|
@ -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 *part, off_t last)
|
|||
}
|
||||
}
|
||||
|
||||
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 struct gpt_cmd *cmd)
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 *, ...) __printflike(2, 3);
|
|||
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 gpt_cmd *);
|
|||
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_ */
|
||||
|
|
128
sbin/gpt/label.c
128
sbin/gpt/label.c
|
@ -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/01 16:32:19 christos Exp $");
|
|||
#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();
|
||||
break;
|
||||
case 't':
|
||||
if (!gpt_uuid_is_nil(type))
|
||||
return usage();
|
||||
if (gpt_uuid_parse(optarg, type) != 0)
|
||||
return usage();
|
||||
name = strdup(optarg);
|
||||
break;
|
||||
default:
|
||||
return usage();
|
||||
if (gpt_add_find(gpt, &find, ch) == -1)
|
||||
return usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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_t start, struct gpt_ent *ent)
|
|||
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");
|
||||
if (gpt_create(gpt, last, parts, 0) == -1)
|
||||
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. */
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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/12/01 16:32:19 christos Exp $");
|
|||
#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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *argv[])
|
|||
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);
|
||||
|
|
|
@ -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 16:32:19 christos Exp $");
|
|||
#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[] = {
|
||||
|
@ -67,71 +64,21 @@ 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);
|
||||
}
|
||||
|
|
125
sbin/gpt/type.c
125
sbin/gpt/type.c
|
@ -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/01 16:32:19 christos Exp $");
|
|||
#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))
|
||||
if (gpt_uuid_is_nil(newtype) || argc != optind)
|
||||
return usage();
|
||||
|
||||
if (argc != optind)
|
||||
return usage();
|
||||
|
||||
return chtype(gpt);
|
||||
return gpt_change_ent(gpt, &find, change, &newtype);
|
||||
}
|
||||
|
|
|
@ -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/01 16:32:19 christos Exp $");
|
|||
#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[] = {
|
||||
|
@ -67,69 +64,21 @@ 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 *argv[])
|
|||
if (argc != optind)
|
||||
return usage();
|
||||
|
||||
if (entry == 0 || attributes == 0)
|
||||
return usage();
|
||||
|
||||
return unset(gpt);
|
||||
return gpt_attr_update(gpt, entry, 0, attributes);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue