Fix resizedisk.
This commit is contained in:
parent
b8ae390746
commit
5b47b594ae
|
@ -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.62 2015/12/04 01:46:32 christos Exp $");
|
||||
__RCSID("$NetBSD: gpt.c,v 1.63 2015/12/04 16:46:24 christos Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -829,16 +829,8 @@ gpt_create(gpt_t gpt, off_t last, u_int parts, int primary_only)
|
|||
|
||||
blocks--; /* Number of blocks in the GPT table. */
|
||||
|
||||
if ((p = calloc(1, gpt->secsz)) == NULL) {
|
||||
gpt_warnx(gpt, "Can't allocate the primary GPT");
|
||||
if (gpt_add_hdr(gpt, MAP_TYPE_PRI_GPT_HDR, 1) == -1)
|
||||
return -1;
|
||||
}
|
||||
if ((gpt->gpt = map_add(gpt, 1LL, 1LL,
|
||||
MAP_TYPE_PRI_GPT_HDR, p, 1)) == NULL) {
|
||||
free(p);
|
||||
gpt_warnx(gpt, "Can't add the primary GPT");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((p = calloc((size_t)blocks, gpt->secsz)) == NULL) {
|
||||
gpt_warnx(gpt, "Can't allocate the primary GPT table");
|
||||
|
@ -885,16 +877,8 @@ gpt_create(gpt_t gpt, off_t last, u_int parts, int primary_only)
|
|||
if (primary_only)
|
||||
return last;
|
||||
|
||||
if ((p = calloc(1, gpt->secsz)) == NULL) {
|
||||
gpt_warnx(gpt, "Can't allocate the secondary GPT");
|
||||
if (gpt_add_hdr(gpt, MAP_TYPE_SEC_GPT_HDR, last) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((gpt->tpg = map_add(gpt, last, 1LL,
|
||||
MAP_TYPE_SEC_GPT_HDR, p, 1)) == 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, 0)) == NULL) {
|
||||
|
@ -1202,3 +1186,38 @@ gpt_show_num(const char *prompt, uintmax_t num)
|
|||
#endif
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int
|
||||
gpt_add_hdr(gpt_t gpt, int type, off_t loc)
|
||||
{
|
||||
void *p;
|
||||
map_t *t;
|
||||
const char *msg;
|
||||
|
||||
switch (type) {
|
||||
case MAP_TYPE_PRI_GPT_HDR:
|
||||
t = &gpt->gpt;
|
||||
msg = "primary";
|
||||
break;
|
||||
case MAP_TYPE_SEC_GPT_HDR:
|
||||
t = &gpt->tpg;
|
||||
msg = "secondary";
|
||||
break;
|
||||
default:
|
||||
gpt_warnx(gpt, "Unknown GPT header type %d", type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((p = calloc(1, gpt->secsz)) == NULL) {
|
||||
gpt_warn(gpt, "Error allocating %s GPT header", msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*t = map_add(gpt, loc, 1LL, type, p, 1);
|
||||
if (*t == NULL) {
|
||||
gpt_warn(gpt, "Error adding %s GPT header", msg);
|
||||
free(p);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ int gpt_uint_get(u_int *);
|
|||
int gpt_human_get(off_t *);
|
||||
int gpt_uuid_get(gpt_t, gpt_uuid_t *);
|
||||
int gpt_name_get(gpt_t, void *);
|
||||
int gpt_add_hdr(gpt_t, int, off_t);
|
||||
void gpt_show_num(const char *, uintmax_t);
|
||||
|
||||
#endif /* _GPT_H_ */
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
__FBSDID("$FreeBSD: src/sbin/gpt/recover.c,v 1.8 2005/08/31 01:47:19 marcel Exp $");
|
||||
#endif
|
||||
#ifdef __RCSID
|
||||
__RCSID("$NetBSD: recover.c,v 1.14 2015/12/03 21:30:54 christos Exp $");
|
||||
__RCSID("$NetBSD: recover.c,v 1.15 2015/12/04 16:46:24 christos Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -68,10 +68,12 @@ static int
|
|||
recover_gpt_hdr(gpt_t gpt, int type, off_t last)
|
||||
{
|
||||
const char *name, *origname;
|
||||
void *p;
|
||||
map_t *dgpt, dtbl, sgpt, stbl;
|
||||
struct gpt_hdr *hdr;
|
||||
|
||||
if (gpt_add_hdr(gpt, type, last) == -1)
|
||||
return -1;
|
||||
|
||||
switch (type) {
|
||||
case MAP_TYPE_PRI_GPT_HDR:
|
||||
dgpt = &gpt->gpt;
|
||||
|
@ -94,14 +96,6 @@ recover_gpt_hdr(gpt_t gpt, int type, off_t last)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((p = calloc(1, gpt->secsz)) == NULL) {
|
||||
gpt_warn(gpt, "Cannot allocate %s GPT header", name);
|
||||
return -1;
|
||||
}
|
||||
if ((*dgpt = map_add(gpt, last, 1LL, type, p, 1)) == NULL) {
|
||||
gpt_warnx(gpt, "Cannot add %s GPT header", name);
|
||||
return -1;
|
||||
}
|
||||
memcpy((*dgpt)->map_data, sgpt->map_data, gpt->secsz);
|
||||
hdr = (*dgpt)->map_data;
|
||||
hdr->hdr_lba_self = htole64((uint64_t)(*dgpt)->map_start);
|
||||
|
|
|
@ -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.15 2015/12/03 21:30:54 christos Exp $");
|
||||
__RCSID("$NetBSD: resizedisk.c,v 1.16 2015/12/04 16:46:24 christos Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/bootblock.h>
|
||||
|
@ -58,7 +58,7 @@ static const char *resizediskhelp[] = {
|
|||
};
|
||||
|
||||
struct gpt_cmd c_resizedisk = {
|
||||
"resize",
|
||||
"resizedisk",
|
||||
cmd_resizedisk,
|
||||
resizediskhelp, __arraycount(resizediskhelp),
|
||||
0,
|
||||
|
@ -86,14 +86,15 @@ resizedisk(gpt_t gpt, off_t sector, off_t size)
|
|||
struct mbr *mbr;
|
||||
off_t last, oldloc, newloc, lastdata, gpt_size;
|
||||
int i;
|
||||
void *p;
|
||||
|
||||
last = gpt->mediasz / gpt->secsz - 1;
|
||||
lastdata = 0;
|
||||
newloc = 0;
|
||||
|
||||
if (sector > last) {
|
||||
gpt_warnx(gpt, "specified size is larger then the disk");
|
||||
gpt_warnx(gpt, "specified number of sectors %jd"
|
||||
" is larger then the disk %jd", (uintmax_t)sector,
|
||||
(uintmax_t)last);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -105,22 +106,39 @@ resizedisk(gpt_t gpt, off_t sector, off_t size)
|
|||
mbr = mbrmap->map_data;
|
||||
|
||||
gpt->gpt = map_find(gpt, MAP_TYPE_PRI_GPT_HDR);
|
||||
ent = NULL;
|
||||
if (gpt == NULL) {
|
||||
gpt_warnx(gpt, "No primary GPT header; run create or recover");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpt->tbl = map_find(gpt, MAP_TYPE_PRI_GPT_TBL);
|
||||
if (gpt->tbl == NULL) {
|
||||
gpt_warnx(gpt, "No primary GPT table; Run recover");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdr = gpt->gpt->map_data;
|
||||
oldloc = (off_t)le64toh((uint64_t)hdr->hdr_lba_alt);
|
||||
|
||||
gpt->tpg = map_find(gpt, MAP_TYPE_SEC_GPT_HDR);
|
||||
if (gpt->tpg == NULL)
|
||||
if (gpt_gpt(gpt, oldloc, 1))
|
||||
gpt->tpg = map_find(gpt, MAP_TYPE_SEC_GPT_HDR);
|
||||
gpt->lbt = map_find(gpt, MAP_TYPE_SEC_GPT_TBL);
|
||||
if (gpt->tpg == NULL || gpt->lbt == NULL) {
|
||||
if (gpt_gpt(gpt, oldloc, 1) == -1) {
|
||||
gpt_warnx(gpt,
|
||||
"Error reading backup GPT information at %#jx",
|
||||
oldloc);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
gpt->tbl = map_find(gpt, MAP_TYPE_PRI_GPT_TBL);
|
||||
if (gpt->tbl == NULL) {
|
||||
gpt_warnx(gpt, "Run recover");
|
||||
gpt->tpg = map_find(gpt, MAP_TYPE_SEC_GPT_HDR);
|
||||
if (gpt->tpg == NULL) {
|
||||
gpt_warnx(gpt, "No secondary GPT header; Run recover");
|
||||
return -1;
|
||||
}
|
||||
gpt->lbt = map_find(gpt, MAP_TYPE_SEC_GPT_TBL);
|
||||
if (gpt->lbt == NULL) {
|
||||
gpt_warnx(gpt, "No secondary GPT table; Run recover");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -129,6 +147,7 @@ resizedisk(gpt_t gpt, off_t sector, off_t size)
|
|||
gpt_warnx(gpt, "Device is already the specified size");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sector == 0 && last == oldloc) {
|
||||
gpt_warnx(gpt, "Device hasn't changed size");
|
||||
return 0;
|
||||
|
@ -142,11 +161,13 @@ resizedisk(gpt_t gpt, off_t sector, off_t size)
|
|||
lastdata = (off_t)le64toh((uint64_t)ent->ent_lba_end);
|
||||
}
|
||||
}
|
||||
|
||||
if (sector - gpt_size <= lastdata) {
|
||||
gpt_warnx(gpt, "Not enough space at %" PRIu64
|
||||
" for secondary GPT table", sector);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (last - gpt_size <= lastdata) {
|
||||
gpt_warnx(gpt, "Not enough space for new secondary GPT table");
|
||||
return -1;
|
||||
|
@ -158,6 +179,7 @@ resizedisk(gpt_t gpt, off_t sector, off_t size)
|
|||
newloc = sector;
|
||||
if (sector == 0 && last > oldloc)
|
||||
newloc = last;
|
||||
|
||||
if (newloc > 0) {
|
||||
if (gpt->tpg == NULL) {
|
||||
gpt_warnx(gpt, "No secondary GPT header; run recover");
|
||||
|
@ -175,16 +197,8 @@ resizedisk(gpt_t gpt, off_t sector, off_t size)
|
|||
else
|
||||
newloc = last;
|
||||
|
||||
if ((p = calloc(1, gpt->secsz)) == NULL) {
|
||||
gpt_warn(gpt, "Error allocating secondary GPT header");
|
||||
if (gpt_add_hdr(gpt, MAP_TYPE_SEC_GPT_HDR, newloc) == -1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpt->tpg = map_add(gpt, newloc, 1LL, MAP_TYPE_SEC_GPT_HDR, p, 1);
|
||||
if (gpt->tpg == NULL) {
|
||||
gpt_warn(gpt, "Error adding secondary GPT header");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpt->lbt = map_add(gpt, newloc - gpt_size, gpt_size,
|
||||
MAP_TYPE_SEC_GPT_TBL, gpt->tbl->map_data, 0);
|
||||
|
@ -238,7 +252,7 @@ static int
|
|||
cmd_resizedisk(gpt_t gpt, int argc, char *argv[])
|
||||
{
|
||||
int ch;
|
||||
off_t sector, size = 0;
|
||||
off_t sector, size = gpt->mediasz;
|
||||
|
||||
while ((ch = getopt(argc, argv, "s:")) != -1) {
|
||||
switch(ch) {
|
||||
|
@ -257,5 +271,10 @@ cmd_resizedisk(gpt_t gpt, int argc, char *argv[])
|
|||
if ((sector = gpt_check_ais(gpt, 0, (u_int)~0, size)) == -1)
|
||||
return -1;
|
||||
|
||||
if (--sector == 0) {
|
||||
gpt_warnx(gpt, "New size %ju too small", (uintptr_t)size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return resizedisk(gpt, sector, size);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue