diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/geom/nop/g_nop.c | 69 | ||||
-rw-r--r-- | sys/geom/nop/g_nop.h | 8 |
2 files changed, 74 insertions, 3 deletions
diff --git a/sys/geom/nop/g_nop.c b/sys/geom/nop/g_nop.c index 1a2cb3b..da9abf5 100644 --- a/sys/geom/nop/g_nop.c +++ b/sys/geom/nop/g_nop.c @@ -86,6 +86,16 @@ g_nop_start(struct bio *bp) g_io_deliver(bp, ENOMEM); return; } + switch (bp->bio_cmd) { + case BIO_READ: + sc->sc_reads++; + sc->sc_readbytes += bp->bio_length; + break; + case BIO_WRITE: + sc->sc_writes++; + sc->sc_wrotebytes += bp->bio_length; + break; + } if (sc->sc_failprob > 0) { u_int rval; @@ -176,6 +186,10 @@ g_nop_create(struct gctl_req *req, struct g_class *mp, struct g_provider *pp, sc = g_malloc(sizeof(*sc), M_WAITOK); sc->sc_offset = offset; sc->sc_failprob = failprob; + sc->sc_reads = 0; + sc->sc_writes = 0; + sc->sc_readbytes = 0; + sc->sc_wrotebytes = 0; gp->softc = sc; gp->start = g_nop_start; gp->orphan = g_nop_orphan; @@ -449,6 +463,50 @@ g_nop_ctl_destroy(struct gctl_req *req, struct g_class *mp) } static void +g_nop_ctl_reset(struct gctl_req *req, struct g_class *mp) +{ + struct g_nop_softc *sc; + struct g_provider *pp; + const char *name; + char param[16]; + int i, *nargs; + + g_topology_assert(); + + nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); + if (nargs == NULL) { + gctl_error(req, "No '%s' argument", "nargs"); + return; + } + if (*nargs <= 0) { + gctl_error(req, "Missing device(s)."); + return; + } + + for (i = 0; i < *nargs; i++) { + snprintf(param, sizeof(param), "arg%d", i); + name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%d' argument", i); + return; + } + if (strncmp(name, "/dev/", strlen("/dev/")) == 0) + name += strlen("/dev/"); + pp = g_provider_by_name(name); + if (pp == NULL || pp->geom->class != mp) { + G_NOP_DEBUG(1, "Provider %s is invalid.", name); + gctl_error(req, "Provider %s is invalid.", name); + return; + } + sc = pp->geom->softc; + sc->sc_reads = 0; + sc->sc_writes = 0; + sc->sc_readbytes = 0; + sc->sc_wrotebytes = 0; + } +} + +static void g_nop_config(struct gctl_req *req, struct g_class *mp, const char *verb) { uint32_t *version; @@ -474,6 +532,9 @@ g_nop_config(struct gctl_req *req, struct g_class *mp, const char *verb) } else if (strcmp(verb, "destroy") == 0) { g_nop_ctl_destroy(req, mp); return; + } else if (strcmp(verb, "reset") == 0) { + g_nop_ctl_reset(req, mp); + return; } gctl_error(req, "Unknown verb."); @@ -490,7 +551,13 @@ g_nop_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, sc = gp->softc; sbuf_printf(sb, "%s<Offset>%jd</Offset>\n", indent, (intmax_t)sc->sc_offset); - sbuf_printf(sb, "%s<Failprob>%u</Failprob>\n", indent, sc->sc_failprob); + sbuf_printf(sb, "%s<FailProb>%u</FailProb>\n", indent, sc->sc_failprob); + sbuf_printf(sb, "%s<Reads>%ju</Reads>\n", indent, sc->sc_reads); + sbuf_printf(sb, "%s<Writes>%ju</Writes>\n", indent, sc->sc_writes); + sbuf_printf(sb, "%s<ReadBytes>%ju</ReadBytess>\n", indent, + sc->sc_readbytes); + sbuf_printf(sb, "%s<WroteBytes>%ju</WroteBytes>\n", indent, + sc->sc_writebytes); } DECLARE_GEOM_CLASS(g_nop_class, g_nop); diff --git a/sys/geom/nop/g_nop.h b/sys/geom/nop/g_nop.h index 378c3ef..e8df888 100644 --- a/sys/geom/nop/g_nop.h +++ b/sys/geom/nop/g_nop.h @@ -55,8 +55,12 @@ } while (0) struct g_nop_softc { - off_t sc_offset; - u_int sc_failprob; + off_t sc_offset; + u_int sc_failprob; + uintmax_t sc_reads; + uintmax_t sc_writes; + uintmax_t sc_readbytes; + uintmax_t sc_wrotebytes; }; #endif /* _KERNEL */ |