diff --git a/sbin/geom/class/raid3/geom_raid3.c b/sbin/geom/class/raid3/geom_raid3.c index 3f037cdbec8..cd0aa65b14c 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 f396cc3e9d1..a82d3882e8a 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 952ac2bf9f7..b3a42ff7bbb 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);