diff options
author | lulf <lulf@FreeBSD.org> | 2009-04-10 10:12:09 +0000 |
---|---|---|
committer | lulf <lulf@FreeBSD.org> | 2009-04-10 10:12:09 +0000 |
commit | cd9a5afff5db18022235b4e882b1ee5b9095d754 (patch) | |
tree | 7878a6830d89856242ee9068d85f5f48fe849304 /sbin | |
parent | 4ea821c2235c44e6912826449ef0dee77f2f387d (diff) | |
download | FreeBSD-src-cd9a5afff5db18022235b4e882b1ee5b9095d754.zip FreeBSD-src-cd9a5afff5db18022235b4e882b1ee5b9095d754.tar.gz |
- 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.
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/gvinum/gvinum.8 | 16 | ||||
-rw-r--r-- | sbin/gvinum/gvinum.c | 86 |
2 files changed, 95 insertions, 7 deletions
diff --git a/sbin/gvinum/gvinum.8 b/sbin/gvinum/gvinum.8 index d2b9616..9bf44ee 100644 --- a/sbin/gvinum/gvinum.8 +++ b/sbin/gvinum/gvinum.8 @@ -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 progress using the .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 diff --git a/sbin/gvinum/gvinum.c b/sbin/gvinum/gvinum.c index 81bdbe4..1688a7b 100644 --- a/sbin/gvinum/gvinum.c +++ b/sbin/gvinum/gvinum.c @@ -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")) |