Forgot to commit those: introduce hardcoded provider functionality,
which allow to store provider's name in the metadata and avoid problems when few providers share the same last sector.
This commit is contained in:
parent
03e62bf373
commit
c38d2f4eca
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=133447
@ -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>
|
||||||
@ -48,7 +49,7 @@ static char label_balance[] = "split", configure_balance[] = "none";
|
|||||||
static intmax_t label_slice = 4096, configure_slice = -1;
|
static intmax_t label_slice = 4096, configure_slice = -1;
|
||||||
static intmax_t insert_priority = 0;
|
static intmax_t insert_priority = 0;
|
||||||
|
|
||||||
static void mirror_main(struct gctl_req *req, unsigned f);
|
static void mirror_main(struct gctl_req *req, unsigned flags);
|
||||||
static void mirror_activate(struct gctl_req *req);
|
static void mirror_activate(struct gctl_req *req);
|
||||||
static void mirror_clear(struct gctl_req *req);
|
static void mirror_clear(struct gctl_req *req);
|
||||||
static void mirror_dump(struct gctl_req *req);
|
static void mirror_dump(struct gctl_req *req);
|
||||||
@ -61,6 +62,8 @@ struct g_command class_commands[] = {
|
|||||||
{
|
{
|
||||||
{ 'a', "autosync", NULL, G_TYPE_NONE },
|
{ 'a', "autosync", NULL, G_TYPE_NONE },
|
||||||
{ 'b', "balance", configure_balance, G_TYPE_STRING },
|
{ 'b', "balance", configure_balance, G_TYPE_STRING },
|
||||||
|
{ 'd', "dynamic", NULL, G_TYPE_NONE },
|
||||||
|
{ 'h', "hardcode", NULL, G_TYPE_NONE },
|
||||||
{ 'n', "noautosync", NULL, G_TYPE_NONE },
|
{ 'n', "noautosync", NULL, G_TYPE_NONE },
|
||||||
{ 's', "slice", &configure_slice, G_TYPE_NUMBER },
|
{ 's', "slice", &configure_slice, G_TYPE_NUMBER },
|
||||||
G_OPT_SENTINEL
|
G_OPT_SENTINEL
|
||||||
@ -72,6 +75,7 @@ struct g_command class_commands[] = {
|
|||||||
{ "label", G_FLAG_VERBOSE, mirror_main,
|
{ "label", G_FLAG_VERBOSE, mirror_main,
|
||||||
{
|
{
|
||||||
{ 'b', "balance", label_balance, G_TYPE_STRING },
|
{ 'b', "balance", label_balance, G_TYPE_STRING },
|
||||||
|
{ 'h', "hardcode", NULL, G_TYPE_NONE },
|
||||||
{ 'n', "noautosync", NULL, G_TYPE_NONE },
|
{ 'n', "noautosync", NULL, G_TYPE_NONE },
|
||||||
{ 's', "slice", &label_slice, G_TYPE_NUMBER },
|
{ 's', "slice", &label_slice, G_TYPE_NUMBER },
|
||||||
G_OPT_SENTINEL
|
G_OPT_SENTINEL
|
||||||
@ -79,6 +83,7 @@ struct g_command class_commands[] = {
|
|||||||
},
|
},
|
||||||
{ "insert", G_FLAG_VERBOSE, NULL,
|
{ "insert", G_FLAG_VERBOSE, NULL,
|
||||||
{
|
{
|
||||||
|
{ 'h', "hardcode", NULL, G_TYPE_NONE },
|
||||||
{ 'i', "inactive", NULL, G_TYPE_NONE },
|
{ 'i', "inactive", NULL, G_TYPE_NONE },
|
||||||
{ 'p', "priority", &insert_priority, G_TYPE_NUMBER },
|
{ 'p', "priority", &insert_priority, G_TYPE_NUMBER },
|
||||||
G_OPT_SENTINEL
|
G_OPT_SENTINEL
|
||||||
@ -102,27 +107,27 @@ void
|
|||||||
usage(const char *comm)
|
usage(const char *comm)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: %s label [-nv] [-b balance] [-s slice] name dev1 [dev2 [...]]\n"
|
"usage: %s label [-hnv] [-b balance] [-s slice] name prov [prov [...]]\n"
|
||||||
" %s clear [-v] dev1 [dev2 [...]]\n"
|
" %s clear [-v] prov [prov [...]]\n"
|
||||||
" %s dump dev1 [dev2 [...]]\n"
|
" %s dump prov [prov [...]]\n"
|
||||||
" %s configure [-anv] [-b balance] [-s slice] name\n"
|
" %s configure [-adhnv] [-b balance] [-s slice] name\n"
|
||||||
" %s rebuild [-v] name dev1 [dev2 [...]]\n"
|
" %s rebuild [-v] name prov [prov [...]]\n"
|
||||||
" %s insert [-iv] [-p priority] name dev1 [dev2 [...]]\n"
|
" %s insert [-hiv] [-p priority] name prov [prov [...]]\n"
|
||||||
" %s remove [-v] name dev1 [dev2 [...]]\n"
|
" %s remove [-v] name prov [prov [...]]\n"
|
||||||
" %s activate [-v] name dev1 [dev2 [...]]\n"
|
" %s activate [-v] name prov [prov [...]]\n"
|
||||||
" %s deactivate [-v] name dev1 [dev2 [...]]\n"
|
" %s deactivate [-v] name prov [prov [...]]\n"
|
||||||
" %s forget dev1 [dev2 [...]]\n"
|
" %s forget prov [prov [...]]\n"
|
||||||
" %s stop [-fv] name\n",
|
" %s stop [-fv] name\n",
|
||||||
comm, comm, comm, comm, comm, comm, comm, comm, comm, comm, comm);
|
comm, comm, comm, comm, comm, comm, comm, comm, comm, comm, comm);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mirror_main(struct gctl_req *req, unsigned f)
|
mirror_main(struct gctl_req *req, unsigned flags)
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
if ((f & G_FLAG_VERBOSE) != 0)
|
if ((flags & G_FLAG_VERBOSE) != 0)
|
||||||
verbose = 1;
|
verbose = 1;
|
||||||
|
|
||||||
name = gctl_get_asciiparam(req, "verb");
|
name = gctl_get_asciiparam(req, "verb");
|
||||||
@ -149,7 +154,7 @@ mirror_label(struct gctl_req *req)
|
|||||||
u_char sector[512];
|
u_char sector[512];
|
||||||
const char *str;
|
const char *str;
|
||||||
char param[16];
|
char param[16];
|
||||||
int *nargs, *noautosync, bal, error, i;
|
int *hardcode, *nargs, *noautosync, bal, error, i;
|
||||||
unsigned sectorsize;
|
unsigned sectorsize;
|
||||||
off_t mediasize;
|
off_t mediasize;
|
||||||
intmax_t *valp;
|
intmax_t *valp;
|
||||||
@ -202,6 +207,11 @@ mirror_label(struct gctl_req *req)
|
|||||||
}
|
}
|
||||||
if (*noautosync)
|
if (*noautosync)
|
||||||
md.md_mflags |= G_MIRROR_DEVICE_FLAG_NOAUTOSYNC;
|
md.md_mflags |= G_MIRROR_DEVICE_FLAG_NOAUTOSYNC;
|
||||||
|
hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode));
|
||||||
|
if (hardcode == NULL) {
|
||||||
|
gctl_error(req, "No '%s' argument.", "hardcode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate sectorsize by finding least common multiple from
|
* Calculate sectorsize by finding least common multiple from
|
||||||
@ -258,6 +268,13 @@ mirror_label(struct gctl_req *req)
|
|||||||
|
|
||||||
md.md_did = arc4random();
|
md.md_did = arc4random();
|
||||||
md.md_priority = i - 1;
|
md.md_priority = i - 1;
|
||||||
|
if (!*hardcode)
|
||||||
|
bzero(md.md_provider, sizeof(md.md_provider));
|
||||||
|
else {
|
||||||
|
if (strncmp(str, _PATH_DEV, strlen(_PATH_DEV)) == 0)
|
||||||
|
str += strlen(_PATH_DEV);
|
||||||
|
strlcpy(md.md_provider, str, sizeof(md.md_provider));
|
||||||
|
}
|
||||||
mirror_metadata_encode(&md, sector);
|
mirror_metadata_encode(&md, sector);
|
||||||
error = g_metadata_store(str, sector, sizeof(sector));
|
error = g_metadata_store(str, sector, sizeof(sector));
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
|
@ -92,7 +92,7 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
|||||||
intmax_t *slicep;
|
intmax_t *slicep;
|
||||||
uint32_t slice;
|
uint32_t slice;
|
||||||
uint8_t balance;
|
uint8_t balance;
|
||||||
int *nargs, *autosync, *noautosync, do_sync = 0;
|
int *nargs, *autosync, *noautosync, *hardcode, *dynamic, do_sync = 0;
|
||||||
|
|
||||||
g_topology_assert();
|
g_topology_assert();
|
||||||
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
|
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
|
||||||
@ -139,8 +139,18 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
|||||||
gctl_error(req, "No '%s' argument.", "noautosync");
|
gctl_error(req, "No '%s' argument.", "noautosync");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode));
|
||||||
|
if (hardcode == NULL) {
|
||||||
|
gctl_error(req, "No '%s' argument.", "hardcode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dynamic = gctl_get_paraml(req, "dynamic", sizeof(*dynamic));
|
||||||
|
if (dynamic == NULL) {
|
||||||
|
gctl_error(req, "No '%s' argument.", "dynamic");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (sc->sc_balance == balance && sc->sc_slice == slice && !*autosync &&
|
if (sc->sc_balance == balance && sc->sc_slice == slice && !*autosync &&
|
||||||
!*noautosync) {
|
!*noautosync && !*hardcode && !*dynamic) {
|
||||||
gctl_error(req, "Nothing has changed.");
|
gctl_error(req, "Nothing has changed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -149,6 +159,11 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
|||||||
"noautosync");
|
"noautosync");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (*hardcode && *dynamic) {
|
||||||
|
gctl_error(req, "'%s' and '%s' specified.", "hardcode",
|
||||||
|
"dynamic");
|
||||||
|
return;
|
||||||
|
}
|
||||||
sc->sc_balance = balance;
|
sc->sc_balance = balance;
|
||||||
sc->sc_slice = slice;
|
sc->sc_slice = slice;
|
||||||
if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_NOAUTOSYNC) != 0) {
|
if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_NOAUTOSYNC) != 0) {
|
||||||
@ -165,6 +180,10 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
|||||||
if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING)
|
if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING)
|
||||||
disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC;
|
disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC;
|
||||||
}
|
}
|
||||||
|
if (*hardcode)
|
||||||
|
disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED;
|
||||||
|
else if (*dynamic)
|
||||||
|
disk->d_flags &= ~G_MIRROR_DISK_FLAG_HARDCODED;
|
||||||
g_mirror_update_metadata(disk);
|
g_mirror_update_metadata(disk);
|
||||||
if (do_sync) {
|
if (do_sync) {
|
||||||
if (disk->d_state == G_MIRROR_DISK_STATE_STALE) {
|
if (disk->d_state == G_MIRROR_DISK_STATE_STALE) {
|
||||||
@ -257,7 +276,7 @@ g_mirror_ctl_insert(struct gctl_req *req, struct g_class *mp)
|
|||||||
char param[16];
|
char param[16];
|
||||||
u_char *sector;
|
u_char *sector;
|
||||||
u_int i, n;
|
u_int i, n;
|
||||||
int error, *nargs, *inactive;
|
int error, *nargs, *hardcode, *inactive;
|
||||||
struct {
|
struct {
|
||||||
struct g_provider *provider;
|
struct g_provider *provider;
|
||||||
struct g_consumer *consumer;
|
struct g_consumer *consumer;
|
||||||
@ -283,6 +302,11 @@ g_mirror_ctl_insert(struct gctl_req *req, struct g_class *mp)
|
|||||||
gctl_error(req, "No '%s' argument.", "inactive");
|
gctl_error(req, "No '%s' argument.", "inactive");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode));
|
||||||
|
if (hardcode == NULL) {
|
||||||
|
gctl_error(req, "No '%s' argument.", "hardcode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
name = gctl_get_asciiparam(req, "arg0");
|
name = gctl_get_asciiparam(req, "arg0");
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
gctl_error(req, "No 'arg%u' argument.", 0);
|
gctl_error(req, "No 'arg%u' argument.", 0);
|
||||||
@ -356,6 +380,12 @@ g_mirror_ctl_insert(struct gctl_req *req, struct g_class *mp)
|
|||||||
if (*inactive)
|
if (*inactive)
|
||||||
md.md_dflags |= G_MIRROR_DISK_FLAG_INACTIVE;
|
md.md_dflags |= G_MIRROR_DISK_FLAG_INACTIVE;
|
||||||
pp = disks[i].provider;
|
pp = disks[i].provider;
|
||||||
|
if (*hardcode) {
|
||||||
|
strlcpy(md.md_provider, pp->name,
|
||||||
|
sizeof(md.md_provider));
|
||||||
|
} else {
|
||||||
|
bzero(md.md_provider, sizeof(md.md_provider));
|
||||||
|
}
|
||||||
sector = g_malloc(pp->sectorsize, M_WAITOK);
|
sector = g_malloc(pp->sectorsize, M_WAITOK);
|
||||||
mirror_metadata_encode(&md, sector);
|
mirror_metadata_encode(&md, sector);
|
||||||
error = g_write_data(disks[i].consumer,
|
error = g_write_data(disks[i].consumer,
|
||||||
|
Loading…
Reference in New Issue
Block a user