mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-23 18:01:04 +01:00
Add optional -o argument to the graid label
to specify some metadata
format options. Use it for specifying byte order for the DDF metadata: big-endian defined by specification and little-endian used by Adaptec.
This commit is contained in:
parent
6107adc3f5
commit
8df8e26adc
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=234940
@ -48,11 +48,12 @@ struct g_command class_commands[] = {
|
|||||||
{ "label", G_FLAG_VERBOSE, NULL,
|
{ "label", G_FLAG_VERBOSE, NULL,
|
||||||
{
|
{
|
||||||
{ 'f', "force", NULL, G_TYPE_BOOL },
|
{ 'f', "force", NULL, G_TYPE_BOOL },
|
||||||
|
{ 'o', "fmtopt", G_VAL_OPTIONAL, G_TYPE_STRING },
|
||||||
{ 'S', "size", G_VAL_OPTIONAL, G_TYPE_NUMBER },
|
{ 'S', "size", G_VAL_OPTIONAL, G_TYPE_NUMBER },
|
||||||
{ 's', "strip", G_VAL_OPTIONAL, G_TYPE_NUMBER },
|
{ 's', "strip", G_VAL_OPTIONAL, G_TYPE_NUMBER },
|
||||||
G_OPT_SENTINEL
|
G_OPT_SENTINEL
|
||||||
},
|
},
|
||||||
"[-fv] [-S size] [-s stripsize] format label level prov ..."
|
"[-fv] [-o fmtopt] [-S size] [-s stripsize] format label level prov ..."
|
||||||
},
|
},
|
||||||
{ "add", G_FLAG_VERBOSE, NULL,
|
{ "add", G_FLAG_VERBOSE, NULL,
|
||||||
{
|
{
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
.Nm
|
.Nm
|
||||||
.Cm label
|
.Cm label
|
||||||
.Op Fl f
|
.Op Fl f
|
||||||
|
.Op Fl o Ar fmtopt
|
||||||
.Op Fl S Ar size
|
.Op Fl S Ar size
|
||||||
.Op Fl s Ar strip
|
.Op Fl s Ar strip
|
||||||
.Ar format
|
.Ar format
|
||||||
@ -119,6 +120,8 @@ Additional options include:
|
|||||||
.It Fl f
|
.It Fl f
|
||||||
Enforce specified configuration creation if it is officially unsupported,
|
Enforce specified configuration creation if it is officially unsupported,
|
||||||
but technically can be created.
|
but technically can be created.
|
||||||
|
.It Fl o Ar fmtopt
|
||||||
|
Specifies metadata format options.
|
||||||
.It Fl S Ar size
|
.It Fl S Ar size
|
||||||
Use
|
Use
|
||||||
.Ar size
|
.Ar size
|
||||||
@ -205,14 +208,18 @@ The format defined by the SNIA Common RAID Disk Data Format v2.0 specification.
|
|||||||
Used by some Adaptec RAID BIOSes and some hardware RAID controllers.
|
Used by some Adaptec RAID BIOSes and some hardware RAID controllers.
|
||||||
Because of high format flexibility different implementations support
|
Because of high format flexibility different implementations support
|
||||||
different set of features and have different on-disk metadata layouts.
|
different set of features and have different on-disk metadata layouts.
|
||||||
To provide compatibility, the GEOM RAID class mimics capabilities and
|
To provide compatibility, the GEOM RAID class mimics capabilities
|
||||||
metadata layout of the first detected DDF array.
|
of the first detected DDF array.
|
||||||
Respecting that, it may support different number of disks per volume,
|
Respecting that, it may support different number of disks per volume,
|
||||||
volumes per array, partitions per disk, etc.
|
volumes per array, partitions per disk, etc.
|
||||||
The following configurations are supported: RAID0 (2+ disks), RAID1 (2+ disks),
|
The following configurations are supported: RAID0 (2+ disks), RAID1 (2+ disks),
|
||||||
RAID1E (3+ disks), RAID3 (3+ disks), RAID4 (3+ disks), RAID5 (3+ disks),
|
RAID1E (3+ disks), RAID3 (3+ disks), RAID4 (3+ disks), RAID5 (3+ disks),
|
||||||
RAID5E (4+ disks), RAID5EE (4+ disks), RAID5R (3+ disks), RAID6 (4+ disks),
|
RAID5E (4+ disks), RAID5EE (4+ disks), RAID5R (3+ disks), RAID6 (4+ disks),
|
||||||
RAIDMDF (5+ disks), RAID10 (4+ disks), SINGLE (1 disk), CONCAT (2+ disks).
|
RAIDMDF (5+ disks), RAID10 (4+ disks), SINGLE (1 disk), CONCAT (2+ disks).
|
||||||
|
.Pp
|
||||||
|
Format supports two options "BE" and "LE", that mean big-endian byte order
|
||||||
|
defined by specification (default) and little-endian used by some Adaptec
|
||||||
|
controllers.
|
||||||
.It Intel
|
.It Intel
|
||||||
The format used by Intel RAID BIOS.
|
The format used by Intel RAID BIOS.
|
||||||
Supports up to two volumes per array.
|
Supports up to two volumes per array.
|
||||||
|
@ -2143,7 +2143,7 @@ g_raid_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name);
|
g_trace(G_T_TOPOLOGY, "%s(%s, %s)", __func__, mp->name, pp->name);
|
||||||
G_RAID_DEBUG(2, "Tasting provider %s.", pp->name);
|
G_RAID_DEBUG(2, "Tasting provider %s.", pp->name);
|
||||||
|
|
||||||
gp = g_new_geomf(mp, "mirror:taste");
|
gp = g_new_geomf(mp, "raid:taste");
|
||||||
/*
|
/*
|
||||||
* This orphan function should be never called.
|
* This orphan function should be never called.
|
||||||
*/
|
*/
|
||||||
@ -2173,7 +2173,8 @@ g_raid_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
g_raid_create_node_format(const char *format, struct g_geom **gp)
|
g_raid_create_node_format(const char *format, struct gctl_req *req,
|
||||||
|
struct g_geom **gp)
|
||||||
{
|
{
|
||||||
struct g_raid_md_class *class;
|
struct g_raid_md_class *class;
|
||||||
struct g_raid_md_object *obj;
|
struct g_raid_md_object *obj;
|
||||||
@ -2191,7 +2192,7 @@ g_raid_create_node_format(const char *format, struct g_geom **gp)
|
|||||||
obj = (void *)kobj_create((kobj_class_t)class, M_RAID,
|
obj = (void *)kobj_create((kobj_class_t)class, M_RAID,
|
||||||
M_WAITOK);
|
M_WAITOK);
|
||||||
obj->mdo_class = class;
|
obj->mdo_class = class;
|
||||||
status = G_RAID_MD_CREATE(obj, &g_raid_class, gp);
|
status = G_RAID_MD_CREATE_REQ(obj, &g_raid_class, req, gp);
|
||||||
if (status != G_RAID_MD_TASTE_NEW)
|
if (status != G_RAID_MD_TASTE_NEW)
|
||||||
kobj_delete((kobj_t)obj, M_RAID);
|
kobj_delete((kobj_t)obj, M_RAID);
|
||||||
return (status);
|
return (status);
|
||||||
|
@ -382,7 +382,8 @@ const char * g_raid_disk_state2str(int state);
|
|||||||
|
|
||||||
struct g_raid_softc * g_raid_create_node(struct g_class *mp,
|
struct g_raid_softc * g_raid_create_node(struct g_class *mp,
|
||||||
const char *name, struct g_raid_md_object *md);
|
const char *name, struct g_raid_md_object *md);
|
||||||
int g_raid_create_node_format(const char *format, struct g_geom **gp);
|
int g_raid_create_node_format(const char *format, struct gctl_req *req,
|
||||||
|
struct g_geom **gp);
|
||||||
struct g_raid_volume * g_raid_create_volume(struct g_raid_softc *sc,
|
struct g_raid_volume * g_raid_create_volume(struct g_raid_softc *sc,
|
||||||
const char *name, int id);
|
const char *name, int id);
|
||||||
struct g_raid_disk * g_raid_create_disk(struct g_raid_softc *sc);
|
struct g_raid_disk * g_raid_create_disk(struct g_raid_softc *sc);
|
||||||
|
@ -88,7 +88,7 @@ g_raid_ctl_label(struct gctl_req *req, struct g_class *mp)
|
|||||||
gctl_error(req, "No format recieved.");
|
gctl_error(req, "No format recieved.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
crstatus = g_raid_create_node_format(format, &geom);
|
crstatus = g_raid_create_node_format(format, req, &geom);
|
||||||
if (crstatus == G_RAID_MD_TASTE_FAIL) {
|
if (crstatus == G_RAID_MD_TASTE_FAIL) {
|
||||||
gctl_error(req, "Failed to create array with format '%s'.",
|
gctl_error(req, "Failed to create array with format '%s'.",
|
||||||
format);
|
format);
|
||||||
|
@ -49,12 +49,21 @@ HEADER {
|
|||||||
# Default implementations of methods.
|
# Default implementations of methods.
|
||||||
CODE {
|
CODE {
|
||||||
static int
|
static int
|
||||||
g_raid_md_create_default(struct g_raid_md_object *md)
|
g_raid_md_create_default(struct g_raid_md_object *md,
|
||||||
|
struct g_class *mp, struct g_geom **gp)
|
||||||
{
|
{
|
||||||
|
|
||||||
return (G_RAID_MD_TASTE_FAIL);
|
return (G_RAID_MD_TASTE_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
g_raid_md_create_req_default(struct g_raid_md_object *md,
|
||||||
|
struct g_class *mp, struct gctl_req *req, struct g_geom **gp)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (G_RAID_MD_CREATE(md, mp, gp));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
g_raid_md_ctl_default(struct g_raid_md_object *md,
|
g_raid_md_ctl_default(struct g_raid_md_object *md,
|
||||||
struct gctl_req *req)
|
struct gctl_req *req)
|
||||||
@ -95,6 +104,14 @@ METHOD int create {
|
|||||||
struct g_geom **gp;
|
struct g_geom **gp;
|
||||||
} DEFAULT g_raid_md_create_default;
|
} DEFAULT g_raid_md_create_default;
|
||||||
|
|
||||||
|
# create_req() - create new node from scratch, with request argument.
|
||||||
|
METHOD int create_req {
|
||||||
|
struct g_raid_md_object *md;
|
||||||
|
struct g_class *mp;
|
||||||
|
struct gctl_req *req;
|
||||||
|
struct g_geom **gp;
|
||||||
|
} DEFAULT g_raid_md_create_req_default;
|
||||||
|
|
||||||
# taste() - taste disk and, if needed, create new node.
|
# taste() - taste disk and, if needed, create new node.
|
||||||
METHOD int taste {
|
METHOD int taste {
|
||||||
struct g_raid_md_object *md;
|
struct g_raid_md_object *md;
|
||||||
|
@ -88,6 +88,7 @@ struct g_raid_md_ddf_pervolume {
|
|||||||
|
|
||||||
struct g_raid_md_ddf_object {
|
struct g_raid_md_ddf_object {
|
||||||
struct g_raid_md_object mdio_base;
|
struct g_raid_md_object mdio_base;
|
||||||
|
u_int mdio_bigendian;
|
||||||
struct ddf_meta mdio_meta;
|
struct ddf_meta mdio_meta;
|
||||||
int mdio_starting;
|
int mdio_starting;
|
||||||
struct callout mdio_start_co; /* STARTING state timer. */
|
struct callout mdio_start_co; /* STARTING state timer. */
|
||||||
@ -95,7 +96,7 @@ struct g_raid_md_ddf_object {
|
|||||||
struct root_hold_token *mdio_rootmount; /* Root mount delay token. */
|
struct root_hold_token *mdio_rootmount; /* Root mount delay token. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static g_raid_md_create_t g_raid_md_create_ddf;
|
static g_raid_md_create_req_t g_raid_md_create_req_ddf;
|
||||||
static g_raid_md_taste_t g_raid_md_taste_ddf;
|
static g_raid_md_taste_t g_raid_md_taste_ddf;
|
||||||
static g_raid_md_event_t g_raid_md_event_ddf;
|
static g_raid_md_event_t g_raid_md_event_ddf;
|
||||||
static g_raid_md_volume_event_t g_raid_md_volume_event_ddf;
|
static g_raid_md_volume_event_t g_raid_md_volume_event_ddf;
|
||||||
@ -107,7 +108,7 @@ static g_raid_md_free_volume_t g_raid_md_free_volume_ddf;
|
|||||||
static g_raid_md_free_t g_raid_md_free_ddf;
|
static g_raid_md_free_t g_raid_md_free_ddf;
|
||||||
|
|
||||||
static kobj_method_t g_raid_md_ddf_methods[] = {
|
static kobj_method_t g_raid_md_ddf_methods[] = {
|
||||||
KOBJMETHOD(g_raid_md_create, g_raid_md_create_ddf),
|
KOBJMETHOD(g_raid_md_create_req, g_raid_md_create_req_ddf),
|
||||||
KOBJMETHOD(g_raid_md_taste, g_raid_md_taste_ddf),
|
KOBJMETHOD(g_raid_md_taste, g_raid_md_taste_ddf),
|
||||||
KOBJMETHOD(g_raid_md_event, g_raid_md_event_ddf),
|
KOBJMETHOD(g_raid_md_event, g_raid_md_event_ddf),
|
||||||
KOBJMETHOD(g_raid_md_volume_event, g_raid_md_volume_event_ddf),
|
KOBJMETHOD(g_raid_md_volume_event, g_raid_md_volume_event_ddf),
|
||||||
@ -562,6 +563,7 @@ ddf_meta_create(struct g_raid_disk *disk, struct ddf_meta *sample)
|
|||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
struct clocktime ct;
|
struct clocktime ct;
|
||||||
struct g_raid_md_ddf_perdisk *pd;
|
struct g_raid_md_ddf_perdisk *pd;
|
||||||
|
struct g_raid_md_ddf_object *mdi;
|
||||||
struct ddf_meta *meta;
|
struct ddf_meta *meta;
|
||||||
struct ddf_pd_entry *pde;
|
struct ddf_pd_entry *pde;
|
||||||
off_t anchorlba;
|
off_t anchorlba;
|
||||||
@ -572,13 +574,14 @@ ddf_meta_create(struct g_raid_disk *disk, struct ddf_meta *sample)
|
|||||||
if (sample->hdr == NULL)
|
if (sample->hdr == NULL)
|
||||||
sample = NULL;
|
sample = NULL;
|
||||||
|
|
||||||
|
mdi = (struct g_raid_md_ddf_object *)disk->d_softc->sc_md;
|
||||||
pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
|
pd = (struct g_raid_md_ddf_perdisk *)disk->d_md_data;
|
||||||
meta = &pd->pd_meta;
|
meta = &pd->pd_meta;
|
||||||
ss = disk->d_consumer->provider->sectorsize;
|
ss = disk->d_consumer->provider->sectorsize;
|
||||||
anchorlba = disk->d_consumer->provider->mediasize / ss - 1;
|
anchorlba = disk->d_consumer->provider->mediasize / ss - 1;
|
||||||
|
|
||||||
meta->sectorsize = ss;
|
meta->sectorsize = ss;
|
||||||
meta->bigendian = sample ? sample->bigendian : 0;
|
meta->bigendian = sample ? sample->bigendian : mdi->mdio_bigendian;
|
||||||
getnanotime(&ts);
|
getnanotime(&ts);
|
||||||
clock_ts_to_ct(&ts, &ct);
|
clock_ts_to_ct(&ts, &ct);
|
||||||
|
|
||||||
@ -2012,11 +2015,26 @@ g_raid_md_ddf_new_disk(struct g_raid_disk *disk)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
g_raid_md_create_ddf(struct g_raid_md_object *md, struct g_class *mp,
|
g_raid_md_create_req_ddf(struct g_raid_md_object *md, struct g_class *mp,
|
||||||
struct g_geom **gp)
|
struct gctl_req *req, struct g_geom **gp)
|
||||||
{
|
{
|
||||||
struct g_geom *geom;
|
struct g_geom *geom;
|
||||||
struct g_raid_softc *sc;
|
struct g_raid_softc *sc;
|
||||||
|
struct g_raid_md_ddf_object *mdi, *mdi1;
|
||||||
|
char name[16];
|
||||||
|
const char *fmtopt;
|
||||||
|
int be = 1;
|
||||||
|
|
||||||
|
mdi = (struct g_raid_md_ddf_object *)md;
|
||||||
|
fmtopt = gctl_get_asciiparam(req, "fmtopt");
|
||||||
|
if (fmtopt == NULL || strcasecmp(fmtopt, "BE") == 0)
|
||||||
|
be = 1;
|
||||||
|
else if (strcasecmp(fmtopt, "LE") == 0)
|
||||||
|
be = 0;
|
||||||
|
else {
|
||||||
|
gctl_error(req, "Incorrect fmtopt argument.");
|
||||||
|
return (G_RAID_MD_TASTE_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Search for existing node. */
|
/* Search for existing node. */
|
||||||
LIST_FOREACH(geom, &mp->geom, geom) {
|
LIST_FOREACH(geom, &mp->geom, geom) {
|
||||||
@ -2027,6 +2045,9 @@ g_raid_md_create_ddf(struct g_raid_md_object *md, struct g_class *mp,
|
|||||||
continue;
|
continue;
|
||||||
if (sc->sc_md->mdo_class != md->mdo_class)
|
if (sc->sc_md->mdo_class != md->mdo_class)
|
||||||
continue;
|
continue;
|
||||||
|
mdi1 = (struct g_raid_md_ddf_object *)sc->sc_md;
|
||||||
|
if (mdi1->mdio_bigendian != be)
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (geom != NULL) {
|
if (geom != NULL) {
|
||||||
@ -2035,7 +2056,9 @@ g_raid_md_create_ddf(struct g_raid_md_object *md, struct g_class *mp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create new one if not found. */
|
/* Create new one if not found. */
|
||||||
sc = g_raid_create_node(mp, "DDF", md);
|
mdi->mdio_bigendian = be;
|
||||||
|
snprintf(name, sizeof(name), "DDF%s", be ? "" : "-LE");
|
||||||
|
sc = g_raid_create_node(mp, name, md);
|
||||||
if (sc == NULL)
|
if (sc == NULL)
|
||||||
return (G_RAID_MD_TASTE_FAIL);
|
return (G_RAID_MD_TASTE_FAIL);
|
||||||
md->mdo_softc = sc;
|
md->mdo_softc = sc;
|
||||||
@ -2053,11 +2076,13 @@ g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp,
|
|||||||
struct g_raid_disk *disk;
|
struct g_raid_disk *disk;
|
||||||
struct ddf_meta meta;
|
struct ddf_meta meta;
|
||||||
struct g_raid_md_ddf_perdisk *pd;
|
struct g_raid_md_ddf_perdisk *pd;
|
||||||
|
struct g_raid_md_ddf_object *mdi;
|
||||||
struct g_geom *geom;
|
struct g_geom *geom;
|
||||||
int error, result, len;
|
int error, result, len, be;
|
||||||
char name[16];
|
char name[16];
|
||||||
|
|
||||||
G_RAID_DEBUG(1, "Tasting DDF on %s", cp->provider->name);
|
G_RAID_DEBUG(1, "Tasting DDF on %s", cp->provider->name);
|
||||||
|
mdi = (struct g_raid_md_ddf_object *)md;
|
||||||
pp = cp->provider;
|
pp = cp->provider;
|
||||||
|
|
||||||
/* Read metadata from device. */
|
/* Read metadata from device. */
|
||||||
@ -2070,6 +2095,7 @@ g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp,
|
|||||||
g_access(cp, -1, 0, 0);
|
g_access(cp, -1, 0, 0);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (G_RAID_MD_TASTE_FAIL);
|
return (G_RAID_MD_TASTE_FAIL);
|
||||||
|
be = meta.bigendian;
|
||||||
|
|
||||||
/* Metadata valid. Print it. */
|
/* Metadata valid. Print it. */
|
||||||
g_raid_md_ddf_print(&meta);
|
g_raid_md_ddf_print(&meta);
|
||||||
@ -2084,6 +2110,9 @@ g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp,
|
|||||||
continue;
|
continue;
|
||||||
if (sc->sc_md->mdo_class != md->mdo_class)
|
if (sc->sc_md->mdo_class != md->mdo_class)
|
||||||
continue;
|
continue;
|
||||||
|
mdi = (struct g_raid_md_ddf_object *)sc->sc_md;
|
||||||
|
if (mdi->mdio_bigendian != be)
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2094,7 +2123,8 @@ g_raid_md_taste_ddf(struct g_raid_md_object *md, struct g_class *mp,
|
|||||||
|
|
||||||
} else { /* Not found matching node -- create one. */
|
} else { /* Not found matching node -- create one. */
|
||||||
result = G_RAID_MD_TASTE_NEW;
|
result = G_RAID_MD_TASTE_NEW;
|
||||||
snprintf(name, sizeof(name), "DDF");
|
mdi->mdio_bigendian = be;
|
||||||
|
snprintf(name, sizeof(name), "DDF%s", be ? "" : "-LE");
|
||||||
sc = g_raid_create_node(mp, name, md);
|
sc = g_raid_create_node(mp, name, md);
|
||||||
md->mdo_softc = sc;
|
md->mdo_softc = sc;
|
||||||
geom = sc->sc_geom;
|
geom = sc->sc_geom;
|
||||||
|
Loading…
Reference in New Issue
Block a user