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"))
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to