MFp4:
119373: o Remove the query verb, along with the request and response parameters. o Add the version and output parameters. 119390: [APM,GPT] Properly clear deleted entries. 119394: o Make the alias the standard and use the '!' to prefix literal partition types. o Treat schemes and partition types as case insensitive. 119462: [GPT] Fix a page fault caused when modifying a partition entry without a new partition type.
This commit is contained in:
parent
62c4e3f043
commit
d287f59062
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=169389
@ -64,12 +64,12 @@ struct g_part_alias_list {
|
||||
const char *lexeme;
|
||||
enum g_part_alias alias;
|
||||
} g_part_alias_list[G_PART_ALIAS_COUNT] = {
|
||||
{ "@efi", G_PART_ALIAS_EFI },
|
||||
{ "@freebsd", G_PART_ALIAS_FREEBSD },
|
||||
{ "@freebsd-swap", G_PART_ALIAS_FREEBSD_SWAP },
|
||||
{ "@freebsd-ufs", G_PART_ALIAS_FREEBSD_UFS },
|
||||
{ "@freebsd-vinum", G_PART_ALIAS_FREEBSD_VINUM },
|
||||
{ "@mbr", G_PART_ALIAS_MBR }
|
||||
{ "efi", G_PART_ALIAS_EFI },
|
||||
{ "freebsd", G_PART_ALIAS_FREEBSD },
|
||||
{ "freebsd-swap", G_PART_ALIAS_FREEBSD_SWAP },
|
||||
{ "freebsd-ufs", G_PART_ALIAS_FREEBSD_UFS },
|
||||
{ "freebsd-vinum", G_PART_ALIAS_FREEBSD_VINUM },
|
||||
{ "mbr", G_PART_ALIAS_MBR }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -111,7 +111,6 @@ enum g_part_ctl {
|
||||
G_PART_CTL_DESTROY,
|
||||
G_PART_CTL_MODIFY,
|
||||
G_PART_CTL_MOVE,
|
||||
G_PART_CTL_QUERY,
|
||||
G_PART_CTL_RECOVER,
|
||||
G_PART_CTL_RESIZE,
|
||||
G_PART_CTL_UNDO
|
||||
@ -247,7 +246,7 @@ g_part_parm_scheme(const char *p, struct g_part_scheme **v)
|
||||
SET_FOREACH(iter, g_part_scheme_set) {
|
||||
if ((*iter)->name == NULL)
|
||||
continue;
|
||||
if (!strcmp((*iter)->name, p)) {
|
||||
if (!strcasecmp((*iter)->name, p)) {
|
||||
s = *iter;
|
||||
break;
|
||||
}
|
||||
@ -731,13 +730,6 @@ g_part_ctl_move(struct gctl_req *req, struct g_part_parms *gpp)
|
||||
return (ENOSYS);
|
||||
}
|
||||
|
||||
static int
|
||||
g_part_ctl_query(struct gctl_req *req, struct g_part_parms *gpp)
|
||||
{
|
||||
gctl_error(req, "%d verb 'query'", ENOSYS);
|
||||
return (ENOSYS);
|
||||
}
|
||||
|
||||
static int
|
||||
g_part_ctl_recover(struct gctl_req *req, struct g_part_parms *gpp)
|
||||
{
|
||||
@ -863,83 +855,67 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
|
||||
|
||||
ctlreq = G_PART_CTL_NONE;
|
||||
modifies = 0;
|
||||
mparms = oparms = 0;
|
||||
mparms = 0;
|
||||
oparms = G_PART_PARM_FLAGS | G_PART_PARM_OUTPUT | G_PART_PARM_VERSION;
|
||||
switch (*verb) {
|
||||
case 'a':
|
||||
if (!strcmp(verb, "add")) {
|
||||
ctlreq = G_PART_CTL_ADD;
|
||||
modifies = 1;
|
||||
mparms = G_PART_PARM_GEOM | G_PART_PARM_SIZE |
|
||||
mparms |= G_PART_PARM_GEOM | G_PART_PARM_SIZE |
|
||||
G_PART_PARM_START | G_PART_PARM_TYPE;
|
||||
oparms = G_PART_PARM_FLAGS | G_PART_PARM_INDEX |
|
||||
G_PART_PARM_LABEL;
|
||||
oparms |= G_PART_PARM_INDEX | G_PART_PARM_LABEL;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
if (!strcmp(verb, "commit")) {
|
||||
ctlreq = G_PART_CTL_COMMIT;
|
||||
mparms = G_PART_PARM_GEOM;
|
||||
oparms = G_PART_PARM_FLAGS;
|
||||
mparms |= G_PART_PARM_GEOM;
|
||||
} else if (!strcmp(verb, "create")) {
|
||||
ctlreq = G_PART_CTL_CREATE;
|
||||
modifies = 1;
|
||||
mparms = G_PART_PARM_PROVIDER |
|
||||
G_PART_PARM_SCHEME;
|
||||
oparms = G_PART_PARM_ENTRIES | G_PART_PARM_FLAGS;
|
||||
mparms |= G_PART_PARM_PROVIDER | G_PART_PARM_SCHEME;
|
||||
oparms |= G_PART_PARM_ENTRIES;
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if (!strcmp(verb, "delete")) {
|
||||
ctlreq = G_PART_CTL_DELETE;
|
||||
modifies = 1;
|
||||
mparms = G_PART_PARM_GEOM | G_PART_PARM_INDEX;
|
||||
oparms = G_PART_PARM_FLAGS;
|
||||
mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
|
||||
} else if (!strcmp(verb, "destroy")) {
|
||||
ctlreq = G_PART_CTL_DESTROY;
|
||||
modifies = 1;
|
||||
mparms = G_PART_PARM_GEOM;
|
||||
oparms = G_PART_PARM_FLAGS;
|
||||
mparms |= G_PART_PARM_GEOM;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
if (!strcmp(verb, "modify")) {
|
||||
ctlreq = G_PART_CTL_MODIFY;
|
||||
modifies = 1;
|
||||
mparms = G_PART_PARM_GEOM | G_PART_PARM_INDEX;
|
||||
oparms = G_PART_PARM_FLAGS | G_PART_PARM_LABEL |
|
||||
G_PART_PARM_TYPE;
|
||||
mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
|
||||
oparms |= G_PART_PARM_LABEL | G_PART_PARM_TYPE;
|
||||
} else if (!strcmp(verb, "move")) {
|
||||
ctlreq = G_PART_CTL_MOVE;
|
||||
modifies = 1;
|
||||
mparms = G_PART_PARM_GEOM | G_PART_PARM_INDEX;
|
||||
oparms = G_PART_PARM_FLAGS;
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
if (!strcmp(verb, "query")) {
|
||||
ctlreq = G_PART_CTL_QUERY;
|
||||
mparms = G_PART_PARM_REQUEST | G_PART_PARM_RESPONSE;
|
||||
oparms = G_PART_PARM_FLAGS | G_PART_PARM_GEOM;
|
||||
mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
if (!strcmp(verb, "recover")) {
|
||||
ctlreq = G_PART_CTL_RECOVER;
|
||||
modifies = 1;
|
||||
mparms = G_PART_PARM_GEOM;
|
||||
oparms = G_PART_PARM_FLAGS;
|
||||
mparms |= G_PART_PARM_GEOM;
|
||||
} else if (!strcmp(verb, "resize")) {
|
||||
ctlreq = G_PART_CTL_RESIZE;
|
||||
modifies = 1;
|
||||
mparms = G_PART_PARM_GEOM | G_PART_PARM_INDEX;
|
||||
oparms = G_PART_PARM_FLAGS;
|
||||
mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
if (!strcmp(verb, "undo")) {
|
||||
ctlreq = G_PART_CTL_UNDO;
|
||||
mparms = G_PART_PARM_GEOM;
|
||||
oparms = G_PART_PARM_FLAGS;
|
||||
mparms |= G_PART_PARM_GEOM;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -977,16 +953,14 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
|
||||
if (!strcmp(ap->name, "label"))
|
||||
parm = G_PART_PARM_LABEL;
|
||||
break;
|
||||
case 'o':
|
||||
if (!strcmp(ap->name, "output"))
|
||||
parm = G_PART_PARM_OUTPUT;
|
||||
break;
|
||||
case 'p':
|
||||
if (!strcmp(ap->name, "provider"))
|
||||
parm = G_PART_PARM_PROVIDER;
|
||||
break;
|
||||
case 'r':
|
||||
if (!strcmp(ap->name, "request"))
|
||||
parm = G_PART_PARM_REQUEST;
|
||||
else if (!strcmp(ap->name, "response"))
|
||||
parm = G_PART_PARM_RESPONSE;
|
||||
break;
|
||||
case 's':
|
||||
if (!strcmp(ap->name, "scheme"))
|
||||
parm = G_PART_PARM_SCHEME;
|
||||
@ -1002,6 +976,8 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
|
||||
case 'v':
|
||||
if (!strcmp(ap->name, "verb"))
|
||||
continue;
|
||||
else if (!strcmp(ap->name, "version"))
|
||||
parm = G_PART_PARM_VERSION;
|
||||
break;
|
||||
}
|
||||
if ((parm & (mparms | oparms)) == 0) {
|
||||
@ -1029,15 +1005,12 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
|
||||
case G_PART_PARM_LABEL:
|
||||
error = g_part_parm_str(p, &gpp.gpp_label);
|
||||
break;
|
||||
case G_PART_PARM_OUTPUT:
|
||||
error = 0; /* Write-only parameter */
|
||||
break;
|
||||
case G_PART_PARM_PROVIDER:
|
||||
error = g_part_parm_provider(p, &gpp.gpp_provider);
|
||||
break;
|
||||
case G_PART_PARM_REQUEST:
|
||||
error = g_part_parm_str(p, &gpp.gpp_request);
|
||||
break;
|
||||
case G_PART_PARM_RESPONSE:
|
||||
error = 0; /* Write-only parameter. */
|
||||
break;
|
||||
case G_PART_PARM_SCHEME:
|
||||
error = g_part_parm_scheme(p, &gpp.gpp_scheme);
|
||||
break;
|
||||
@ -1050,6 +1023,9 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
|
||||
case G_PART_PARM_TYPE:
|
||||
error = g_part_parm_str(p, &gpp.gpp_type);
|
||||
break;
|
||||
case G_PART_PARM_VERSION:
|
||||
error = g_part_parm_uint(p, &gpp.gpp_version);
|
||||
break;
|
||||
default:
|
||||
error = EDOOFUS;
|
||||
break;
|
||||
@ -1106,9 +1082,6 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
|
||||
case G_PART_CTL_MOVE:
|
||||
error = g_part_ctl_move(req, &gpp);
|
||||
break;
|
||||
case G_PART_CTL_QUERY:
|
||||
error = g_part_ctl_query(req, &gpp);
|
||||
break;
|
||||
case G_PART_CTL_RECOVER:
|
||||
error = g_part_ctl_recover(req, &gpp);
|
||||
break;
|
||||
|
@ -104,13 +104,13 @@ struct g_part_entry *g_part_new_entry(struct g_part_table *, int, quad_t,
|
||||
#define G_PART_PARM_GEOM 0x0004
|
||||
#define G_PART_PARM_INDEX 0x0008
|
||||
#define G_PART_PARM_LABEL 0x0010
|
||||
#define G_PART_PARM_PROVIDER 0x0020
|
||||
#define G_PART_PARM_REQUEST 0x0040
|
||||
#define G_PART_PARM_RESPONSE 0x0080
|
||||
#define G_PART_PARM_SCHEME 0x0100
|
||||
#define G_PART_PARM_SIZE 0x0200
|
||||
#define G_PART_PARM_START 0x0400
|
||||
#define G_PART_PARM_TYPE 0x0800
|
||||
#define G_PART_PARM_OUTPUT 0x0020
|
||||
#define G_PART_PARM_PROVIDER 0x0040
|
||||
#define G_PART_PARM_SCHEME 0x0080
|
||||
#define G_PART_PARM_SIZE 0x0100
|
||||
#define G_PART_PARM_START 0x0200
|
||||
#define G_PART_PARM_TYPE 0x0400
|
||||
#define G_PART_PARM_VERSION 0x0800
|
||||
|
||||
struct g_part_parms {
|
||||
unsigned int gpp_parms;
|
||||
@ -120,11 +120,11 @@ struct g_part_parms {
|
||||
unsigned int gpp_index;
|
||||
const char *gpp_label;
|
||||
struct g_provider *gpp_provider;
|
||||
const char *gpp_request;
|
||||
struct g_part_scheme *gpp_scheme;
|
||||
quad_t gpp_size;
|
||||
quad_t gpp_start;
|
||||
const char *gpp_type;
|
||||
unsigned int gpp_version;
|
||||
};
|
||||
|
||||
#endif /* !_GEOM_PART_H_ */
|
||||
|
@ -99,8 +99,10 @@ G_PART_SCHEME_DECLARE(g_part_apm_scheme);
|
||||
static int
|
||||
apm_parse_type(const char *type, char *buf, size_t bufsz)
|
||||
{
|
||||
const char *alias;
|
||||
|
||||
if (type[0] != '@') {
|
||||
if (type[0] == '!') {
|
||||
type++;
|
||||
if (strlen(type) > bufsz)
|
||||
return (EINVAL);
|
||||
if (!strcmp(type, APM_ENT_TYPE_SELF) ||
|
||||
@ -109,17 +111,27 @@ apm_parse_type(const char *type, char *buf, size_t bufsz)
|
||||
strncpy(buf, type, bufsz);
|
||||
return (0);
|
||||
}
|
||||
if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD)))
|
||||
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD);
|
||||
if (!strcasecmp(type, alias)) {
|
||||
strcpy(buf, APM_ENT_TYPE_FREEBSD);
|
||||
else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP)))
|
||||
return (0);
|
||||
}
|
||||
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP);
|
||||
if (!strcasecmp(type, alias)) {
|
||||
strcpy(buf, APM_ENT_TYPE_FREEBSD_SWAP);
|
||||
else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS)))
|
||||
return (0);
|
||||
}
|
||||
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS);
|
||||
if (!strcasecmp(type, alias)) {
|
||||
strcpy(buf, APM_ENT_TYPE_FREEBSD_UFS);
|
||||
else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM)))
|
||||
return (0);
|
||||
}
|
||||
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM);
|
||||
if (!strcasecmp(type, alias)) {
|
||||
strcpy(buf, APM_ENT_TYPE_FREEBSD_VINUM);
|
||||
else
|
||||
return (EINVAL);
|
||||
return (0);
|
||||
return (0);
|
||||
}
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -392,15 +404,15 @@ g_part_apm_write(struct g_part_table *basetable, struct g_consumer *cp)
|
||||
|
||||
baseentry = LIST_FIRST(&basetable->gpt_entry);
|
||||
for (index = 1; index <= basetable->gpt_entries; index++) {
|
||||
if (baseentry != NULL && index == baseentry->gpe_index) {
|
||||
entry = (struct g_part_apm_entry *)baseentry;
|
||||
entry = (baseentry != NULL && index == baseentry->gpe_index)
|
||||
? (struct g_part_apm_entry *)baseentry : NULL;
|
||||
if (entry != NULL && !baseentry->gpe_deleted) {
|
||||
be32enc(buf + 8, entry->ent.ent_start);
|
||||
be32enc(buf + 12, entry->ent.ent_size);
|
||||
bcopy(entry->ent.ent_name, buf + 16,
|
||||
sizeof(entry->ent.ent_name));
|
||||
bcopy(entry->ent.ent_type, buf + 48,
|
||||
sizeof(entry->ent.ent_type));
|
||||
baseentry = LIST_NEXT(baseentry, gpe_entry);
|
||||
} else {
|
||||
bzero(buf + 8, 4 + 4 + 32 + 32);
|
||||
strcpy(buf + 48, APM_ENT_TYPE_UNUSED);
|
||||
@ -408,6 +420,8 @@ g_part_apm_write(struct g_part_table *basetable, struct g_consumer *cp)
|
||||
error = g_write_data(cp, (index + 1) * 512, buf, sizeof(buf));
|
||||
if (error)
|
||||
return (error);
|
||||
if (entry != NULL)
|
||||
baseentry = LIST_NEXT(baseentry, gpe_entry);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
@ -272,10 +272,11 @@ static int
|
||||
gpt_parse_type(const char *type, struct uuid *uuid)
|
||||
{
|
||||
struct uuid tmp;
|
||||
const char *alias;
|
||||
int error;
|
||||
|
||||
if (type[0] != '@') {
|
||||
error = parse_uuid(type, &tmp);
|
||||
if (type[0] == '!') {
|
||||
error = parse_uuid(type + 1, &tmp);
|
||||
if (error)
|
||||
return (error);
|
||||
if (EQUUID(&tmp, &gpt_uuid_unused))
|
||||
@ -283,21 +284,37 @@ gpt_parse_type(const char *type, struct uuid *uuid)
|
||||
*uuid = tmp;
|
||||
return (0);
|
||||
}
|
||||
if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_EFI)))
|
||||
alias = g_part_alias_name(G_PART_ALIAS_EFI);
|
||||
if (!strcasecmp(type, alias)) {
|
||||
*uuid = gpt_uuid_efi;
|
||||
else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD)))
|
||||
return (0);
|
||||
}
|
||||
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD);
|
||||
if (!strcasecmp(type, alias)) {
|
||||
*uuid = gpt_uuid_freebsd;
|
||||
else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP)))
|
||||
return (0);
|
||||
}
|
||||
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP);
|
||||
if (!strcasecmp(type, alias)) {
|
||||
*uuid = gpt_uuid_freebsd_swap;
|
||||
else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS)))
|
||||
return (0);
|
||||
}
|
||||
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS);
|
||||
if (!strcasecmp(type, alias)) {
|
||||
*uuid = gpt_uuid_freebsd_ufs;
|
||||
else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM)))
|
||||
return (0);
|
||||
}
|
||||
alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM);
|
||||
if (!strcasecmp(type, alias)) {
|
||||
*uuid = gpt_uuid_freebsd_vinum;
|
||||
else if (!strcmp(type, g_part_alias_name(G_PART_ALIAS_MBR)))
|
||||
return (0);
|
||||
}
|
||||
alias = g_part_alias_name(G_PART_ALIAS_MBR);
|
||||
if (!strcasecmp(type, alias)) {
|
||||
*uuid = gpt_uuid_mbr;
|
||||
else
|
||||
return (EINVAL);
|
||||
return (0);
|
||||
return (0);
|
||||
}
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -391,9 +408,11 @@ g_part_gpt_modify(struct g_part_table *basetable,
|
||||
int error;
|
||||
|
||||
entry = (struct g_part_gpt_entry *)baseentry;
|
||||
error = gpt_parse_type(gpp->gpp_type, &entry->ent.ent_type);
|
||||
if (error)
|
||||
return (error);
|
||||
if (gpp->gpp_parms & G_PART_PARM_TYPE) {
|
||||
error = gpt_parse_type(gpp->gpp_type, &entry->ent.ent_type);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
/* XXX label */
|
||||
return (0);
|
||||
}
|
||||
@ -636,6 +655,8 @@ g_part_gpt_write(struct g_part_table *basetable, struct g_consumer *cp)
|
||||
le32enc(buf + 84, table->hdr.hdr_entsz);
|
||||
|
||||
LIST_FOREACH(baseentry, &basetable->gpt_entry, gpe_entry) {
|
||||
if (baseentry->gpe_deleted)
|
||||
continue;
|
||||
entry = (struct g_part_gpt_entry *)baseentry;
|
||||
index = baseentry->gpe_index - 1;
|
||||
bp = buf + pp->sectorsize + table->hdr.hdr_entsz * index;
|
||||
|
Loading…
Reference in New Issue
Block a user