Add the set and unset verbs used to set and clear attributes for
partition entries. Implement the setunset method for the MBR scheme to control the active flag.
This commit is contained in:
parent
dd76dbbb9c
commit
f6aa3fccce
@ -1,5 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2002, 2005, 2006, 2007 Marcel Moolenaar
|
* Copyright (c) 2002, 2005-2008 Marcel Moolenaar
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -121,7 +121,9 @@ enum g_part_ctl {
|
|||||||
G_PART_CTL_MOVE,
|
G_PART_CTL_MOVE,
|
||||||
G_PART_CTL_RECOVER,
|
G_PART_CTL_RECOVER,
|
||||||
G_PART_CTL_RESIZE,
|
G_PART_CTL_RESIZE,
|
||||||
G_PART_CTL_UNDO
|
G_PART_CTL_SET,
|
||||||
|
G_PART_CTL_UNDO,
|
||||||
|
G_PART_CTL_UNSET
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -953,6 +955,53 @@ g_part_ctl_resize(struct gctl_req *req, struct g_part_parms *gpp)
|
|||||||
return (ENOSYS);
|
return (ENOSYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
g_part_ctl_setunset(struct gctl_req *req, struct g_part_parms *gpp,
|
||||||
|
unsigned int set)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
struct g_geom *gp;
|
||||||
|
struct g_part_entry *entry;
|
||||||
|
struct g_part_table *table;
|
||||||
|
struct sbuf *sb;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
gp = gpp->gpp_geom;
|
||||||
|
G_PART_TRACE((G_T_TOPOLOGY, "%s(%s)", __func__, gp->name));
|
||||||
|
g_topology_assert();
|
||||||
|
|
||||||
|
table = gp->softc;
|
||||||
|
|
||||||
|
LIST_FOREACH(entry, &table->gpt_entry, gpe_entry) {
|
||||||
|
if (entry->gpe_deleted || entry->gpe_internal)
|
||||||
|
continue;
|
||||||
|
if (entry->gpe_index == gpp->gpp_index)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (entry == NULL) {
|
||||||
|
gctl_error(req, "%d index '%d'", ENOENT, gpp->gpp_index);
|
||||||
|
return (ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = G_PART_SETUNSET(table, entry, gpp->gpp_attrib, set);
|
||||||
|
if (error) {
|
||||||
|
gctl_error(req, "%d attrib '%s'", error, gpp->gpp_attrib);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Provide feedback if so requested. */
|
||||||
|
if (gpp->gpp_parms & G_PART_PARM_OUTPUT) {
|
||||||
|
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
|
||||||
|
sbuf_printf(sb, "%s%s has %s %sset\n", gp->name,
|
||||||
|
G_PART_NAME(table, entry, buf, sizeof(buf)),
|
||||||
|
gpp->gpp_attrib, (set) ? "" : "un");
|
||||||
|
sbuf_finish(sb);
|
||||||
|
gctl_set_param(req, "output", sbuf_data(sb), sbuf_len(sb) + 1);
|
||||||
|
sbuf_delete(sb);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
g_part_ctl_undo(struct gctl_req *req, struct g_part_parms *gpp)
|
g_part_ctl_undo(struct gctl_req *req, struct g_part_parms *gpp)
|
||||||
{
|
{
|
||||||
@ -1129,11 +1178,22 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
|
|||||||
mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
|
mparms |= G_PART_PARM_GEOM | G_PART_PARM_INDEX;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 's':
|
||||||
|
if (!strcmp(verb, "set")) {
|
||||||
|
ctlreq = G_PART_CTL_SET;
|
||||||
|
mparms |= G_PART_PARM_ATTRIB | G_PART_PARM_GEOM |
|
||||||
|
G_PART_PARM_INDEX;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
if (!strcmp(verb, "undo")) {
|
if (!strcmp(verb, "undo")) {
|
||||||
ctlreq = G_PART_CTL_UNDO;
|
ctlreq = G_PART_CTL_UNDO;
|
||||||
mparms |= G_PART_PARM_GEOM;
|
mparms |= G_PART_PARM_GEOM;
|
||||||
modifies = 0;
|
modifies = 0;
|
||||||
|
} else if (!strcmp(verb, "unset")) {
|
||||||
|
ctlreq = G_PART_CTL_UNSET;
|
||||||
|
mparms |= G_PART_PARM_ATTRIB | G_PART_PARM_GEOM |
|
||||||
|
G_PART_PARM_INDEX;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1147,6 +1207,10 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
|
|||||||
ap = &req->arg[i];
|
ap = &req->arg[i];
|
||||||
parm = 0;
|
parm = 0;
|
||||||
switch (ap->name[0]) {
|
switch (ap->name[0]) {
|
||||||
|
case 'a':
|
||||||
|
if (!strcmp(ap->name, "attrib"))
|
||||||
|
parm = G_PART_PARM_ATTRIB;
|
||||||
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
if (!strcmp(ap->name, "bootcode"))
|
if (!strcmp(ap->name, "bootcode"))
|
||||||
parm = G_PART_PARM_BOOTCODE;
|
parm = G_PART_PARM_BOOTCODE;
|
||||||
@ -1215,6 +1279,9 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (parm) {
|
switch (parm) {
|
||||||
|
case G_PART_PARM_ATTRIB:
|
||||||
|
error = g_part_parm_str(p, &gpp.gpp_attrib);
|
||||||
|
break;
|
||||||
case G_PART_PARM_BOOTCODE:
|
case G_PART_PARM_BOOTCODE:
|
||||||
gpp.gpp_codeptr = p;
|
gpp.gpp_codeptr = p;
|
||||||
gpp.gpp_codesize = len;
|
gpp.gpp_codesize = len;
|
||||||
@ -1328,9 +1395,15 @@ g_part_ctlreq(struct gctl_req *req, struct g_class *mp, const char *verb)
|
|||||||
case G_PART_CTL_RESIZE:
|
case G_PART_CTL_RESIZE:
|
||||||
error = g_part_ctl_resize(req, &gpp);
|
error = g_part_ctl_resize(req, &gpp);
|
||||||
break;
|
break;
|
||||||
|
case G_PART_CTL_SET:
|
||||||
|
error = g_part_ctl_setunset(req, &gpp, 1);
|
||||||
|
break;
|
||||||
case G_PART_CTL_UNDO:
|
case G_PART_CTL_UNDO:
|
||||||
error = g_part_ctl_undo(req, &gpp);
|
error = g_part_ctl_undo(req, &gpp);
|
||||||
break;
|
break;
|
||||||
|
case G_PART_CTL_UNSET:
|
||||||
|
error = g_part_ctl_setunset(req, &gpp, 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implement automatic commit. */
|
/* Implement automatic commit. */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2006, 2007 Marcel Moolenaar
|
* Copyright (c) 2006-2008 Marcel Moolenaar
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -136,6 +136,7 @@ struct g_part_entry *g_part_new_entry(struct g_part_table *, int, quad_t,
|
|||||||
#define G_PART_PARM_TYPE 0x0400
|
#define G_PART_PARM_TYPE 0x0400
|
||||||
#define G_PART_PARM_VERSION 0x0800
|
#define G_PART_PARM_VERSION 0x0800
|
||||||
#define G_PART_PARM_BOOTCODE 0x1000
|
#define G_PART_PARM_BOOTCODE 0x1000
|
||||||
|
#define G_PART_PARM_ATTRIB 0x2000
|
||||||
|
|
||||||
struct g_part_parms {
|
struct g_part_parms {
|
||||||
unsigned int gpp_parms;
|
unsigned int gpp_parms;
|
||||||
@ -152,6 +153,7 @@ struct g_part_parms {
|
|||||||
unsigned int gpp_version;
|
unsigned int gpp_version;
|
||||||
const void *gpp_codeptr;
|
const void *gpp_codeptr;
|
||||||
unsigned int gpp_codesize;
|
unsigned int gpp_codesize;
|
||||||
|
const char *gpp_attrib;
|
||||||
};
|
};
|
||||||
|
|
||||||
void g_part_geometry_heads(off_t, u_int, off_t *, u_int *);
|
void g_part_geometry_heads(off_t, u_int, off_t *, u_int *);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#-
|
#-
|
||||||
# Copyright (c) 2006, 2007 Marcel Moolenaar
|
# Copyright (c) 2006-2008 Marcel Moolenaar
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@ -108,6 +108,14 @@ METHOD int read {
|
|||||||
struct g_consumer *cp;
|
struct g_consumer *cp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# setunset() - set or unset partition entry attributes.
|
||||||
|
METHOD int setunset {
|
||||||
|
struct g_part_table *table;
|
||||||
|
struct g_part_entry *entry;
|
||||||
|
const char *attrib;
|
||||||
|
unsigned int set;
|
||||||
|
};
|
||||||
|
|
||||||
# type() - return a string representation of the partition type.
|
# type() - return a string representation of the partition type.
|
||||||
# Preferrably, the alias names.
|
# Preferrably, the alias names.
|
||||||
METHOD const char * type {
|
METHOD const char * type {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2007 Marcel Moolenaar
|
* Copyright (c) 2007, 2008 Marcel Moolenaar
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -71,6 +71,8 @@ static char *g_part_mbr_name(struct g_part_table *, struct g_part_entry *,
|
|||||||
char *, size_t);
|
char *, size_t);
|
||||||
static int g_part_mbr_probe(struct g_part_table *, struct g_consumer *);
|
static int g_part_mbr_probe(struct g_part_table *, struct g_consumer *);
|
||||||
static int g_part_mbr_read(struct g_part_table *, struct g_consumer *);
|
static int g_part_mbr_read(struct g_part_table *, struct g_consumer *);
|
||||||
|
static int g_part_mbr_setunset(struct g_part_table *, struct g_part_entry *,
|
||||||
|
const char *, unsigned int);
|
||||||
static const char *g_part_mbr_type(struct g_part_table *, struct g_part_entry *,
|
static const char *g_part_mbr_type(struct g_part_table *, struct g_part_entry *,
|
||||||
char *, size_t);
|
char *, size_t);
|
||||||
static int g_part_mbr_write(struct g_part_table *, struct g_consumer *);
|
static int g_part_mbr_write(struct g_part_table *, struct g_consumer *);
|
||||||
@ -86,6 +88,7 @@ static kobj_method_t g_part_mbr_methods[] = {
|
|||||||
KOBJMETHOD(g_part_name, g_part_mbr_name),
|
KOBJMETHOD(g_part_name, g_part_mbr_name),
|
||||||
KOBJMETHOD(g_part_probe, g_part_mbr_probe),
|
KOBJMETHOD(g_part_probe, g_part_mbr_probe),
|
||||||
KOBJMETHOD(g_part_read, g_part_mbr_read),
|
KOBJMETHOD(g_part_read, g_part_mbr_read),
|
||||||
|
KOBJMETHOD(g_part_setunset, g_part_mbr_setunset),
|
||||||
KOBJMETHOD(g_part_type, g_part_mbr_type),
|
KOBJMETHOD(g_part_type, g_part_mbr_type),
|
||||||
KOBJMETHOD(g_part_write, g_part_mbr_write),
|
KOBJMETHOD(g_part_write, g_part_mbr_write),
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
@ -262,6 +265,8 @@ g_part_mbr_dumpconf(struct g_part_table *table, struct g_part_entry *baseentry,
|
|||||||
/* confxml: partition entry information */
|
/* confxml: partition entry information */
|
||||||
sbuf_printf(sb, "%s<rawtype>%u</rawtype>\n", indent,
|
sbuf_printf(sb, "%s<rawtype>%u</rawtype>\n", indent,
|
||||||
entry->ent.dp_typ);
|
entry->ent.dp_typ);
|
||||||
|
if (entry->ent.dp_flag & 0x80)
|
||||||
|
sbuf_printf(sb, "%s<attrib>active</attrib>\n", indent);
|
||||||
} else {
|
} else {
|
||||||
/* confxml: scheme information */
|
/* confxml: scheme information */
|
||||||
}
|
}
|
||||||
@ -420,6 +425,43 @@ g_part_mbr_read(struct g_part_table *basetable, struct g_consumer *cp)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
g_part_mbr_setunset(struct g_part_table *table, struct g_part_entry *baseentry,
|
||||||
|
const char *attrib, unsigned int set)
|
||||||
|
{
|
||||||
|
struct g_part_entry *iter;
|
||||||
|
struct g_part_mbr_entry *entry;
|
||||||
|
int changed;
|
||||||
|
|
||||||
|
if (strcasecmp(attrib, "active") != 0)
|
||||||
|
return (EINVAL);
|
||||||
|
|
||||||
|
/* Only one entry can have the active attribute. */
|
||||||
|
LIST_FOREACH(iter, &table->gpt_entry, gpe_entry) {
|
||||||
|
if (iter->gpe_deleted)
|
||||||
|
continue;
|
||||||
|
changed = 0;
|
||||||
|
entry = (struct g_part_mbr_entry *)iter;
|
||||||
|
if (iter == baseentry) {
|
||||||
|
if (set && (entry->ent.dp_flag & 0x80) == 0) {
|
||||||
|
entry->ent.dp_flag |= 0x80;
|
||||||
|
changed = 1;
|
||||||
|
} else if (!set && (entry->ent.dp_flag & 0x80)) {
|
||||||
|
entry->ent.dp_flag &= ~0x80;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (set && (entry->ent.dp_flag & 0x80)) {
|
||||||
|
entry->ent.dp_flag &= ~0x80;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed && !iter->gpe_created)
|
||||||
|
iter->gpe_modified = 1;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
g_part_mbr_type(struct g_part_table *basetable, struct g_part_entry *baseentry,
|
g_part_mbr_type(struct g_part_table *basetable, struct g_part_entry *baseentry,
|
||||||
char *buf, size_t bufsz)
|
char *buf, size_t bufsz)
|
||||||
|
Loading…
Reference in New Issue
Block a user