]> xenbits.xensource.com Git - freebsd.git/commitdiff
Add a "count_until_fail" option to gnop, which says to start failing
authorchs <chs@FreeBSD.org>
Fri, 13 Sep 2019 23:03:56 +0000 (23:03 +0000)
committerchs <chs@FreeBSD.org>
Fri, 13 Sep 2019 23:03:56 +0000 (23:03 +0000)
I/O requests after the given number have been allowed though.

Approved by:    imp (mentor)
Reviewed by:    rpokala kib 0mp mckusick
Sponsored by:   Netflix
Differential Revision:  https://reviews.freebsd.org/D21593

lib/geom/nop/geom_nop.c
lib/geom/nop/gnop.8
sys/geom/nop/g_nop.c
sys/geom/nop/g_nop.h

index ea7afdce0ca083e46199bd008da625130e8813e9..346a721d3127d865ae0f263b8370f5951883d9c7 100644 (file)
@@ -43,6 +43,7 @@ uint32_t version = G_NOP_VERSION;
 struct g_command class_commands[] = {
        { "create", G_FLAG_VERBOSE | G_FLAG_LOADKLD, NULL,
            {
+               { 'c', "count_until_fail", "-1", G_TYPE_NUMBER },
                { 'd', "delaymsec", "-1", G_TYPE_NUMBER },
                { 'e', "error", "-1", G_TYPE_NUMBER },
                { 'o', "offset", "0", G_TYPE_NUMBER },
@@ -57,12 +58,14 @@ struct g_command class_commands[] = {
                { 'z', "physpath", G_NOP_PHYSPATH_PASSTHROUGH, G_TYPE_STRING },
                G_OPT_SENTINEL
            },
-           "[-v] [-d delaymsec] [-e error] [-o offset] [-p stripesize] "
-           "[-P stripeoffset] [-q rdelayprob] [-r rfailprob] [-s size] "
-           "[-S secsize] [-w wfailprob] [-x wdelayprob] [-z physpath] dev ..."
+           "[-v] [-c count_until_fail] [-d delaymsec] [-e error] [-o offset] "
+           "[-p stripesize] [-P stripeoffset] [-q rdelayprob] [-r rfailprob] "
+           "[-s size]  [-S secsize] [-w wfailprob] [-x wdelayprob] "
+           "[-z physpath] dev ..."
        },
        { "configure", G_FLAG_VERBOSE, NULL,
            {
+               { 'c', "count_until_fail", "-1", G_TYPE_NUMBER },
                { 'd', "delaymsec", "-1", G_TYPE_NUMBER },
                { 'e', "error", "-1", G_TYPE_NUMBER },
                { 'q', "rdelayprob", "-1", G_TYPE_NUMBER },
@@ -71,8 +74,9 @@ struct g_command class_commands[] = {
                { 'x', "wdelayprob", "-1", G_TYPE_NUMBER },
                G_OPT_SENTINEL
            },
-           "[-v] [-d delaymsec] [-e error] [-q rdelayprob] [-r rfailprob] "
-           "[-w wfailprob] [-x wdelayprob] prov ..."
+           "[-v] [-c count_until_fail] [-d delaymsec] [-e error] "
+           "[-q rdelayprob] [-r rfailprob] [-w wfailprob] [-x wdelayprob] "
+           "prov ..."
        },
        { "destroy", G_FLAG_VERBOSE, NULL,
            {
index ef6c44bc5297466bb99bf16b8168c4ed537e6f86..12e60972856680cffe9486d6a5657cf7f4b8269f 100644 (file)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 31, 2019
+.Dd September 13, 2019
 .Dt GNOP 8
 .Os
 .Sh NAME
@@ -34,6 +34,7 @@
 .Nm
 .Cm create
 .Op Fl v
+.Op Fl c Ar count_until_fail
 .Op Fl d Ar delaymsec
 .Op Fl e Ar error
 .Op Fl o Ar offset
@@ -50,6 +51,7 @@
 .Nm
 .Cm configure
 .Op Fl v
+.Op Fl c Ar count_until_fail
 .Op Fl d Ar delaymsec
 .Op Fl e Ar error
 .Op Fl q Ar rdelayprob
@@ -118,7 +120,10 @@ See
 .El
 .Pp
 Additional options:
-.Bl -tag -width ".Fl r Ar rfailprob"
+.Bl -tag -width "-c count_until_fail"
+.It Fl c Ar count_until_fail
+Specifies the number of I/O requests to allow before setting the read and write
+failure probabilities to 100%.
 .It Fl d Ar delaymsec
 Specifies the delay of the requests in milliseconds.
 Note that requests will be delayed before they are sent to the backing device.
index 6c7706b52cd35550c39789cf4eae5922fbe2882d..e8152030f51800f86a9266d438dbc2dbd5fde883 100644 (file)
@@ -195,6 +195,10 @@ g_nop_start(struct bio *bp)
 
        G_NOP_LOGREQ(bp, "Request received.");
        mtx_lock(&sc->sc_lock);
+       if (sc->sc_count_until_fail != 0 && --sc->sc_count_until_fail == 0) {
+               sc->sc_rfailprob = 100;
+               sc->sc_wfailprob = 100;
+       }
        switch (bp->bio_cmd) {
        case BIO_READ:
                sc->sc_reads++;
@@ -308,9 +312,10 @@ g_nop_access(struct g_provider *pp, int dr, int dw, int de)
 
 static int
 g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp,
-    int ioerror, u_int rfailprob, u_int wfailprob, u_int delaymsec, u_int rdelayprob,
-    u_int wdelayprob, off_t offset, off_t size, u_int secsize, off_t stripesize,
-    off_t stripeoffset, const char *physpath)
+    int ioerror, u_int count_until_fail, u_int rfailprob, u_int wfailprob,
+    u_int delaymsec, u_int rdelayprob, u_int wdelayprob, off_t offset,
+    off_t size, u_int secsize, off_t stripesize, off_t stripeoffset,
+    const char *physpath)
 {
        struct g_nop_softc *sc;
        struct g_geom *gp;
@@ -386,6 +391,7 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp,
        } else
                sc->sc_physpath = NULL;
        sc->sc_error = ioerror;
+       sc->sc_count_until_fail = count_until_fail;
        sc->sc_rfailprob = rfailprob;
        sc->sc_wfailprob = wfailprob;
        sc->sc_delaymsec = delaymsec;
@@ -491,8 +497,9 @@ static void
 g_nop_ctl_create(struct gctl_req *req, struct g_class *mp)
 {
        struct g_provider *pp;
-       intmax_t *error, *rfailprob, *wfailprob, *offset, *secsize, *size,
-           *stripesize, *stripeoffset, *delaymsec, *rdelayprob, *wdelayprob;
+       intmax_t *error, *rfailprob, *wfailprob, *count_until_fail, *offset,
+           *secsize, *size, *stripesize, *stripeoffset, *delaymsec,
+           *rdelayprob, *wdelayprob;
        const char *name, *physpath;
        char param[16];
        int i, *nargs;
@@ -558,6 +565,16 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class *mp)
                gctl_error(req, "Invalid '%s' argument", "wdelayprob");
                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");
@@ -622,6 +639,7 @@ g_nop_ctl_create(struct gctl_req *req, struct g_class *mp)
                }
                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,
@@ -640,7 +658,8 @@ 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;
+       intmax_t *delaymsec, *error, *rdelayprob, *rfailprob, *wdelayprob,
+           *wfailprob, *count_until_fail;
        const char *name;
        char param[16];
        int i, *nargs;
@@ -661,6 +680,12 @@ g_nop_ctl_configure(struct gctl_req *req, struct g_class *mp)
                gctl_error(req, "No '%s' argument", "error");
                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;
+       }
        rfailprob = gctl_get_paraml(req, "rfailprob", sizeof(*rfailprob));
        if (rfailprob == NULL) {
                gctl_error(req, "No '%s' argument", "rfailprob");
@@ -736,6 +761,8 @@ g_nop_ctl_configure(struct gctl_req *req, struct g_class *mp)
                        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;
        }
 }
 
@@ -904,6 +931,8 @@ g_nop_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
        sbuf_printf(sb, "%s<WriteDelayedProb>%u</WriteDelayedProb>\n", indent,
            sc->sc_wdelayprob);
        sbuf_printf(sb, "%s<Delay>%d</Delay>\n", indent, sc->sc_delaymsec);
+       sbuf_printf(sb, "%s<CountUntilFail>%u</CountUntilFail>\n", indent,
+           sc->sc_count_until_fail);
        sbuf_printf(sb, "%s<Error>%d</Error>\n", indent, sc->sc_error);
        sbuf_printf(sb, "%s<Reads>%ju</Reads>\n", indent, sc->sc_reads);
        sbuf_printf(sb, "%s<Writes>%ju</Writes>\n", indent, sc->sc_writes);
index d7649ac1c23f93a74dc4fd5213b5a6ffbfcb676e..f65a7544c4cab0c804d35b724e3035dc6986f46e 100644 (file)
@@ -62,6 +62,7 @@ struct g_nop_softc {
        u_int                    sc_delaymsec;
        u_int                    sc_rdelayprob;
        u_int                    sc_wdelayprob;
+       u_int                    sc_count_until_fail;
        uintmax_t                sc_reads;
        uintmax_t                sc_writes;
        uintmax_t                sc_deletes;