Date: Sun, 6 Sep 2009 02:36:10 +0200 From: Mel Flynn <mel.flynn+fbsd.fs@mailing.thruhere.net> To: freebsd-fs@freebsd.org Cc: Pawel Jakub Dawidek <pjd@freebsd.org>, freebsd-geom@freebsd.org Subject: Re: Patch to allow gmirror to set priority of a disk Message-ID: <200909060236.11224.mel.flynn%2Bfbsd.fs@mailing.thruhere.net> In-Reply-To: <20090905192251.GJ1665@garage.freebsd.pl> References: <200909030000.11961.mel.flynn%2Bfbsd.fs@mailing.thruhere.net> <200909052111.27667.mel.flynn%2Bfbsd.fs@mailing.thruhere.net> <20090905192251.GJ1665@garage.freebsd.pl>
next in thread | previous in thread | raw e-mail | index | archive | help
--Boundary-00=_7PwoKCEku+NtiA2 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline 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 --Boundary-00=_7PwoKCEku+NtiA2 Content-Type: text/plain; charset="UTF-8"; name="gmirror-priority.txt" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="gmirror-priority.txt" 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 --Boundary-00=_7PwoKCEku+NtiA2--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200909060236.11224.mel.flynn%2Bfbsd.fs>