Patch to allow gmirror to set priority of a disk

Mel Flynn mel.flynn+fbsd.fs at mailing.thruhere.net
Sun Sep 6 00:36:16 UTC 2009


Hi,

new patch containing everything and points for elegance. Double checked for 
style, so I'm sure there's one or two left ;).

Since it's applies nearly clean (1 hunk -6 lines offset) on 7-STABLE, I can 
runtime test it tomorrow (tonight is lvl 0 backup).
-- 
Mel
-------------- next part --------------
Index: sys/geom/mirror/g_mirror_ctl.c
===================================================================
--- sys/geom/mirror/g_mirror_ctl.c	(revision 196868)
+++ 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,29 @@
 		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");
@@ -189,6 +212,14 @@
 		slice = sc->sc_slice;
 	else
 		slice = *slicep;
+	/* Enforce usage() of -p not allowing any other options */
+	if (do_priority && (*autosync || *noautosync || *failsync ||
+		    *nofailsync || *hardcode || *dynamic || *slicep != -1 ||
+		    (strcmp(balancep, "none")))) {
+		gctl_error(req, "only -p accepted when setting priority");
+		sx_xunlock(&sc->sc_lock);
+		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 "
@@ -197,7 +228,7 @@
 	}
 	if (sc->sc_balance == balance && sc->sc_slice == slice && !*autosync &&
 	    !*noautosync && !*failsync && !*nofailsync && !*hardcode &&
-	    !*dynamic) {
+	    !*dynamic && !do_priority) {
 		sx_xunlock(&sc->sc_lock);
 		gctl_error(req, "Nothing has changed.");
 		return;
@@ -223,6 +254,19 @@
 		}
 	}
 	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) {
+				disk->d_priority = *priority;
+				g_mirror_update_metadata(disk);
+				break;
+			}
+			continue;
+		}
 		if (do_sync) {
 			if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING)
 				disk->d_flags &= ~G_MIRROR_DISK_FLAG_FORCE_SYNC;
Index: sbin/geom/core/geom.c
===================================================================
--- sbin/geom/core/geom.c	(revision 196868)
+++ sbin/geom/core/geom.c	(working copy)
@@ -98,11 +98,25 @@
 	struct g_option *opt;
 	unsigned i;
 
-	fprintf(stderr, "%s %s %s", prefix, comm, cmd->gc_name);
 	if (cmd->gc_usage != NULL) {
-		fprintf(stderr, " %s\n", cmd->gc_usage);
+		char *pos, *ptr, *sptr;
+
+		ptr = strdup(cmd->gc_usage);
+		sptr = ptr;
+		while ((pos = strchr(ptr, '\n')) != NULL) {
+			*pos = '\0';
+			fprintf(stderr, "%s %s %s", prefix, comm, cmd->gc_name);
+			fprintf(stderr, "%s\n", ptr);
+			ptr = pos + 1;
+		}
+		/* Tail or no \n at all */
+		fprintf(stderr, "%s %s %s", prefix, comm, cmd->gc_name);
+		fprintf(stderr, " %s\n", ptr);
+		free(sptr);
 		return;
 	}
+
+	fprintf(stderr, "%s %s %s", prefix, comm, cmd->gc_name);
 	if ((cmd->gc_flags & G_FLAG_VERBOSE) != 0)
 		fprintf(stderr, " [-v]");
 	for (i = 0; ; i++) {
Index: sbin/geom/class/mirror/geom_mirror.c
===================================================================
--- sbin/geom/class/mirror/geom_mirror.c	(revision 196868)
+++ 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,12 @@
 		{ '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] name\n"
+		  "-p priority 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 196868)
+++ sbin/geom/class/mirror/gmirror.8	(working copy)
@@ -49,6 +49,12 @@
 .Op Fl s Ar slice
 .Ar name
 .Nm
+.Cm configure
+.Op Fl v
+.Fl p Ar priority
+.Ar name
+.Ar prov
+.Nm
 .Cm rebuild
 .Op Fl v
 .Ar name
@@ -115,8 +121,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 +181,9 @@
 Hardcode providers' names in metadata.
 .It Fl n
 Turn off autosynchronization of stale components.
+.It Fl p Ar priority
+Specifies priority for the given component
+.Ar prov .
 .It Fl s Ar slice
 Specifies slice size for
 .Cm split


More information about the freebsd-fs mailing list