Teach NOP GEOM class how to gather the following statistics:

- number of read I/O requests,
- number of write I/O requests,
- number of read bytes,
- number of written bytes.
Add 'reset' subcommand for resetting statistics.
This commit is contained in:
Pawel Jakub Dawidek 2005-12-08 23:00:31 +00:00
parent c46a4f9afd
commit df3d5a19fc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=153250
4 changed files with 99 additions and 9 deletions

View File

@ -68,5 +68,8 @@ struct g_command class_commands[] = {
},
"[-fv] prov ..."
},
{ "reset", G_FLAG_VERBOSE, NULL, G_NULL_OPTS,
"[-v] prov ..."
},
G_CMD_SENTINEL
};

View File

@ -49,6 +49,10 @@
.Op Fl fv
.Ar prov ...
.Nm
.Cm reset
.Op Fl v
.Ar prov ...
.Nm
.Cm list
.Nm
.Cm status
@ -62,7 +66,10 @@ The
utility is used for setting up transparent providers on existing ones.
Its main purpose is testing other GEOM classes, as it allows forced provider
removal and I/O error simulation with a given probability.
It is also a good starting point for implementing new GEOM classes.
It also gathers the following statistics: number of read requests, number of
write requests, number of read bytes and number of wrote bytes.
In addition, it can be used as a good starting point for implementing new GEOM
class.
.Pp
The first argument to
.Nm
@ -77,13 +84,11 @@ The kernel module
will be loaded if it is not loaded already.
.It Cm configure
Configure existing transparent provider.
At the moment it is only used
for changing failure probability.
The kernel module
.Pa geom_nop.ko
will be loaded if it is not loaded already.
At the moment it is only used for changing failure probability.
.It Cm destroy
Turn off the given transparent providers.
.It Cm reset
Reset statistics for the given transparent providers.
.It Cm list
See
.Xr geom 8 .
@ -139,6 +144,17 @@ with 50% failure probability, and how to destroy it.
gnop create -v -f 50 da0
gnop destroy -v da0.nop
.Ed
.Pp
The traffic statistics for the given transparent providers we can get with
.Cm list
command.
Example below shows how can we obtain number of bytes written with
.Xr newfs 8 :
.Bd -literal -offset indent
gnop create da0
newfs /dev/da0.nop
gnop list
.Ed
.Sh SEE ALSO
.Xr geom 4 ,
.Xr geom 8

View File

@ -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;
@ -448,6 +462,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)
{
@ -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);

View File

@ -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 */