Add support for changing providers priority.
Submitted by: Mel Flynn
This commit is contained in:
parent
87070efb4d
commit
b740e905a4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=196879
@ -1,5 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
* Copyright (c) 2004-2009 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||||
* 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
|
||||||
@ -41,13 +41,12 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <core/geom.h>
|
#include <core/geom.h>
|
||||||
#include <misc/subr.h>
|
#include <misc/subr.h>
|
||||||
|
|
||||||
|
|
||||||
uint32_t lib_version = G_LIB_VERSION;
|
uint32_t lib_version = G_LIB_VERSION;
|
||||||
uint32_t version = G_MIRROR_VERSION;
|
uint32_t version = G_MIRROR_VERSION;
|
||||||
|
|
||||||
static char label_balance[] = "split", configure_balance[] = "none";
|
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, configure_priority = -1;
|
||||||
|
|
||||||
static void mirror_main(struct gctl_req *req, unsigned flags);
|
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);
|
||||||
@ -71,10 +70,12 @@ struct g_command class_commands[] = {
|
|||||||
{ 'F', "nofailsync", NULL, G_TYPE_BOOL },
|
{ 'F', "nofailsync", NULL, G_TYPE_BOOL },
|
||||||
{ 'h', "hardcode", NULL, G_TYPE_BOOL },
|
{ 'h', "hardcode", NULL, G_TYPE_BOOL },
|
||||||
{ 'n', "noautosync", NULL, G_TYPE_BOOL },
|
{ 'n', "noautosync", NULL, G_TYPE_BOOL },
|
||||||
|
{ 'p', "priority", &configure_priority, G_TYPE_NUMBER },
|
||||||
{ 's', "slice", &configure_slice, G_TYPE_NUMBER },
|
{ 's', "slice", &configure_slice, G_TYPE_NUMBER },
|
||||||
G_OPT_SENTINEL
|
G_OPT_SENTINEL
|
||||||
},
|
},
|
||||||
NULL, "[-adfFhnv] [-b balance] [-s slice] name"
|
NULL, "[-adfFhnv] [-b balance] [-s slice] name\n"
|
||||||
|
"[-v] -p priority name prov"
|
||||||
},
|
},
|
||||||
{ "deactivate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS, NULL,
|
{ "deactivate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS, NULL,
|
||||||
"[-v] name prov ..."
|
"[-v] name prov ..."
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" Copyright (c) 2004-2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
.\" Copyright (c) 2004-2009 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||||
.\" 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
|
||||||
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd November 1, 2006
|
.Dd August 1, 2009
|
||||||
.Dt GMIRROR 8
|
.Dt GMIRROR 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -49,6 +49,12 @@
|
|||||||
.Op Fl s Ar slice
|
.Op Fl s Ar slice
|
||||||
.Ar name
|
.Ar name
|
||||||
.Nm
|
.Nm
|
||||||
|
.Cm configure
|
||||||
|
.Op Fl v
|
||||||
|
.Fl p Ar priority
|
||||||
|
.Ar name
|
||||||
|
.Ar prov
|
||||||
|
.Nm
|
||||||
.Cm rebuild
|
.Cm rebuild
|
||||||
.Op Fl v
|
.Op Fl v
|
||||||
.Ar name
|
.Ar name
|
||||||
@ -115,8 +121,8 @@ indicates an action to be performed:
|
|||||||
.It Cm label
|
.It Cm label
|
||||||
Create a mirror.
|
Create a mirror.
|
||||||
The order of components is important, because a component's priority is based on its position
|
The order of components is important, because a component's priority is based on its position
|
||||||
(starting from 0).
|
(starting from 0 to 255).
|
||||||
The component with the biggest priority is used by the
|
The component with the biggest priority (the lowest number) is used by the
|
||||||
.Cm prefer
|
.Cm prefer
|
||||||
balance algorithm
|
balance algorithm
|
||||||
and is also used as a master component when resynchronization is needed,
|
and is also used as a master component when resynchronization is needed,
|
||||||
@ -159,7 +165,7 @@ Clear metadata on the given providers.
|
|||||||
Configure the given device.
|
Configure the given device.
|
||||||
.Pp
|
.Pp
|
||||||
Additional options include:
|
Additional options include:
|
||||||
.Bl -tag -width ".Fl b Ar balance"
|
.Bl -tag -width ".Fl p Ar priority"
|
||||||
.It Fl a
|
.It Fl a
|
||||||
Turn on autosynchronization of stale components.
|
Turn on autosynchronization of stale components.
|
||||||
.It Fl b Ar balance
|
.It Fl b Ar balance
|
||||||
@ -175,6 +181,9 @@ Assumes device is in consistent state.
|
|||||||
Hardcode providers' names in metadata.
|
Hardcode providers' names in metadata.
|
||||||
.It Fl n
|
.It Fl n
|
||||||
Turn off autosynchronization of stale components.
|
Turn off autosynchronization of stale components.
|
||||||
|
.It Fl p Ar priority
|
||||||
|
Specifies priority for the given component
|
||||||
|
.Ar prov .
|
||||||
.It Fl s Ar slice
|
.It Fl s Ar slice
|
||||||
Specifies slice size for
|
Specifies slice size for
|
||||||
.Cm split
|
.Cm split
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
* Copyright (c) 2004-2009 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
||||||
* 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
|
||||||
@ -93,19 +93,19 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
|||||||
{
|
{
|
||||||
struct g_mirror_softc *sc;
|
struct g_mirror_softc *sc;
|
||||||
struct g_mirror_disk *disk;
|
struct g_mirror_disk *disk;
|
||||||
const char *name, *balancep;
|
const char *name, *balancep, *prov;
|
||||||
intmax_t *slicep;
|
intmax_t *slicep, *priority;
|
||||||
uint32_t slice;
|
uint32_t slice;
|
||||||
uint8_t balance;
|
uint8_t balance;
|
||||||
int *autosync, *noautosync, *failsync, *nofailsync, *hardcode, *dynamic;
|
int *autosync, *noautosync, *failsync, *nofailsync, *hardcode, *dynamic;
|
||||||
int *nargs, do_sync = 0, dirty = 1;
|
int *nargs, do_sync = 0, dirty = 1, do_priority = 0;
|
||||||
|
|
||||||
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
|
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
|
||||||
if (nargs == NULL) {
|
if (nargs == NULL) {
|
||||||
gctl_error(req, "No '%s' argument.", "nargs");
|
gctl_error(req, "No '%s' argument.", "nargs");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (*nargs != 1) {
|
if (*nargs != 1 && *nargs != 2) {
|
||||||
gctl_error(req, "Invalid number of arguments.");
|
gctl_error(req, "Invalid number of arguments.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -149,6 +149,29 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
|||||||
gctl_error(req, "No '%s' argument.", "dynamic");
|
gctl_error(req, "No '%s' argument.", "dynamic");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
priority = gctl_get_paraml(req, "priority", sizeof(*priority));
|
||||||
|
if (priority == NULL) {
|
||||||
|
gctl_error(req, "No '%s' argument.", "priority");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (*priority < -1 || *priority > 255) {
|
||||||
|
gctl_error(req, "Priority range is 0 to 255, %jd given",
|
||||||
|
*priority);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Since we have a priority, we also need a provider now.
|
||||||
|
* Note: be WARNS safe, by always assigning prov and only throw an
|
||||||
|
* error if *priority != -1.
|
||||||
|
*/
|
||||||
|
prov = gctl_get_asciiparam(req, "arg1");
|
||||||
|
if (*priority > -1) {
|
||||||
|
if (prov == NULL) {
|
||||||
|
gctl_error(req, "Priority needs a disk name");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do_priority = 1;
|
||||||
|
}
|
||||||
if (*autosync && *noautosync) {
|
if (*autosync && *noautosync) {
|
||||||
gctl_error(req, "'%s' and '%s' specified.", "autosync",
|
gctl_error(req, "'%s' and '%s' specified.", "autosync",
|
||||||
"noautosync");
|
"noautosync");
|
||||||
@ -189,19 +212,32 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
|||||||
slice = sc->sc_slice;
|
slice = sc->sc_slice;
|
||||||
else
|
else
|
||||||
slice = *slicep;
|
slice = *slicep;
|
||||||
if (g_mirror_ndisks(sc, -1) < sc->sc_ndisks) {
|
/* Enforce usage() of -p not allowing any other options. */
|
||||||
|
if (do_priority && (*autosync || *noautosync || *failsync ||
|
||||||
|
*nofailsync || *hardcode || *dynamic || *slicep != -1 ||
|
||||||
|
strcmp(balancep, "none") != 0)) {
|
||||||
sx_xunlock(&sc->sc_lock);
|
sx_xunlock(&sc->sc_lock);
|
||||||
gctl_error(req, "Not all disks connected. Try 'forget' command "
|
gctl_error(req, "only -p accepted when setting priority");
|
||||||
"first.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sc->sc_balance == balance && sc->sc_slice == slice && !*autosync &&
|
if (sc->sc_balance == balance && sc->sc_slice == slice && !*autosync &&
|
||||||
!*noautosync && !*failsync && !*nofailsync && !*hardcode &&
|
!*noautosync && !*failsync && !*nofailsync && !*hardcode &&
|
||||||
!*dynamic) {
|
!*dynamic && !do_priority) {
|
||||||
sx_xunlock(&sc->sc_lock);
|
sx_xunlock(&sc->sc_lock);
|
||||||
gctl_error(req, "Nothing has changed.");
|
gctl_error(req, "Nothing has changed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ((!do_priority && *nargs != 1) || (do_priority && *nargs != 2)) {
|
||||||
|
sx_xunlock(&sc->sc_lock);
|
||||||
|
gctl_error(req, "Invalid number of arguments.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (g_mirror_ndisks(sc, -1) < sc->sc_ndisks) {
|
||||||
|
sx_xunlock(&sc->sc_lock);
|
||||||
|
gctl_error(req, "Not all disks connected. Try 'forget' command "
|
||||||
|
"first.");
|
||||||
|
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) {
|
||||||
@ -223,6 +259,23 @@ g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
|
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
|
||||||
|
/*
|
||||||
|
* Handle priority first, since we only need one disk, do one
|
||||||
|
* operation on it and then we're done. No need to check other
|
||||||
|
* flags, as usage doesn't allow it.
|
||||||
|
*/
|
||||||
|
if (do_priority) {
|
||||||
|
if (strcmp(disk->d_name, prov) == 0) {
|
||||||
|
if (disk->d_priority == *priority)
|
||||||
|
gctl_error(req, "Nothing has changed.");
|
||||||
|
else {
|
||||||
|
disk->d_priority = *priority;
|
||||||
|
g_mirror_update_metadata(disk);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (do_sync) {
|
if (do_sync) {
|
||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user