Patch to allow gmirror to set priority of a disk
Mel Flynn
mel.flynn+fbsd.fs at mailing.thruhere.net
Fri Sep 4 08:16:56 UTC 2009
On Thursday 03 September 2009 15:57:41 Pawel Jakub Dawidek wrote:
> On Thu, Sep 03, 2009 at 03:48:37PM +0200, Mel Flynn wrote:
> > On Thursday 03 September 2009 14:44:07 Pawel Jakub Dawidek wrote:
> > > I'd suggest doing this not as separate gmirror(8) subcommand, but as an
> > > extension to 'configure' subcommand, where one can provide priority by
> > > giving '-p' argument.
> >
> > Except I didn't see how configure was implemented. Am I correct that this
> > is g_mirror_ctl_configure in sys/geom/mirror/g_mirror_ctl.c?
>
> Yes, you are correct.
Ok, new patch. I gathered from configure_slice, that my assumption was about
flag handling is correct. Patch is only compile tested.
--
Mel
-------------- next part --------------
Index: sbin/geom/class/mirror/geom_mirror.c
===================================================================
--- sbin/geom/class/mirror/geom_mirror.c (revision 196803)
+++ sbin/geom/class/mirror/geom_mirror.c (working copy)
@@ -47,7 +47,7 @@
static char label_balance[] = "split", configure_balance[] = "none";
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_activate(struct gctl_req *req);
@@ -71,10 +71,11 @@
{ 'F', "nofailsync", NULL, G_TYPE_BOOL },
{ 'h', "hardcode", NULL, G_TYPE_BOOL },
{ 'n', "noautosync", NULL, G_TYPE_BOOL },
+ { 'p', "priority", &configure_priority, G_TYPE_NUMBER },
{ 's', "slice", &configure_slice, G_TYPE_NUMBER },
G_OPT_SENTINEL
},
- NULL, "[-adfFhnv] [-b balance] [-s slice] name"
+ NULL, "[-adfFhnv] [-b balance] [-s slice] [-p prio] name [prov]"
},
{ "deactivate", G_FLAG_VERBOSE, NULL, G_NULL_OPTS, NULL,
"[-v] name prov ..."
Index: sbin/geom/class/mirror/gmirror.8
===================================================================
--- sbin/geom/class/mirror/gmirror.8 (revision 196803)
+++ sbin/geom/class/mirror/gmirror.8 (working copy)
@@ -47,7 +47,9 @@
.Op Fl adfFhnv
.Op Fl b Ar balance
.Op Fl s Ar slice
+.Op Fl p Ar priority
.Ar name
+.Op Ar prov
.Nm
.Cm rebuild
.Op Fl v
@@ -115,8 +117,8 @@
.It Cm label
Create a mirror.
The order of components is important, because a component's priority is based on its position
-(starting from 0).
-The component with the biggest priority is used by the
+(starting from 0 to 255).
+The component with the biggest priority (the lowest number) is used by the
.Cm prefer
balance algorithm
and is also used as a master component when resynchronization is needed,
@@ -175,6 +177,9 @@
Hardcode providers' names in metadata.
.It Fl n
Turn off autosynchronization of stale components.
+.It Fl p Ar priority
+Specify priority for given
+.Ar prov
.It Fl s Ar slice
Specifies slice size for
.Cm split
Index: sys/geom/mirror/g_mirror_ctl.c
===================================================================
--- sys/geom/mirror/g_mirror_ctl.c (revision 196803)
+++ sys/geom/mirror/g_mirror_ctl.c (working copy)
@@ -93,12 +93,12 @@
{
struct g_mirror_softc *sc;
struct g_mirror_disk *disk;
- const char *name, *balancep;
+ const char *name, *balancep, *prov;
intmax_t *slicep;
uint32_t slice;
uint8_t balance;
int *autosync, *noautosync, *failsync, *nofailsync, *hardcode, *dynamic;
- int *nargs, do_sync = 0, dirty = 1;
+ int *nargs, *priority, do_sync = 0, dirty = 1, do_priority = 0;
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
if (nargs == NULL) {
@@ -149,6 +149,27 @@
gctl_error(req, "No '%s' argument.", "dynamic");
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, %i 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) {
gctl_error(req, "'%s' and '%s' specified.", "autosync",
"noautosync");
@@ -233,6 +254,11 @@
disk->d_flags &= ~G_MIRROR_DISK_FLAG_HARDCODED;
if (!dirty)
disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY;
+ if (do_priority) {
+ if (strcmp(disk->d_name, prov) == 0) {
+ disk->d_priority = *priority;
+ }
+ }
g_mirror_update_metadata(disk);
if (do_sync) {
if (disk->d_state == G_MIRROR_DISK_STATE_STALE) {
More information about the freebsd-fs
mailing list