Make all the gnop parameters optional in the request from userland,

filling in the same defaults that the current userland module uses.
This allows an old geom_nop.so userland module to work with a new kernel.

Approved by:	imp (mentor)
Reviewed by:	cem
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D21972
This commit is contained in:
chs 2019-10-16 21:49:44 +00:00
parent 8356d793be
commit c0b77cf1b2

View File

@ -497,15 +497,28 @@ static void
g_nop_ctl_create(struct gctl_req *req, struct g_class *mp)
{
struct g_provider *pp;
intmax_t *error, *rfailprob, *wfailprob, *count_until_fail, *offset,
*secsize, *size, *stripesize, *stripeoffset, *delaymsec,
*rdelayprob, *wdelayprob;
intmax_t *val, error, rfailprob, wfailprob, count_until_fail, offset,
secsize, size, stripesize, stripeoffset, delaymsec,
rdelayprob, wdelayprob;
const char *name, *physpath;
char param[16];
int i, *nargs;
g_topology_assert();
error = -1;
rfailprob = -1;
wfailprob = -1;
count_until_fail = -1;
offset = 0;
secsize = 0;
size = 0;
stripesize = 0;
stripeoffset = 0;
delaymsec = -1;
rdelayprob = -1;
wdelayprob = -1;
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
if (nargs == NULL) {
gctl_error(req, "No '%s' argument", "nargs");
@ -515,110 +528,99 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "Missing device(s).");
return;
}
error = gctl_get_paraml(req, "error", sizeof(*error));
if (error == NULL) {
gctl_error(req, "No '%s' argument", "error");
return;
val = gctl_get_paraml_opt(req, "error", sizeof(*val));
if (val != NULL) {
error = *val;
}
rfailprob = gctl_get_paraml(req, "rfailprob", sizeof(*rfailprob));
if (rfailprob == NULL) {
gctl_error(req, "No '%s' argument", "rfailprob");
return;
val = gctl_get_paraml_opt(req, "rfailprob", sizeof(*val));
if (val != NULL) {
rfailprob = *val;
if (rfailprob < -1 || rfailprob > 100) {
gctl_error(req, "Invalid '%s' argument", "rfailprob");
return;
}
}
if (*rfailprob < -1 || *rfailprob > 100) {
gctl_error(req, "Invalid '%s' argument", "rfailprob");
return;
val = gctl_get_paraml_opt(req, "wfailprob", sizeof(*val));
if (val != NULL) {
wfailprob = *val;
if (wfailprob < -1 || wfailprob > 100) {
gctl_error(req, "Invalid '%s' argument", "wfailprob");
return;
}
}
wfailprob = gctl_get_paraml(req, "wfailprob", sizeof(*wfailprob));
if (wfailprob == NULL) {
gctl_error(req, "No '%s' argument", "wfailprob");
return;
val = gctl_get_paraml_opt(req, "delaymsec", sizeof(*val));
if (val != NULL) {
delaymsec = *val;
if (delaymsec < 1 && delaymsec != -1) {
gctl_error(req, "Invalid '%s' argument", "delaymsec");
return;
}
}
if (*wfailprob < -1 || *wfailprob > 100) {
gctl_error(req, "Invalid '%s' argument", "wfailprob");
return;
val = gctl_get_paraml_opt(req, "rdelayprob", sizeof(*val));
if (val != NULL) {
rdelayprob = *val;
if (rdelayprob < -1 || rdelayprob > 100) {
gctl_error(req, "Invalid '%s' argument", "rdelayprob");
return;
}
}
delaymsec = gctl_get_paraml(req, "delaymsec", sizeof(*delaymsec));
if (delaymsec == NULL) {
gctl_error(req, "No '%s' argument", "delaymsec");
return;
val = gctl_get_paraml_opt(req, "wdelayprob", sizeof(*val));
if (val != NULL) {
wdelayprob = *val;
if (wdelayprob < -1 || wdelayprob > 100) {
gctl_error(req, "Invalid '%s' argument", "wdelayprob");
return;
}
}
if (*delaymsec < 1 && *delaymsec != -1) {
gctl_error(req, "Invalid '%s' argument", "delaymsec");
return;
val = gctl_get_paraml_opt(req, "count_until_fail", sizeof(*val));
if (val != NULL) {
count_until_fail = *val;
if (count_until_fail < -1) {
gctl_error(req, "Invalid '%s' argument",
"count_until_fail");
return;
}
}
rdelayprob = gctl_get_paraml(req, "rdelayprob", sizeof(*rdelayprob));
if (rdelayprob == NULL) {
gctl_error(req, "No '%s' argument", "rdelayprob");
return;
val = gctl_get_paraml_opt(req, "offset", sizeof(*val));
if (val != NULL) {
offset = *val;
if (offset < 0) {
gctl_error(req, "Invalid '%s' argument", "offset");
return;
}
}
if (*rdelayprob < -1 || *rdelayprob > 100) {
gctl_error(req, "Invalid '%s' argument", "rdelayprob");
return;
val = gctl_get_paraml_opt(req, "size", sizeof(*val));
if (val != NULL) {
size = *val;
if (size < 0) {
gctl_error(req, "Invalid '%s' argument", "size");
return;
}
}
wdelayprob = gctl_get_paraml(req, "wdelayprob", sizeof(*wdelayprob));
if (wdelayprob == NULL) {
gctl_error(req, "No '%s' argument", "wdelayprob");
return;
val = gctl_get_paraml_opt(req, "secsize", sizeof(*val));
if (val != NULL) {
secsize = *val;
if (secsize < 0) {
gctl_error(req, "Invalid '%s' argument", "secsize");
return;
}
}
if (*wdelayprob < -1 || *wdelayprob > 100) {
gctl_error(req, "Invalid '%s' argument", "wdelayprob");
return;
val = gctl_get_paraml_opt(req, "stripesize", sizeof(*val));
if (val != NULL) {
stripesize = *val;
if (stripesize < 0) {
gctl_error(req, "Invalid '%s' argument", "stripesize");
return;
}
}
count_until_fail = gctl_get_paraml(req, "count_until_fail",
sizeof(*count_until_fail));
if (count_until_fail == NULL) {
gctl_error(req, "No '%s' argument", "count_until_fail");
return;
}
if (*count_until_fail < -1) {
gctl_error(req, "Invalid '%s' argument", "count_until_fail");
return;
}
offset = gctl_get_paraml(req, "offset", sizeof(*offset));
if (offset == NULL) {
gctl_error(req, "No '%s' argument", "offset");
return;
}
if (*offset < 0) {
gctl_error(req, "Invalid '%s' argument", "offset");
return;
}
size = gctl_get_paraml(req, "size", sizeof(*size));
if (size == NULL) {
gctl_error(req, "No '%s' argument", "size");
return;
}
if (*size < 0) {
gctl_error(req, "Invalid '%s' argument", "size");
return;
}
secsize = gctl_get_paraml(req, "secsize", sizeof(*secsize));
if (secsize == NULL) {
gctl_error(req, "No '%s' argument", "secsize");
return;
}
if (*secsize < 0) {
gctl_error(req, "Invalid '%s' argument", "secsize");
return;
}
stripesize = gctl_get_paraml(req, "stripesize", sizeof(*stripesize));
if (stripesize == NULL) {
gctl_error(req, "No '%s' argument", "stripesize");
return;
}
if (*stripesize < 0) {
gctl_error(req, "Invalid '%s' argument", "stripesize");
return;
}
stripeoffset = gctl_get_paraml(req, "stripeoffset", sizeof(*stripeoffset));
if (stripeoffset == NULL) {
gctl_error(req, "No '%s' argument", "stripeoffset");
return;
}
if (*stripeoffset < 0) {
gctl_error(req, "Invalid '%s' argument", "stripeoffset");
return;
val = gctl_get_paraml_opt(req, "stripeoffset", sizeof(*val));
if (val != NULL) {
stripeoffset = *val;
if (stripeoffset < 0) {
gctl_error(req, "Invalid '%s' argument",
"stripeoffset");
return;
}
}
physpath = gctl_get_asciiparam(req, "physpath");
@ -638,15 +640,15 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class *mp)
return;
}
if (g_nop_create(req, mp, pp,
*error == -1 ? EIO : (int)*error,
*count_until_fail == -1 ? 0 : (u_int)*count_until_fail,
*rfailprob == -1 ? 0 : (u_int)*rfailprob,
*wfailprob == -1 ? 0 : (u_int)*wfailprob,
*delaymsec == -1 ? 1 : (u_int)*delaymsec,
*rdelayprob == -1 ? 0 : (u_int)*rdelayprob,
*wdelayprob == -1 ? 0 : (u_int)*wdelayprob,
(off_t)*offset, (off_t)*size, (u_int)*secsize,
(off_t)*stripesize, (off_t)*stripeoffset,
error == -1 ? EIO : (int)error,
count_until_fail == -1 ? 0 : (u_int)count_until_fail,
rfailprob == -1 ? 0 : (u_int)rfailprob,
wfailprob == -1 ? 0 : (u_int)wfailprob,
delaymsec == -1 ? 1 : (u_int)delaymsec,
rdelayprob == -1 ? 0 : (u_int)rdelayprob,
wdelayprob == -1 ? 0 : (u_int)wdelayprob,
(off_t)offset, (off_t)size, (u_int)secsize,
(off_t)stripesize, (off_t)stripeoffset,
physpath) != 0) {
return;
}
@ -658,14 +660,22 @@ g_nop_ctl_configure(struct gctl_req *req, struct g_class *mp)
{
struct g_nop_softc *sc;
struct g_provider *pp;
intmax_t *delaymsec, *error, *rdelayprob, *rfailprob, *wdelayprob,
*wfailprob, *count_until_fail;
intmax_t *val, delaymsec, error, rdelayprob, rfailprob, wdelayprob,
wfailprob, count_until_fail;
const char *name;
char param[16];
int i, *nargs;
g_topology_assert();
count_until_fail = -1;
delaymsec = -1;
error = -1;
rdelayprob = -1;
rfailprob = -1;
wdelayprob = -1;
wfailprob = -1;
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
if (nargs == NULL) {
gctl_error(req, "No '%s' argument", "nargs");
@ -675,62 +685,53 @@ g_nop_ctl_configure(struct gctl_req *req, struct g_class *mp)
gctl_error(req, "Missing device(s).");
return;
}
error = gctl_get_paraml(req, "error", sizeof(*error));
if (error == NULL) {
gctl_error(req, "No '%s' argument", "error");
return;
val = gctl_get_paraml_opt(req, "error", sizeof(*val));
if (val != NULL) {
error = *val;
}
count_until_fail = gctl_get_paraml(req, "count_until_fail",
sizeof(*count_until_fail));
if (count_until_fail == NULL) {
gctl_error(req, "No '%s' argument", "count_until_fail");
return;
val = gctl_get_paraml_opt(req, "count_until_fail", sizeof(*val));
if (val != NULL) {
count_until_fail = *val;
}
rfailprob = gctl_get_paraml(req, "rfailprob", sizeof(*rfailprob));
if (rfailprob == NULL) {
gctl_error(req, "No '%s' argument", "rfailprob");
return;
val = gctl_get_paraml_opt(req, "rfailprob", sizeof(*val));
if (val != NULL) {
rfailprob = *val;
if (rfailprob < -1 || rfailprob > 100) {
gctl_error(req, "Invalid '%s' argument", "rfailprob");
return;
}
}
if (*rfailprob < -1 || *rfailprob > 100) {
gctl_error(req, "Invalid '%s' argument", "rfailprob");
return;
val = gctl_get_paraml_opt(req, "wfailprob", sizeof(*val));
if (val != NULL) {
wfailprob = *val;
if (wfailprob < -1 || wfailprob > 100) {
gctl_error(req, "Invalid '%s' argument", "wfailprob");
return;
}
}
wfailprob = gctl_get_paraml(req, "wfailprob", sizeof(*wfailprob));
if (wfailprob == NULL) {
gctl_error(req, "No '%s' argument", "wfailprob");
return;
val = gctl_get_paraml_opt(req, "delaymsec", sizeof(*val));
if (val != NULL) {
delaymsec = *val;
if (delaymsec < 1 && delaymsec != -1) {
gctl_error(req, "Invalid '%s' argument", "delaymsec");
return;
}
}
if (*wfailprob < -1 || *wfailprob > 100) {
gctl_error(req, "Invalid '%s' argument", "wfailprob");
return;
val = gctl_get_paraml_opt(req, "rdelayprob", sizeof(*val));
if (val != NULL) {
rdelayprob = *val;
if (rdelayprob < -1 || rdelayprob > 100) {
gctl_error(req, "Invalid '%s' argument", "rdelayprob");
return;
}
}
delaymsec = gctl_get_paraml(req, "delaymsec", sizeof(*delaymsec));
if (delaymsec == NULL) {
gctl_error(req, "No '%s' argument", "delaymsec");
return;
}
if (*delaymsec < 1 && *delaymsec != -1) {
gctl_error(req, "Invalid '%s' argument", "delaymsec");
return;
}
rdelayprob = gctl_get_paraml(req, "rdelayprob", sizeof(*rdelayprob));
if (rdelayprob == NULL) {
gctl_error(req, "No '%s' argument", "rdelayprob");
return;
}
if (*rdelayprob < -1 || *rdelayprob > 100) {
gctl_error(req, "Invalid '%s' argument", "rdelayprob");
return;
}
wdelayprob = gctl_get_paraml(req, "wdelayprob", sizeof(*wdelayprob));
if (wdelayprob == NULL) {
gctl_error(req, "No '%s' argument", "wdelayprob");
return;
}
if (*wdelayprob < -1 || *wdelayprob > 100) {
gctl_error(req, "Invalid '%s' argument", "wdelayprob");
return;
val = gctl_get_paraml_opt(req, "wdelayprob", sizeof(*val));
if (val != NULL) {
wdelayprob = *val;
if (wdelayprob < -1 || wdelayprob > 100) {
gctl_error(req, "Invalid '%s' argument", "wdelayprob");
return;
}
}
for (i = 0; i < *nargs; i++) {
@ -749,20 +750,20 @@ g_nop_ctl_configure(struct gctl_req *req, struct g_class *mp)
return;
}
sc = pp->geom->softc;
if (*error != -1)
sc->sc_error = (int)*error;
if (*rfailprob != -1)
sc->sc_rfailprob = (u_int)*rfailprob;
if (*wfailprob != -1)
sc->sc_wfailprob = (u_int)*wfailprob;
if (*rdelayprob != -1)
sc->sc_rdelayprob = (u_int)*rdelayprob;
if (*wdelayprob != -1)
sc->sc_wdelayprob = (u_int)*wdelayprob;
if (*delaymsec != -1)
sc->sc_delaymsec = (u_int)*delaymsec;
if (*count_until_fail != -1)
sc->sc_count_until_fail = (u_int)*count_until_fail;
if (error != -1)
sc->sc_error = (int)error;
if (rfailprob != -1)
sc->sc_rfailprob = (u_int)rfailprob;
if (wfailprob != -1)
sc->sc_wfailprob = (u_int)wfailprob;
if (rdelayprob != -1)
sc->sc_rdelayprob = (u_int)rdelayprob;
if (wdelayprob != -1)
sc->sc_wdelayprob = (u_int)wdelayprob;
if (delaymsec != -1)
sc->sc_delaymsec = (u_int)delaymsec;
if (count_until_fail != -1)
sc->sc_count_until_fail = (u_int)count_until_fail;
}
}