Index: lib/geom/nop/gnop.8 =================================================================== --- lib/geom/nop/gnop.8 +++ lib/geom/nop/gnop.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 2, 2019 +.Dd December 3, 2019 .Dt GNOP 8 .Os .Sh NAME @@ -123,8 +123,8 @@ Additional options: .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%. +Specifies the number of I/O requests to allow before setting the read, write and +delay failure probabilities. .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: sys/geom/nop/g_nop.c =================================================================== --- sys/geom/nop/g_nop.c +++ sys/geom/nop/g_nop.c @@ -194,6 +194,23 @@ g_free(data); } +static void +g_nop_fetch_delays(struct g_nop_softc *sc, u_int *failprobp, u_int *delayprobp, + u_int *delaytimep) +{ + + if (sc->sc_count_until_fail != 0) { + sc->sc_count_until_fail -= 1; + *failprobp = 0; + *delayprobp = 0; + *delaytimep = 0; + } else { + *failprobp = sc->sc_rfailprob; + *delayprobp = sc->sc_rdelayprob; + *delaytimep = sc->sc_delaymsec; + } +} + static void g_nop_start(struct bio *bp) { @@ -210,24 +227,16 @@ 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++; sc->sc_readbytes += bp->bio_length; - failprob = sc->sc_rfailprob; - delayprob = sc->sc_rdelayprob; - delaytime = sc->sc_delaymsec; + g_nop_fetch_delays(sc, &failprob, &delayprob, &delaytime); break; case BIO_WRITE: sc->sc_writes++; sc->sc_wrotebytes += bp->bio_length; - failprob = sc->sc_wfailprob; - delayprob = sc->sc_wdelayprob; - delaytime = sc->sc_delaymsec; + g_nop_fetch_delays(sc, &failprob, &delayprob, &delaytime); break; case BIO_DELETE: sc->sc_deletes++; @@ -261,6 +270,7 @@ break; } mtx_unlock(&sc->sc_lock); + if (failprob > 0) { u_int rval;