From owner-svn-src-all@FreeBSD.ORG Fri Apr 10 10:12:10 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 471F31065672; Fri, 10 Apr 2009 10:12:10 +0000 (UTC) (envelope-from lulf@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2B3A58FC0A; Fri, 10 Apr 2009 10:12:10 +0000 (UTC) (envelope-from lulf@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n3AACAMF038867; Fri, 10 Apr 2009 10:12:10 GMT (envelope-from lulf@svn.freebsd.org) Received: (from lulf@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n3AACAuE038865; Fri, 10 Apr 2009 10:12:10 GMT (envelope-from lulf@svn.freebsd.org) Message-Id: <200904101012.n3AACAuE038865@svn.freebsd.org> From: Ulf Lilleengen Date: Fri, 10 Apr 2009 10:12:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r190884 - head/sbin/gvinum X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Apr 2009 10:12:10 -0000 Author: lulf Date: Fri Apr 10 10:12:09 2009 New Revision: 190884 URL: http://svn.freebsd.org/changeset/base/190884 Log: - Implement the grow command to make it easier for users to extend plexes without having to understand all gvinum internals. - Document the grow command in the manpage and update examples to use the command where possible. Modified: head/sbin/gvinum/gvinum.8 head/sbin/gvinum/gvinum.c Modified: head/sbin/gvinum/gvinum.8 ============================================================================== --- head/sbin/gvinum/gvinum.8 Fri Apr 10 09:52:42 2009 (r190883) +++ head/sbin/gvinum/gvinum.8 Fri Apr 10 10:12:09 2009 (r190884) @@ -79,6 +79,10 @@ flag is given. .It Ic detach Oo Fl f Oc Op Ar plex | subdisk Detach a plex or subdisk from the volume or plex to which it is attached. +.It Ic grow Ar plex device +Grow a plex by creating a gvinum drive and subdisk on device and attach it to +the plex. +If required by the plex organization, it will be put into the growable state. .It Ic help Provides a synopsis of .Nm @@ -333,16 +337,11 @@ Then, initiate the rebuild: The plex will go up form degraded mode after the rebuild is finished. The plex can still be used while the rebuild is in progress, although requests might be delayed. -For a more advanced usage and detailed explanation of gvinum, the -handbook is recommended. .Pp Given the configuration as in the previous example, growing a RAID-5 or STRIPED -array is accomplished by adding a new subdisk to the plex with a -.Ar description-file -similar to this: +array is accomplished by using the grow command: .Pp -.Dl "drive newdrive device /dev/ad4" -.Dl "sd drive newdrive plex myraid5vol.p0" +.Dl "gvinum grow myraid5vol.p0 /dev/ad4" .Pp If everything went ok, the plex state should now be set to growable. You can then start the growing with the @@ -355,6 +354,9 @@ As with rebuilding, you can watch the pr .Ic list command. .Pp +For a more advanced usage and detailed explanation of gvinum, the +handbook is recommended. +.Pp .Sh SEE ALSO .Xr geom 4 , .Xr geom 8 Modified: head/sbin/gvinum/gvinum.c ============================================================================== --- head/sbin/gvinum/gvinum.c Fri Apr 10 09:52:42 2009 (r190883) +++ head/sbin/gvinum/gvinum.c Fri Apr 10 10:12:09 2009 (r190884) @@ -61,6 +61,7 @@ void gvinum_attach(int, char **); void gvinum_concat(int, char **); void gvinum_create(int, char **); void gvinum_detach(int, char **); +void gvinum_grow(int, char **); void gvinum_help(void); void gvinum_list(int, char **); void gvinum_move(int, char **); @@ -690,6 +691,8 @@ gvinum_help(void) "detach [-f] [plex | subdisk]\n" " Detach a plex or a subdisk from the volume or plex to\n" " which it is attached.\n" + "grow plex drive\n" + " Grow plex by creating a properly sized subdisk on drive\n" "l | list [-r] [-v] [-V] [volume | plex | subdisk]\n" " List information about specified objects.\n" "ld [-r] [-v] [-V] [volume]\n" @@ -1242,6 +1245,87 @@ gvinum_stripe(int argc, char **argv) create_volume(argc, argv, "stripe"); } +/* Grow a subdisk by adding disk backed by provider. */ +void +gvinum_grow(int argc, char **argv) +{ + struct gctl_req *req; + char *drive, *sdname; + char sdprefix[GV_MAXSDNAME]; + struct gv_drive *d; + struct gv_sd *s; + const char *errstr; + int drives, volumes, plexes, subdisks, flags; + + drives = volumes = plexes = subdisks = 0; + if (argc < 3) { + warnx("usage:\tgrow plex drive\n"); + return; + } + + s = gv_alloc_sd(); + if (s == NULL) { + warn("unable to create subdisk"); + return; + } + d = gv_alloc_drive(); + if (d == NULL) { + warn("unable to create drive"); + free(s); + return; + } + /* Lookup device and set an appropriate drive name. */ + drive = find_drive(argv[2]); + if (drive == NULL) { + warn("unable to find an appropriate drive name"); + free(s); + free(d); + return; + } + strlcpy(d->name, drive, sizeof(d->name)); + if (strncmp(argv[2], "/dev/", 5) == 0) + strlcpy(d->device, (argv[2] + 5), sizeof(d->device)); + else + strlcpy(d->device, argv[2], sizeof(d->device)); + drives = 1; + + /* We try to use the plex name as basis for the subdisk name. */ + snprintf(sdprefix, sizeof(sdprefix), "%s.s", argv[1]); + sdname = find_name(sdprefix, GV_TYPE_SD, GV_MAXSDNAME); + if (sdname == NULL) { + warn("unable to find an appropriate subdisk name"); + free(s); + free(d); + free(drive); + return; + } + strlcpy(s->name, sdname, sizeof(s->name)); + free(sdname); + strlcpy(s->plex, argv[1], sizeof(s->plex)); + strlcpy(s->drive, d->name, sizeof(s->drive)); + subdisks = 1; + + req = gctl_get_handle(); + gctl_ro_param(req, "class", -1, "VINUM"); + gctl_ro_param(req, "verb", -1, "create"); + gctl_ro_param(req, "flags", sizeof(int), &flags); + gctl_ro_param(req, "volumes", sizeof(int), &volumes); + gctl_ro_param(req, "plexes", sizeof(int), &plexes); + gctl_ro_param(req, "subdisks", sizeof(int), &subdisks); + gctl_ro_param(req, "drives", sizeof(int), &drives); + gctl_ro_param(req, "drive0", sizeof(*d), d); + gctl_ro_param(req, "sd0", sizeof(*s), s); + errstr = gctl_issue(req); + free(drive); + if (errstr != NULL) { + warnx("unable to grow plex: %s", errstr); + free(s); + free(d); + return; + } + gctl_free(req); +} + void parseline(int argc, char **argv) { @@ -1258,6 +1342,8 @@ parseline(int argc, char **argv) gvinum_detach(argc, argv); else if (!strcmp(argv[0], "concat")) gvinum_concat(argc, argv); + else if (!strcmp(argv[0], "grow")) + gvinum_grow(argc, argv); else if (!strcmp(argv[0], "help")) gvinum_help(); else if (!strcmp(argv[0], "list") || !strcmp(argv[0], "l"))