summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorlulf <lulf@FreeBSD.org>2009-04-10 10:12:09 +0000
committerlulf <lulf@FreeBSD.org>2009-04-10 10:12:09 +0000
commitcd9a5afff5db18022235b4e882b1ee5b9095d754 (patch)
tree7878a6830d89856242ee9068d85f5f48fe849304 /sbin
parent4ea821c2235c44e6912826449ef0dee77f2f387d (diff)
downloadFreeBSD-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.816
-rw-r--r--sbin/gvinum/gvinum.c86
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"))
OpenPOWER on IntegriCloud