- 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.
This commit is contained in:
parent
11e0093f28
commit
8d4311eacb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=190884
@ -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
|
||||
|
@ -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"))
|
||||
|
Loading…
Reference in New Issue
Block a user