summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/geom/class/raid3/geom_raid3.c2
-rw-r--r--sbin/geom/class/raid3/graid3.86
-rw-r--r--sys/geom/raid3/g_raid3_ctl.c45
3 files changed, 34 insertions, 19 deletions
diff --git a/sbin/geom/class/raid3/geom_raid3.c b/sbin/geom/class/raid3/geom_raid3.c
index 3f037cd..cd0aa65 100644
--- a/sbin/geom/class/raid3/geom_raid3.c
+++ b/sbin/geom/class/raid3/geom_raid3.c
@@ -76,7 +76,7 @@ struct g_command class_commands[] = {
{ "insert", G_FLAG_VERBOSE, NULL,
{
{ 'h', "hardcode", NULL, G_TYPE_BOOL },
- { 'n', "number", NULL, G_TYPE_NUMBER },
+ { 'n', "number", G_VAL_OPTIONAL, G_TYPE_NUMBER },
G_OPT_SENTINEL
},
"[-hv] <-n number> name prov"
diff --git a/sbin/geom/class/raid3/graid3.8 b/sbin/geom/class/raid3/graid3.8
index f396cc3..a82d388 100644
--- a/sbin/geom/class/raid3/graid3.8
+++ b/sbin/geom/class/raid3/graid3.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 5, 2010
+.Dd January 15, 2012
.Dt GRAID3 8
.Os
.Sh NAME
@@ -53,7 +53,7 @@
.Nm
.Cm insert
.Op Fl hv
-.Fl n Ar number
+.Op Fl n Ar number
.Ar name
.Ar prov
.Nm
@@ -171,6 +171,8 @@ Add the given component to the existing array, if one of the components was
removed previously with the
.Cm remove
command or if one component is missing and will not be connected again.
+If no number is given, new component will be added instead of first missed
+component.
.Pp
Additional options include:
.Bl -tag -width ".Fl h"
diff --git a/sys/geom/raid3/g_raid3_ctl.c b/sys/geom/raid3/g_raid3_ctl.c
index 952ac2b..b3a42ff 100644
--- a/sys/geom/raid3/g_raid3_ctl.c
+++ b/sys/geom/raid3/g_raid3_ctl.c
@@ -404,7 +404,7 @@ g_raid3_ctl_insert(struct gctl_req *req, struct g_class *mp)
u_char *sector;
off_t compsize;
intmax_t *no;
- int *hardcode, *nargs, error;
+ int *hardcode, *nargs, error, autono;
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
if (nargs == NULL) {
@@ -425,11 +425,10 @@ g_raid3_ctl_insert(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "No 'arg%u' argument.", 1);
return;
}
- no = gctl_get_paraml(req, "number", sizeof(*no));
- if (no == NULL) {
- gctl_error(req, "No '%s' argument.", "no");
- return;
- }
+ if (gctl_get_param(req, "number", NULL) != NULL)
+ no = gctl_get_paraml(req, "number", sizeof(*no));
+ else
+ no = NULL;
if (strncmp(name, "/dev/", 5) == 0)
name += 5;
g_topology_lock();
@@ -465,16 +464,30 @@ g_raid3_ctl_insert(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "No such device: %s.", name);
goto end;
}
- if (*no >= sc->sc_ndisks) {
- sx_xunlock(&sc->sc_lock);
- gctl_error(req, "Invalid component number.");
- goto end;
- }
- disk = &sc->sc_disks[*no];
- if (disk->d_state != G_RAID3_DISK_STATE_NODISK) {
- sx_xunlock(&sc->sc_lock);
- gctl_error(req, "Component %jd is already connected.", *no);
- goto end;
+ if (no != NULL) {
+ if (*no < 0 || *no >= sc->sc_ndisks) {
+ sx_xunlock(&sc->sc_lock);
+ gctl_error(req, "Invalid component number.");
+ goto end;
+ }
+ disk = &sc->sc_disks[*no];
+ if (disk->d_state != G_RAID3_DISK_STATE_NODISK) {
+ sx_xunlock(&sc->sc_lock);
+ gctl_error(req, "Component %jd is already connected.",
+ *no);
+ goto end;
+ }
+ } else {
+ disk = NULL;
+ for (autono = 0; autono < sc->sc_ndisks && disk == NULL; autono++)
+ if (sc->sc_disks[autono].d_state ==
+ G_RAID3_DISK_STATE_NODISK)
+ disk = &sc->sc_disks[autono];
+ if (disk == NULL) {
+ sx_xunlock(&sc->sc_lock);
+ gctl_error(req, "No disconnected components.");
+ goto end;
+ }
}
if (((sc->sc_sectorsize / (sc->sc_ndisks - 1)) % pp->sectorsize) != 0) {
sx_xunlock(&sc->sc_lock);
OpenPOWER on IntegriCloud