- Introduce option for hardcoding providers' names into metadata.
It allows to fix problems when last provider's sector is shared between few providers. - Bump version number for CONCAT and STRIPE and add code for backward compatibility. - Do not bump version number of MIRROR, as it wasn't officially introduced yet. Even if someone started to play with it, there is no big deal, because wrong MD5 sum of metadata will deny those providers. - Update manual pages. - Add version history to g_(stripe|concat).h files.
This commit is contained in:
parent
d2df8e85e9
commit
6c74f5177c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=133373
@ -35,35 +35,35 @@
|
|||||||
.Cm create
|
.Cm create
|
||||||
.Op Fl v
|
.Op Fl v
|
||||||
.Ar name
|
.Ar name
|
||||||
.Ar dev1
|
.Ar prov
|
||||||
.Ar dev2
|
.Ar prov
|
||||||
.Op Ar dev3 Op Ar ...
|
.Op Ar prov Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm destroy
|
.Cm destroy
|
||||||
.Op Fl fv
|
.Op Fl fv
|
||||||
.Ar name
|
.Ar name
|
||||||
.Op Ar name2 Op Ar ...
|
.Op Ar name Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm label
|
.Cm label
|
||||||
.Op Fl v
|
.Op Fl hv
|
||||||
.Ar name
|
.Ar name
|
||||||
.Ar dev1
|
.Ar prov
|
||||||
.Ar dev2
|
.Ar prov
|
||||||
.Op Ar dev3 Op Ar ...
|
.Op Ar prov Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm stop
|
.Cm stop
|
||||||
.Op Fl fv
|
.Op Fl fv
|
||||||
.Ar name
|
.Ar name
|
||||||
.Op Ar name2 Op Ar ...
|
.Op Ar name Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm clear
|
.Cm clear
|
||||||
.Op Fl v
|
.Op Fl v
|
||||||
.Ar dev1
|
.Ar prov
|
||||||
.Op Ar dev2 Op Ar ...
|
.Op Ar prov Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm dump
|
.Cm dump
|
||||||
.Ar dev1
|
.Ar prov
|
||||||
.Op Ar dev2 Op Ar ...
|
.Op Ar prov Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm list
|
.Cm list
|
||||||
.Op Ar name Op Ar ...
|
.Op Ar name Op Ar ...
|
||||||
@ -140,6 +140,8 @@ Additional options:
|
|||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl f
|
.It Fl f
|
||||||
Force the removal of the specified concatenated device.
|
Force the removal of the specified concatenated device.
|
||||||
|
.It Fl h
|
||||||
|
Hardcode providers' names in metadata.
|
||||||
.It Fl v
|
.It Fl v
|
||||||
Be more verbose.
|
Be more verbose.
|
||||||
.El
|
.El
|
||||||
|
@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <paths.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -59,7 +60,12 @@ struct g_command class_commands[] = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ "dump", 0, concat_main, G_NULL_OPTS },
|
{ "dump", 0, concat_main, G_NULL_OPTS },
|
||||||
{ "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, concat_main, G_NULL_OPTS },
|
{ "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, concat_main,
|
||||||
|
{
|
||||||
|
{ 'h', "hardcode", NULL, G_TYPE_NONE },
|
||||||
|
G_OPT_SENTINEL
|
||||||
|
}
|
||||||
|
},
|
||||||
{ "stop", G_FLAG_VERBOSE, NULL,
|
{ "stop", G_FLAG_VERBOSE, NULL,
|
||||||
{
|
{
|
||||||
{ 'f', "force", NULL, G_TYPE_NONE },
|
{ 'f', "force", NULL, G_TYPE_NONE },
|
||||||
@ -77,12 +83,12 @@ void
|
|||||||
usage(const char *name)
|
usage(const char *name)
|
||||||
{
|
{
|
||||||
|
|
||||||
fprintf(stderr, "usage: %s create [-v] <name> <dev1> <dev2> [dev3 [...]]\n", name);
|
fprintf(stderr, "usage: %s create [-v] <name> <prov> <prov> [prov [...]]\n", name);
|
||||||
fprintf(stderr, " %s destroy [-fv] <name> [name2 [...]]\n", name);
|
fprintf(stderr, " %s destroy [-fv] <name> [name [...]]\n", name);
|
||||||
fprintf(stderr, " %s label [-v] <name> <dev1> <dev2> [dev3 [...]]\n", name);
|
fprintf(stderr, " %s label [-hv] <name> <prov> <prov> [prov [...]]\n", name);
|
||||||
fprintf(stderr, " %s stop [-fv] <name> [name2 [...]]\n", name);
|
fprintf(stderr, " %s stop [-fv] <name> [name [...]]\n", name);
|
||||||
fprintf(stderr, " %s clear [-v] <dev1> [dev2 [...]]\n", name);
|
fprintf(stderr, " %s clear [-v] <prov> [prov [...]]\n", name);
|
||||||
fprintf(stderr, " %s dump <dev1> [dev2 [...]]\n", name);
|
fprintf(stderr, " %s dump <prov> [prov [...]]\n", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -116,7 +122,7 @@ concat_label(struct gctl_req *req)
|
|||||||
const char *name;
|
const char *name;
|
||||||
char param[16];
|
char param[16];
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int *nargs, error;
|
int *hardcode, *nargs, error;
|
||||||
|
|
||||||
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
|
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
|
||||||
if (nargs == NULL) {
|
if (nargs == NULL) {
|
||||||
@ -127,6 +133,11 @@ concat_label(struct gctl_req *req)
|
|||||||
gctl_error(req, "Too few arguments.");
|
gctl_error(req, "Too few arguments.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode));
|
||||||
|
if (hardcode == NULL) {
|
||||||
|
gctl_error(req, "No '%s' argument.", "hardcode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear last sector first to spoil all components if device exists.
|
* Clear last sector first to spoil all components if device exists.
|
||||||
@ -162,6 +173,13 @@ concat_label(struct gctl_req *req)
|
|||||||
name = gctl_get_asciiparam(req, param);
|
name = gctl_get_asciiparam(req, param);
|
||||||
|
|
||||||
md.md_no = i - 1;
|
md.md_no = i - 1;
|
||||||
|
if (!*hardcode)
|
||||||
|
bzero(md.md_provider, sizeof(md.md_provider));
|
||||||
|
else {
|
||||||
|
if (strncmp(name, _PATH_DEV, strlen(_PATH_DEV)) == 0)
|
||||||
|
name += strlen(_PATH_DEV);
|
||||||
|
strlcpy(md.md_provider, name, sizeof(md.md_provider));
|
||||||
|
}
|
||||||
concat_metadata_encode(&md, sector);
|
concat_metadata_encode(&md, sector);
|
||||||
error = g_metadata_store(name, sector, sizeof(sector));
|
error = g_metadata_store(name, sector, sizeof(sector));
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
@ -219,6 +237,7 @@ concat_metadata_dump(const struct g_concat_metadata *md)
|
|||||||
printf(" Device ID: %u\n", (u_int)md->md_id);
|
printf(" Device ID: %u\n", (u_int)md->md_id);
|
||||||
printf(" Disk number: %u\n", (u_int)md->md_no);
|
printf(" Disk number: %u\n", (u_int)md->md_no);
|
||||||
printf("Total number of disks: %u\n", (u_int)md->md_all);
|
printf("Total number of disks: %u\n", (u_int)md->md_all);
|
||||||
|
printf(" Hardcoded provider: %s\n", md->md_provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <paths.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -69,6 +70,7 @@ struct g_command class_commands[] = {
|
|||||||
{ "dump", 0, stripe_main, G_NULL_OPTS },
|
{ "dump", 0, stripe_main, G_NULL_OPTS },
|
||||||
{ "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, stripe_main,
|
{ "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, stripe_main,
|
||||||
{
|
{
|
||||||
|
{ 'h', "hardcode", NULL, G_TYPE_NONE },
|
||||||
{ 's', "stripesize", &stripesize, G_TYPE_NUMBER },
|
{ 's', "stripesize", &stripesize, G_TYPE_NUMBER },
|
||||||
G_OPT_SENTINEL
|
G_OPT_SENTINEL
|
||||||
}
|
}
|
||||||
@ -89,12 +91,12 @@ void
|
|||||||
usage(const char *name)
|
usage(const char *name)
|
||||||
{
|
{
|
||||||
|
|
||||||
fprintf(stderr, "usage: %s create [-v] [-s stripesize] <name> <dev1> <dev2> [dev3 [...]]\n", name);
|
fprintf(stderr, "usage: %s create [-hv] [-s stripesize] <name> <prov> <prov> [prov [...]]\n", name);
|
||||||
fprintf(stderr, " %s destroy [-fv] <name> [name2 [...]]\n", name);
|
fprintf(stderr, " %s destroy [-fv] <name> [name [...]]\n", name);
|
||||||
fprintf(stderr, " %s label [-v] [-s stripesize] <name> <dev1> <dev2> [dev3 [...]]\n", name);
|
fprintf(stderr, " %s label [-hv] [-s stripesize] <name> <prov> <prov> [prov [...]]\n", name);
|
||||||
fprintf(stderr, " %s stop [-fv] <name> [name2 [...]]\n", name);
|
fprintf(stderr, " %s stop [-fv] <name> [name [...]]\n", name);
|
||||||
fprintf(stderr, " %s clear [-v] <dev1> [dev2 [...]]\n", name);
|
fprintf(stderr, " %s clear [-v] <prov> [prov [...]]\n", name);
|
||||||
fprintf(stderr, " %s dump <dev1> [dev2 [...]]\n", name);
|
fprintf(stderr, " %s dump <prov> [prov [...]]\n", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -129,7 +131,7 @@ stripe_label(struct gctl_req *req)
|
|||||||
const char *name;
|
const char *name;
|
||||||
char param[16];
|
char param[16];
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int *nargs, error;
|
int *hardcode, *nargs, error;
|
||||||
|
|
||||||
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
|
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
|
||||||
if (nargs == NULL) {
|
if (nargs == NULL) {
|
||||||
@ -140,6 +142,11 @@ stripe_label(struct gctl_req *req)
|
|||||||
gctl_error(req, "Too few arguments.");
|
gctl_error(req, "Too few arguments.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode));
|
||||||
|
if (hardcode == NULL) {
|
||||||
|
gctl_error(req, "No '%s' argument.", "hardcode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear last sector first to spoil all components if device exists.
|
* Clear last sector first to spoil all components if device exists.
|
||||||
@ -181,6 +188,13 @@ stripe_label(struct gctl_req *req)
|
|||||||
name = gctl_get_asciiparam(req, param);
|
name = gctl_get_asciiparam(req, param);
|
||||||
|
|
||||||
md.md_no = i - 1;
|
md.md_no = i - 1;
|
||||||
|
if (!*hardcode)
|
||||||
|
bzero(md.md_provider, sizeof(md.md_provider));
|
||||||
|
else {
|
||||||
|
if (strncmp(name, _PATH_DEV, strlen(_PATH_DEV)) == 0)
|
||||||
|
name += strlen(_PATH_DEV);
|
||||||
|
strlcpy(md.md_provider, name, sizeof(md.md_provider));
|
||||||
|
}
|
||||||
stripe_metadata_encode(&md, sector);
|
stripe_metadata_encode(&md, sector);
|
||||||
error = g_metadata_store(name, sector, sizeof(sector));
|
error = g_metadata_store(name, sector, sizeof(sector));
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
@ -239,6 +253,7 @@ stripe_metadata_dump(const struct g_stripe_metadata *md)
|
|||||||
printf(" Disk number: %u\n", (u_int)md->md_no);
|
printf(" Disk number: %u\n", (u_int)md->md_no);
|
||||||
printf("Total number of disks: %u\n", (u_int)md->md_all);
|
printf("Total number of disks: %u\n", (u_int)md->md_all);
|
||||||
printf(" Stripe size: %u\n", (u_int)md->md_stripesize);
|
printf(" Stripe size: %u\n", (u_int)md->md_stripesize);
|
||||||
|
printf(" Hardcoded provider: %s\n", md->md_provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -36,36 +36,36 @@
|
|||||||
.Op Fl v
|
.Op Fl v
|
||||||
.Op Fl s Ar stripesize
|
.Op Fl s Ar stripesize
|
||||||
.Ar name
|
.Ar name
|
||||||
.Ar dev1
|
.Ar prov
|
||||||
.Ar dev2
|
.Ar prov
|
||||||
.Op Ar dev3 Op Ar ...
|
.Op Ar prov Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm destroy
|
.Cm destroy
|
||||||
.Op Fl fv
|
.Op Fl fv
|
||||||
.Ar name
|
.Ar name
|
||||||
.Op Ar name2 Op Ar ...
|
.Op Ar name Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm label
|
.Cm label
|
||||||
.Op Fl v
|
.Op Fl hv
|
||||||
.Op Fl s Ar stripesize
|
.Op Fl s Ar stripesize
|
||||||
.Ar name
|
.Ar name
|
||||||
.Ar dev1
|
.Ar prov
|
||||||
.Ar dev2
|
.Ar prov
|
||||||
.Op Ar dev3 Op Ar ...
|
.Op Ar prov Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm stop
|
.Cm stop
|
||||||
.Op Fl fv
|
.Op Fl fv
|
||||||
.Ar name
|
.Ar name
|
||||||
.Op Ar name2 Op Ar ...
|
.Op Ar name Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm clear
|
.Cm clear
|
||||||
.Op Fl v
|
.Op Fl v
|
||||||
.Ar dev1
|
.Ar prov
|
||||||
.Op Ar dev2 Op Ar ...
|
.Op Ar prov Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm dump
|
.Cm dump
|
||||||
.Ar dev1
|
.Ar prov
|
||||||
.Op Ar dev2 Op Ar ...
|
.Op Ar prov Op Ar ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm list
|
.Cm list
|
||||||
.Op Ar name Op Ar ...
|
.Op Ar name Op Ar ...
|
||||||
@ -142,6 +142,8 @@ Additional options:
|
|||||||
.Bl -tag -width ".Fl s Ar stripesize"
|
.Bl -tag -width ".Fl s Ar stripesize"
|
||||||
.It Fl f
|
.It Fl f
|
||||||
Force the removal of the specified striped device.
|
Force the removal of the specified striped device.
|
||||||
|
.It Fl h
|
||||||
|
Hardcode providers' names in metadata.
|
||||||
.It Fl s Ar stripesize
|
.It Fl s Ar stripesize
|
||||||
Specifies size of stripe block.
|
Specifies size of stripe block.
|
||||||
.It Fl v
|
.It Fl v
|
||||||
|
@ -567,6 +567,15 @@ g_concat_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
pp->name);
|
pp->name);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Backward compatibility:
|
||||||
|
* There was no md_provider field in earlier versions of metadata.
|
||||||
|
*/
|
||||||
|
if (md.md_version < 3)
|
||||||
|
bzero(md.md_provider, sizeof(md.md_provider));
|
||||||
|
|
||||||
|
if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Let's check if device already exists.
|
* Let's check if device already exists.
|
||||||
@ -650,6 +659,7 @@ g_concat_ctl_create(struct gctl_req *req, struct g_class *mp)
|
|||||||
md.md_id = arc4random();
|
md.md_id = arc4random();
|
||||||
md.md_no = 0;
|
md.md_no = 0;
|
||||||
md.md_all = *nargs - 1;
|
md.md_all = *nargs - 1;
|
||||||
|
bzero(md.md_provider, sizeof(md.md_provider));
|
||||||
|
|
||||||
/* Check all providers are valid */
|
/* Check all providers are valid */
|
||||||
for (no = 1; no < *nargs; no++) {
|
for (no = 1; no < *nargs; no++) {
|
||||||
|
@ -34,7 +34,13 @@
|
|||||||
#define G_CONCAT_CLASS_NAME "CONCAT"
|
#define G_CONCAT_CLASS_NAME "CONCAT"
|
||||||
|
|
||||||
#define G_CONCAT_MAGIC "GEOM::CONCAT"
|
#define G_CONCAT_MAGIC "GEOM::CONCAT"
|
||||||
#define G_CONCAT_VERSION 2
|
/*
|
||||||
|
* Version history:
|
||||||
|
* 1 - Initial version number.
|
||||||
|
* 2 - Added 'stop' command to gconcat(8).
|
||||||
|
* 3 - Added md_provider field to metadata and '-h' option to gconcat(8).
|
||||||
|
*/
|
||||||
|
#define G_CONCAT_VERSION 3
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
#define G_CONCAT_TYPE_MANUAL 0
|
#define G_CONCAT_TYPE_MANUAL 0
|
||||||
@ -86,6 +92,7 @@ struct g_concat_metadata {
|
|||||||
uint32_t md_id; /* Unique ID. */
|
uint32_t md_id; /* Unique ID. */
|
||||||
uint16_t md_no; /* Disk number. */
|
uint16_t md_no; /* Disk number. */
|
||||||
uint16_t md_all; /* Number of all disks. */
|
uint16_t md_all; /* Number of all disks. */
|
||||||
|
char md_provider[16]; /* Hardcoded provider. */
|
||||||
};
|
};
|
||||||
static __inline void
|
static __inline void
|
||||||
concat_metadata_encode(const struct g_concat_metadata *md, u_char *data)
|
concat_metadata_encode(const struct g_concat_metadata *md, u_char *data)
|
||||||
@ -97,6 +104,7 @@ concat_metadata_encode(const struct g_concat_metadata *md, u_char *data)
|
|||||||
le32enc(data + 36, md->md_id);
|
le32enc(data + 36, md->md_id);
|
||||||
le16enc(data + 40, md->md_no);
|
le16enc(data + 40, md->md_no);
|
||||||
le16enc(data + 42, md->md_all);
|
le16enc(data + 42, md->md_all);
|
||||||
|
bcopy(md->md_provider, data + 44, sizeof(md->md_provider));
|
||||||
}
|
}
|
||||||
static __inline void
|
static __inline void
|
||||||
concat_metadata_decode(const u_char *data, struct g_concat_metadata *md)
|
concat_metadata_decode(const u_char *data, struct g_concat_metadata *md)
|
||||||
@ -108,5 +116,6 @@ concat_metadata_decode(const u_char *data, struct g_concat_metadata *md)
|
|||||||
md->md_id = le32dec(data + 36);
|
md->md_id = le32dec(data + 36);
|
||||||
md->md_no = le16dec(data + 40);
|
md->md_no = le16dec(data + 40);
|
||||||
md->md_all = le16dec(data + 42);
|
md->md_all = le16dec(data + 42);
|
||||||
|
bcopy(data + 44, md->md_provider, sizeof(md->md_provider));
|
||||||
}
|
}
|
||||||
#endif /* _G_CONCAT_H_ */
|
#endif /* _G_CONCAT_H_ */
|
||||||
|
@ -382,6 +382,8 @@ g_mirror_init_disk(struct g_mirror_softc *sc, struct g_provider *pp,
|
|||||||
disk->d_delay.frac = 0;
|
disk->d_delay.frac = 0;
|
||||||
binuptime(&disk->d_last_used);
|
binuptime(&disk->d_last_used);
|
||||||
disk->d_flags = md->md_dflags;
|
disk->d_flags = md->md_dflags;
|
||||||
|
if (md->md_provider[0] != '\0')
|
||||||
|
disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED;
|
||||||
disk->d_sync.ds_consumer = NULL;
|
disk->d_sync.ds_consumer = NULL;
|
||||||
disk->d_sync.ds_offset = md->md_sync_offset;
|
disk->d_sync.ds_offset = md->md_sync_offset;
|
||||||
disk->d_sync.ds_offset_done = md->md_sync_offset;
|
disk->d_sync.ds_offset_done = md->md_sync_offset;
|
||||||
@ -621,6 +623,7 @@ g_mirror_fill_metadata(struct g_mirror_softc *sc, struct g_mirror_disk *disk,
|
|||||||
md->md_mediasize = sc->sc_mediasize;
|
md->md_mediasize = sc->sc_mediasize;
|
||||||
md->md_sectorsize = sc->sc_sectorsize;
|
md->md_sectorsize = sc->sc_sectorsize;
|
||||||
md->md_mflags = (sc->sc_flags & G_MIRROR_DEVICE_FLAG_MASK);
|
md->md_mflags = (sc->sc_flags & G_MIRROR_DEVICE_FLAG_MASK);
|
||||||
|
bzero(md->md_provider, sizeof(md->md_provider));
|
||||||
if (disk == NULL) {
|
if (disk == NULL) {
|
||||||
md->md_did = arc4random();
|
md->md_did = arc4random();
|
||||||
md->md_priority = 0;
|
md->md_priority = 0;
|
||||||
@ -636,6 +639,11 @@ g_mirror_fill_metadata(struct g_mirror_softc *sc, struct g_mirror_disk *disk,
|
|||||||
md->md_sync_offset = disk->d_sync.ds_offset_done;
|
md->md_sync_offset = disk->d_sync.ds_offset_done;
|
||||||
else
|
else
|
||||||
md->md_sync_offset = 0;
|
md->md_sync_offset = 0;
|
||||||
|
if ((disk->d_flags & G_MIRROR_DISK_FLAG_HARDCODED) != 0) {
|
||||||
|
strlcpy(md->md_provider,
|
||||||
|
disk->d_consumer->provider->name,
|
||||||
|
sizeof(md->md_provider));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2491,6 +2499,8 @@ g_mirror_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
pp->name);
|
pp->name);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0)
|
||||||
|
return (NULL);
|
||||||
if ((md.md_dflags & G_MIRROR_DISK_FLAG_INACTIVE) != 0) {
|
if ((md.md_dflags & G_MIRROR_DISK_FLAG_INACTIVE) != 0) {
|
||||||
G_MIRROR_DEBUG(0,
|
G_MIRROR_DEBUG(0,
|
||||||
"Device %s: provider %s marked as inactive, skipping.",
|
"Device %s: provider %s marked as inactive, skipping.",
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#define G_MIRROR_DISK_FLAG_SYNCHRONIZING 0x0000000000000002ULL
|
#define G_MIRROR_DISK_FLAG_SYNCHRONIZING 0x0000000000000002ULL
|
||||||
#define G_MIRROR_DISK_FLAG_FORCE_SYNC 0x0000000000000004ULL
|
#define G_MIRROR_DISK_FLAG_FORCE_SYNC 0x0000000000000004ULL
|
||||||
#define G_MIRROR_DISK_FLAG_INACTIVE 0x0000000000000008ULL
|
#define G_MIRROR_DISK_FLAG_INACTIVE 0x0000000000000008ULL
|
||||||
|
#define G_MIRROR_DISK_FLAG_HARDCODED 0x0000000000000010ULL
|
||||||
#define G_MIRROR_DISK_FLAG_MASK (G_MIRROR_DISK_FLAG_DIRTY | \
|
#define G_MIRROR_DISK_FLAG_MASK (G_MIRROR_DISK_FLAG_DIRTY | \
|
||||||
G_MIRROR_DISK_FLAG_SYNCHRONIZING | \
|
G_MIRROR_DISK_FLAG_SYNCHRONIZING | \
|
||||||
G_MIRROR_DISK_FLAG_FORCE_SYNC | \
|
G_MIRROR_DISK_FLAG_FORCE_SYNC | \
|
||||||
@ -210,6 +211,7 @@ struct g_mirror_metadata {
|
|||||||
uint64_t md_sync_offset; /* Synchronized offset. */
|
uint64_t md_sync_offset; /* Synchronized offset. */
|
||||||
uint64_t md_mflags; /* Additional mirror flags. */
|
uint64_t md_mflags; /* Additional mirror flags. */
|
||||||
uint64_t md_dflags; /* Additional disk flags. */
|
uint64_t md_dflags; /* Additional disk flags. */
|
||||||
|
char md_provider[16]; /* Hardcoded provider. */
|
||||||
u_char md_hash[16]; /* MD5 hash. */
|
u_char md_hash[16]; /* MD5 hash. */
|
||||||
};
|
};
|
||||||
static __inline void
|
static __inline void
|
||||||
@ -232,10 +234,11 @@ mirror_metadata_encode(struct g_mirror_metadata *md, u_char *data)
|
|||||||
le64enc(data + 67, md->md_sync_offset);
|
le64enc(data + 67, md->md_sync_offset);
|
||||||
le64enc(data + 75, md->md_mflags);
|
le64enc(data + 75, md->md_mflags);
|
||||||
le64enc(data + 83, md->md_dflags);
|
le64enc(data + 83, md->md_dflags);
|
||||||
|
bcopy(md->md_provider, data + 91, 16);
|
||||||
MD5Init(&ctx);
|
MD5Init(&ctx);
|
||||||
MD5Update(&ctx, data, 91);
|
MD5Update(&ctx, data, 107);
|
||||||
MD5Final(md->md_hash, &ctx);
|
MD5Final(md->md_hash, &ctx);
|
||||||
bcopy(md->md_hash, data + 91, 16);
|
bcopy(md->md_hash, data + 107, 16);
|
||||||
}
|
}
|
||||||
static __inline int
|
static __inline int
|
||||||
mirror_metadata_decode(const u_char *data, struct g_mirror_metadata *md)
|
mirror_metadata_decode(const u_char *data, struct g_mirror_metadata *md)
|
||||||
@ -257,11 +260,12 @@ mirror_metadata_decode(const u_char *data, struct g_mirror_metadata *md)
|
|||||||
md->md_sync_offset = le64dec(data + 67);
|
md->md_sync_offset = le64dec(data + 67);
|
||||||
md->md_mflags = le64dec(data + 75);
|
md->md_mflags = le64dec(data + 75);
|
||||||
md->md_dflags = le64dec(data + 83);
|
md->md_dflags = le64dec(data + 83);
|
||||||
bcopy(data + 91, md->md_hash, 16);
|
bcopy(data + 91, md->md_provider, 16);
|
||||||
|
bcopy(data + 107, md->md_hash, 16);
|
||||||
MD5Init(&ctx);
|
MD5Init(&ctx);
|
||||||
MD5Update(&ctx, data, 91);
|
MD5Update(&ctx, data, 107);
|
||||||
MD5Final(md->md_hash, &ctx);
|
MD5Final(md->md_hash, &ctx);
|
||||||
if (bcmp(md->md_hash, data + 91, 16) != 0)
|
if (bcmp(md->md_hash, data + 107, 16) != 0)
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -345,6 +349,7 @@ mirror_metadata_dump(const struct g_mirror_metadata *md)
|
|||||||
printf(" INACTIVE");
|
printf(" INACTIVE");
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
printf("hcprovider: %s\n", md->md_provider);
|
||||||
bzero(hash, sizeof(hash));
|
bzero(hash, sizeof(hash));
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
hash[i * 2] = hex[md->md_hash[i] >> 4];
|
hash[i * 2] = hex[md->md_hash[i] >> 4];
|
||||||
|
@ -898,6 +898,15 @@ g_stripe_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
|||||||
pp->name);
|
pp->name);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Backward compatibility:
|
||||||
|
* There was no md_provider field in earlier versions of metadata.
|
||||||
|
*/
|
||||||
|
if (md.md_version < 2)
|
||||||
|
bzero(md.md_provider, sizeof(md.md_provider));
|
||||||
|
|
||||||
|
if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Let's check if device already exists.
|
* Let's check if device already exists.
|
||||||
@ -988,6 +997,7 @@ g_stripe_ctl_create(struct gctl_req *req, struct g_class *mp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
md.md_stripesize = *stripesize;
|
md.md_stripesize = *stripesize;
|
||||||
|
bzero(md.md_provider, sizeof(md.md_provider));
|
||||||
|
|
||||||
/* Check all providers are valid */
|
/* Check all providers are valid */
|
||||||
for (no = 1; no < *nargs; no++) {
|
for (no = 1; no < *nargs; no++) {
|
||||||
|
@ -34,7 +34,13 @@
|
|||||||
#define G_STRIPE_CLASS_NAME "STRIPE"
|
#define G_STRIPE_CLASS_NAME "STRIPE"
|
||||||
|
|
||||||
#define G_STRIPE_MAGIC "GEOM::STRIPE"
|
#define G_STRIPE_MAGIC "GEOM::STRIPE"
|
||||||
#define G_STRIPE_VERSION 1
|
/*
|
||||||
|
* Version history:
|
||||||
|
* 0 - Initial version number.
|
||||||
|
* 1 - Added 'stop' command for gstripe(8).
|
||||||
|
* 2 - Added md_provider field to metadata and '-h' option for gstripe(8).
|
||||||
|
*/
|
||||||
|
#define G_STRIPE_VERSION 2
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
#define G_STRIPE_TYPE_MANUAL 0
|
#define G_STRIPE_TYPE_MANUAL 0
|
||||||
@ -81,6 +87,7 @@ struct g_stripe_metadata {
|
|||||||
uint16_t md_no; /* Disk number. */
|
uint16_t md_no; /* Disk number. */
|
||||||
uint16_t md_all; /* Number of all disks. */
|
uint16_t md_all; /* Number of all disks. */
|
||||||
uint32_t md_stripesize; /* Stripe size. */
|
uint32_t md_stripesize; /* Stripe size. */
|
||||||
|
char md_provider[16]; /* Hardcoded provider. */
|
||||||
};
|
};
|
||||||
static __inline void
|
static __inline void
|
||||||
stripe_metadata_encode(const struct g_stripe_metadata *md, u_char *data)
|
stripe_metadata_encode(const struct g_stripe_metadata *md, u_char *data)
|
||||||
@ -93,6 +100,7 @@ stripe_metadata_encode(const struct g_stripe_metadata *md, u_char *data)
|
|||||||
le16enc(data + 40, md->md_no);
|
le16enc(data + 40, md->md_no);
|
||||||
le16enc(data + 42, md->md_all);
|
le16enc(data + 42, md->md_all);
|
||||||
le32enc(data + 44, md->md_stripesize);
|
le32enc(data + 44, md->md_stripesize);
|
||||||
|
bcopy(md->md_provider, data + 48, sizeof(md->md_provider));
|
||||||
}
|
}
|
||||||
static __inline void
|
static __inline void
|
||||||
stripe_metadata_decode(const u_char *data, struct g_stripe_metadata *md)
|
stripe_metadata_decode(const u_char *data, struct g_stripe_metadata *md)
|
||||||
@ -105,6 +113,7 @@ stripe_metadata_decode(const u_char *data, struct g_stripe_metadata *md)
|
|||||||
md->md_no = le16dec(data + 40);
|
md->md_no = le16dec(data + 40);
|
||||||
md->md_all = le16dec(data + 42);
|
md->md_all = le16dec(data + 42);
|
||||||
md->md_stripesize = le32dec(data + 44);
|
md->md_stripesize = le32dec(data + 44);
|
||||||
|
bcopy(data + 48, md->md_provider, sizeof(md->md_provider));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef BITCOUNT
|
#ifndef BITCOUNT
|
||||||
|
Loading…
Reference in New Issue
Block a user