Make i/o statistics collection more generic, include tape drives and

nfs mounts in the set of devices that statistics will be reported on.
This commit is contained in:
blymn 2006-04-14 13:09:05 +00:00
parent 650c02ea97
commit 3c0adb7d99
23 changed files with 245 additions and 558 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fd.c,v 1.25 2006/03/26 04:32:33 thorpej Exp $ */
/* $NetBSD: fd.c,v 1.26 2006/04/14 13:09:05 blymn Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -89,7 +89,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.25 2006/03/26 04:32:33 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.26 2006/04/14 13:09:05 blymn Exp $");
#include "opt_ddb.h"
@ -1030,7 +1030,7 @@ loop:
fd->sc_cylin = -1;
fdc->sc_state = SEEKWAIT;
fd->sc_dk.dk_seek++;
iostat_seek(fd->sc_dk.dk_stats);
disk_busy(&fd->sc_dk);
callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: fd.c,v 1.25 2006/02/23 05:37:46 thorpej Exp $ */
/* $NetBSD: fd.c,v 1.26 2006/04/14 13:09:05 blymn Exp $ */
/* $OpenBSD: fd.c,v 1.6 1998/10/03 21:18:57 millert Exp $ */
/* NetBSD: fd.c,v 1.78 1995/07/04 07:23:09 mycroft Exp */
@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.25 2006/02/23 05:37:46 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.26 2006/04/14 13:09:05 blymn Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -831,7 +831,7 @@ loop:
fd->sc_cylin = -1;
fdc->sc_state = SEEKWAIT;
fd->sc_dk.dk_seek++;
iostat_seek(fd->sc_dk.dk_stats);
disk_busy(&fd->sc_dk);
callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: hdfd.c,v 1.49 2006/02/23 05:37:46 thorpej Exp $ */
/* $NetBSD: hdfd.c,v 1.50 2006/04/14 13:09:05 blymn Exp $ */
/*-
* Copyright (c) 1996 Leo Weppelman
@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: hdfd.c,v 1.49 2006/02/23 05:37:46 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: hdfd.c,v 1.50 2006/04/14 13:09:05 blymn Exp $");
#include "opt_ddb.h"
@ -1050,7 +1050,7 @@ loop:
fd->sc_cylin = -1;
fdc->sc_state = SEEKWAIT;
fd->sc_dk.dk_seek++;
iostat_seek(fd->sc_dk.dk_stats);
disk_busy(&fd->sc_dk);
callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: rd.c,v 1.73 2006/03/29 16:03:37 tsutsui Exp $ */
/* $NetBSD: rd.c,v 1.74 2006/04/14 13:09:05 blymn Exp $ */
/*-
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
@ -117,7 +117,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rd.c,v 1.73 2006/03/29 16:03:37 tsutsui Exp $");
__KERNEL_RCSID(0, "$NetBSD: rd.c,v 1.74 2006/04/14 13:09:05 blymn Exp $");
#include "opt_useleds.h"
#include "rnd.h"
@ -836,7 +836,7 @@ again:
/* Instrumentation. */
disk_busy(&rs->sc_dkdev);
rs->sc_dkdev.dk_seek++;
iostat_seek(rs->sc_dkdev.dk_stats);
#ifdef DEBUG
if (rddebug & RDB_IO)

View File

@ -1,4 +1,4 @@
/* $NetBSD: hp.c,v 1.5 2006/03/28 17:38:26 thorpej Exp $ */
/* $NetBSD: hp.c,v 1.6 2006/04/14 13:09:05 blymn Exp $ */
/*
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
* All rights reserved.
@ -265,7 +265,7 @@ hpstart(struct rh_device *md)
* Collect statistics.
*/
disk_busy(&sc->sc_disk);
sc->sc_disk.dk_seek++;
iostat_seek(sc->sc_disk.dk_stats);
bn = bp->b_rawblkno;
if (bn) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: fd.c,v 1.125 2006/02/23 05:37:48 thorpej Exp $ */
/* $NetBSD: fd.c,v 1.126 2006/04/14 13:09:05 blymn Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -108,7 +108,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.125 2006/02/23 05:37:48 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.126 2006/04/14 13:09:05 blymn Exp $");
#include "opt_ddb.h"
#include "opt_md.h"
@ -1490,7 +1490,7 @@ loop:
fdc->sc_state = SEEKWAIT;
fdc->sc_nstat = 0;
fd->sc_dk.dk_seek++;
iostat_seek(fd->sc_dk.dk_stats);
disk_busy(&fd->sc_dk);
callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: tctrl.c,v 1.31 2006/03/08 01:17:49 macallan Exp $ */
/* $NetBSD: tctrl.c,v 1.32 2006/04/14 13:09:05 blymn Exp $ */
/*-
* Copyright (c) 1998, 2005, 2006 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tctrl.c,v 1.31 2006/03/08 01:17:49 macallan Exp $");
__KERNEL_RCSID(0, "$NetBSD: tctrl.c,v 1.32 2006/04/14 13:09:05 blymn Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -1532,18 +1532,18 @@ tctrl_event_thread(void *v)
tsleep(&sc->sc_events, PWAIT, "probe_disk", hz);
}
printf("found %s\n", sd->sc_dev.dv_xname);
rcount = sd->sc_dk.dk_rxfer;
wcount = sd->sc_dk.dk_wxfer;
rcount = sd->sc_dk.dk_stats->rxfer;
wcount = sd->sc_dk.dk_stats->wxfer;
tctrl_read_event_status(sc);
while (1) {
tsleep(&sc->sc_events, PWAIT, "tctrl_event", ticks);
s = splhigh();
if ((rcount != sd->sc_dk.dk_rxfer) ||
(wcount != sd->sc_dk.dk_wxfer)) {
rcount = sd->sc_dk.dk_rxfer;
wcount = sd->sc_dk.dk_wxfer;
if ((rcount != sd->sc_dk.dk_stats->rxfer) ||
(wcount != sd->sc_dk.dk_stats->wxfer)) {
rcount = sd->sc_dk.dk_stats->rxfer;
wcount = sd->sc_dk.dk_stats->wxfer;
sc->sc_lcdwanted |= TS102_LCD_DISK_ACTIVE;
} else
sc->sc_lcdwanted &= ~TS102_LCD_DISK_ACTIVE;

View File

@ -1,4 +1,4 @@
/* $NetBSD: hp.c,v 1.40 2006/03/28 17:38:28 thorpej Exp $ */
/* $NetBSD: hp.c,v 1.41 2006/04/14 13:09:05 blymn Exp $ */
/*
* Copyright (c) 1996 Ludd, University of Lule}, Sweden.
* All rights reserved.
@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: hp.c,v 1.40 2006/03/28 17:38:28 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: hp.c,v 1.41 2006/04/14 13:09:05 blymn Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -235,7 +235,7 @@ hpstart(struct mba_device *md)
* Collect statistics.
*/
disk_busy(&sc->sc_disk);
sc->sc_disk.dk_seek++;
iostat_seek(sc->sc_disk->dk_stats);
bn = bp->b_rawblkno;
if (bn) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: fd.c,v 1.69 2006/03/28 17:38:28 thorpej Exp $ */
/* $NetBSD: fd.c,v 1.70 2006/04/14 13:09:06 blymn Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.69 2006/03/28 17:38:28 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.70 2006/04/14 13:09:06 blymn Exp $");
#include "rnd.h"
#include "opt_ddb.h"
@ -1109,7 +1109,7 @@ loop:
fd->sc_cylin = -1;
fdc->sc_state = SEEKWAIT;
fd->sc_dk.dk_seek++;
iostat_seek(fd->sc_dk.dk_stats);
disk_busy(&fd->sc_dk);
callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);

View File

@ -1,4 +1,4 @@
# $NetBSD: files,v 1.769 2006/04/07 18:55:22 riz Exp $
# $NetBSD: files,v 1.770 2006/04/14 13:09:06 blymn Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@ -1250,6 +1250,7 @@ file kern/subr_blist.c vmswap
file kern/subr_bufq.c
file kern/subr_devsw.c
file kern/subr_disk.c
file kern/subr_iostat.c
file kern/subr_evcnt.c
file kern/subr_extent.c
file kern/subr_log.c

View File

@ -1,4 +1,4 @@
/* $NetBSD: rd.c,v 1.11 2006/03/29 06:33:50 thorpej Exp $ */
/* $NetBSD: rd.c,v 1.12 2006/04/14 13:09:06 blymn Exp $ */
/*-
* Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
@ -118,7 +118,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rd.c,v 1.11 2006/03/29 06:33:50 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: rd.c,v 1.12 2006/04/14 13:09:06 blymn Exp $");
#include "rnd.h"
@ -785,7 +785,7 @@ again:
sizeof(sc->sc_ioc)-1) == sizeof(sc->sc_ioc)-1) {
/* Instrumentation. */
disk_busy(&sc->sc_dk);
sc->sc_dk.dk_seek++;
iostat_seek(sc->sc_dk.dk_stats);
gpibawait(sc->sc_ic);
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: fd.c,v 1.66 2006/03/28 17:38:34 thorpej Exp $ */
/* $NetBSD: fd.c,v 1.67 2006/04/14 13:09:06 blymn Exp $ */
/*-
* Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
@ -88,7 +88,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.66 2006/03/28 17:38:34 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.67 2006/04/14 13:09:06 blymn Exp $");
#include "rnd.h"
#include "opt_ddb.h"
@ -1043,7 +1043,7 @@ loop:
fd->sc_cylin = -1;
fdc->sc_state = SEEKWAIT;
fd->sc_dk.dk_seek++;
iostat_seek(fd->sc_dk.dk_stats);
disk_busy(&fd->sc_dk);
callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: st.c,v 1.188 2006/03/30 16:09:28 thorpej Exp $ */
/* $NetBSD: st.c,v 1.189 2006/04/14 13:09:06 blymn Exp $ */
/*-
* Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@ -57,7 +57,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: st.c,v 1.188 2006/03/30 16:09:28 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: st.c,v 1.189 2006/04/14 13:09:06 blymn Exp $");
#include "opt_scsi.h"
@ -76,7 +76,7 @@ __KERNEL_RCSID(0, "$NetBSD: st.c,v 1.188 2006/03/30 16:09:28 thorpej Exp $");
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
#include <sys/tape.h>
#include <sys/iostat.h>
#include <sys/sysctl.h>
#include <dev/scsipi/scsi_spc.h>
@ -107,9 +107,6 @@ __KERNEL_RCSID(0, "$NetBSD: st.c,v 1.188 2006/03/30 16:09:28 thorpej Exp $");
#define ST_MOUNT_DELAY 0
#endif
struct tape *
drive_attach(char *name);
static dev_type_open(stopen);
static dev_type_close(stclose);
static dev_type_read(stread);
@ -352,14 +349,6 @@ static const struct scsipi_periphsw st_switch = {
stdone
};
/*
* A global list of all tape drives attached to the system. May grow or
* shrink over time.
*/
struct tapelist_head tapelist = TAILQ_HEAD_INITIALIZER(tapelist);
int tape_count = 0; /* number of drives in global tapelist */
struct simplelock tapelist_slock = SIMPLELOCK_INITIALIZER;
#if defined(ST_ENABLE_EARLYWARN)
#define ST_INIT_FLAGS ST_EARLYWARN
#else
@ -423,8 +412,9 @@ stattach(struct device *parent, struct st_softc *st, void *aux)
(st->flags & ST_READONLY) ? "protected" : "enabled");
}
st->stats = drive_attach(st->sc_dev.dv_xname);
st->stats = iostat_alloc(IOSTAT_TAPE);
st->stats->name = st->sc_dev.dv_xname;
#if NRND > 0
rnd_attach_source(&st->rnd_source, st->sc_dev.dv_xname,
RND_TYPE_TAPE, 0);
@ -480,16 +470,7 @@ stdetach(struct device *self, int flags)
vdevgone(bmaj, mn, mn+STNMINOR-1, VBLK);
vdevgone(cmaj, mn, mn+STNMINOR-1, VCHR);
if (tape_count == 0) {
printf("%s detach: tape_count already zero\n",
st->sc_dev.dv_xname);
} else {
simple_lock(&tapelist_slock);
TAILQ_REMOVE(&tapelist, st->stats, link);
tape_count--;
simple_unlock(&tapelist_slock);
free(st->stats, M_DEVBUF);
}
iostat_free(st->stats);
#if NRND > 0
/* Unhook the entropy source. */
@ -1187,7 +1168,7 @@ ststart(struct scsipi_periph *periph)
struct buf *bp;
struct scsi_rw_tape cmd;
struct scsipi_xfer *xs;
int flags, error, s;
int flags, error;
SC_DEBUG(periph, SCSIPI_DB2, ("ststart "));
/*
@ -1224,12 +1205,8 @@ ststart(struct scsipi_periph *periph)
if ((bp = BUFQ_PEEK(st->buf_queue)) == NULL)
return;
if (st->stats->busy++ == 0) {
s = splclock();
st->stats->timestamp = mono_time;
splx(s);
}
iostat_busy(st->stats);
/*
* only FIXEDBLOCK devices have pending I/O or space operations.
*/
@ -1356,8 +1333,6 @@ stdone(struct scsipi_xfer *xs, int error)
{
struct st_softc *st = (void *)xs->xs_periph->periph_dev;
struct buf *bp = xs->bp;
int s;
struct timeval st_time, diff_time;
if (bp) {
bp->b_error = error;
@ -1370,32 +1345,10 @@ stdone(struct scsipi_xfer *xs, int error)
else
st->flags &= ~ST_WRITTEN;
if (st->stats->busy-- == 0) {
/* this is not really fatal so we don't panic */
printf("%s: busy < 0, Oops.\n", st->stats->name);
st->stats->busy = 0;
} else {
s = splclock();
st_time = mono_time;
splx(s);
iostat_unbusy(st->stats, bp->b_bcount,
((bp->b_flags & B_READ) == B_READ));
timersub(&st_time, &st->stats->timestamp, &diff_time);
timeradd(&st->stats->time, &diff_time,
&st->stats->time);
st->stats->timestamp = st_time;
if (bp->b_bcount > 0) {
if ((bp->b_flags & B_READ) == B_WRITE) {
st->stats->wbytes += bp->b_bcount;
st->stats->wxfer++;
} else {
st->stats->rbytes += bp->b_bcount;
st->stats->rxfer++;
}
}
}
#if NRND > 0
rnd_add_uint32(&st->rnd_source, bp->b_blkno);
#endif
@ -2453,156 +2406,3 @@ stdump(dev_t dev, daddr_t blkno, caddr_t va, size_t size)
/* Not implemented. */
return (ENXIO);
}
int
sysctl_hw_tapenames(SYSCTLFN_ARGS)
{
char bf[TAPENAMELEN + 1];
char *where = oldp;
struct tape *tapep;
size_t needed, left, slen;
int error, first;
if (newp != NULL)
return (EPERM);
if (namelen != 0)
return (EINVAL);
first = 1;
error = 0;
needed = 0;
left = *oldlenp;
simple_lock(&tapelist_slock);
for (tapep = TAILQ_FIRST(&tapelist); tapep != NULL;
tapep = TAILQ_NEXT(tapep, link)) {
if (where == NULL)
needed += strlen(tapep->name) + 1;
else {
memset(bf, 0, sizeof(bf));
if (first) {
strncpy(bf, tapep->name, sizeof(bf));
first = 0;
} else {
bf[0] = ' ';
strncpy(bf + 1, tapep->name, sizeof(bf) - 1);
}
bf[TAPENAMELEN] = '\0';
slen = strlen(bf);
if (left < slen + 1)
break;
/* +1 to copy out the trailing NUL byte */
error = copyout(bf, where, slen + 1);
if (error)
break;
where += slen;
needed += slen;
left -= slen;
}
}
simple_unlock(&tapelist_slock);
*oldlenp = needed;
return (error);
}
int
sysctl_hw_tapestats(SYSCTLFN_ARGS)
{
struct tape_sysctl stape;
struct tape *tapep;
char *where = oldp;
size_t tocopy, left;
int error;
if (newp != NULL)
return (EPERM);
tocopy = name[0];
if (where == NULL) {
*oldlenp = tape_count * tocopy;
return (0);
}
error = 0;
left = *oldlenp;
memset(&stape, 0, sizeof(stape));
*oldlenp = 0;
simple_lock(&tapelist_slock);
TAILQ_FOREACH(tapep, &tapelist, link) {
if (left < tocopy)
break;
strncpy(stape.name, tapep->name, sizeof(stape.name));
stape.xfer = tapep->rxfer + tapep->wxfer;
stape.rxfer = tapep->rxfer;
stape.wxfer = tapep->wxfer;
stape.bytes = tapep->rbytes + tapep->wbytes;
stape.rbytes = tapep->rbytes;
stape.wbytes = tapep->wbytes;
stape.attachtime_sec = tapep->attachtime.tv_sec;
stape.attachtime_usec = tapep->attachtime.tv_usec;
stape.timestamp_sec = tapep->timestamp.tv_sec;
stape.timestamp_usec = tapep->timestamp.tv_usec;
stape.time_sec = tapep->time.tv_sec;
stape.time_usec = tapep->time.tv_usec;
stape.busy = tapep->busy;
error = copyout(&stape, where, min(tocopy, sizeof(stape)));
if (error)
break;
where += tocopy;
*oldlenp += tocopy;
left -= tocopy;
}
simple_unlock(&tapelist_slock);
return (error);
}
struct tape *
drive_attach(char *name)
{
struct tape *stats;
int s;
/* Allocate and initialise statistics */
stats = (struct tape *) malloc(sizeof(struct tape), M_DEVBUF,
M_WAITOK);
stats->rxfer = stats->wxfer = stats->rbytes = 0;
stats->wbytes = stats->busy = 0;
/*
* Set the attached timestamp.
*/
s = splclock();
stats->attachtime = mono_time;
splx(s);
/* and clear the utilisation time */
timerclear(&stats->time);
/* link the tape drive to the tapelist */
simple_lock(&tapelist_slock);
TAILQ_INSERT_TAIL(&tapelist, stats, link);
tape_count++;
simple_unlock(&tapelist_slock);
stats->name = name;
return stats;
}
SYSCTL_SETUP(sysctl_tape_stats_setup, "sysctl tape stats setup")
{
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_STRING, "tapenames",
SYSCTL_DESCR("List of tape devices present"),
sysctl_hw_tapenames, 0, NULL, 0,
CTL_HW, HW_TAPENAMES, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_STRUCT, "tapestats",
SYSCTL_DESCR("Statistics on tape drive operation"),
sysctl_hw_tapestats, 0, NULL, 0,
CTL_HW, HW_TAPESTATS, CTL_EOL);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: stvar.h,v 1.16 2005/12/11 12:23:51 christos Exp $ */
/* $NetBSD: stvar.h,v 1.17 2006/04/14 13:09:06 blymn Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -150,9 +150,9 @@ struct st_softc {
/* operations */
struct callout sc_callout; /* restarting the queue after */
/* transient error */
struct tape *stats; /* statistics for the drive */
struct io_stats *stats; /* statistics for the drive */
#if NRND > 0
rndsource_element_t rnd_source;
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_sysctl.c,v 1.65 2006/04/01 00:57:34 christos Exp $ */
/* $NetBSD: init_sysctl.c,v 1.66 2006/04/14 13:09:06 blymn Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.65 2006/04/01 00:57:34 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.66 2006/04/14 13:09:06 blymn Exp $");
#include "opt_sysv.h"
#include "opt_multiprocessor.h"
@ -913,18 +913,6 @@ SYSCTL_SETUP(sysctl_hw_setup, "sysctl hw subtree setup")
SYSCTL_DESCR("Software page size"),
NULL, PAGE_SIZE, NULL, 0,
CTL_HW, HW_PAGESIZE, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_STRING, "disknames",
SYSCTL_DESCR("List of disk devices present"),
sysctl_hw_disknames, 0, NULL, 0,
CTL_HW, HW_DISKNAMES, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_STRUCT, "diskstats",
SYSCTL_DESCR("Statistics on disk operation"),
sysctl_hw_diskstats, 0, NULL, 0,
CTL_HW, HW_DISKSTATS, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_STRING, "machine_arch",

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr_disk.c,v 1.73 2005/12/26 18:45:27 perry Exp $ */
/* $NetBSD: subr_disk.c,v 1.74 2006/04/14 13:09:06 blymn Exp $ */
/*-
* Copyright (c) 1996, 1997, 1999, 2000 The NetBSD Foundation, Inc.
@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.73 2005/12/26 18:45:27 perry Exp $");
__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.74 2006/04/14 13:09:06 blymn Exp $");
#include "opt_compat_netbsd.h"
@ -88,14 +88,6 @@ __KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.73 2005/12/26 18:45:27 perry Exp $")
#include <sys/sysctl.h>
#include <lib/libkern/libkern.h>
/*
* A global list of all disks attached to the system. May grow or
* shrink over time.
*/
struct disklist_head disklist = TAILQ_HEAD_INITIALIZER(disklist);
int disk_count; /* number of drives in global disklist */
struct simplelock disklist_slock = SIMPLELOCK_INITIALIZER;
/*
* Compute checksum for disk label.
*/
@ -172,27 +164,20 @@ diskerr(const struct buf *bp, const char *dname, const char *what, int pri,
}
/*
* Searches the disklist for the disk corresponding to the
* Searches the iostatlist for the disk corresponding to the
* name provided.
*/
struct disk *
disk_find(char *name)
{
struct disk *diskp;
struct io_stats *stat;
if ((name == NULL) || (disk_count <= 0))
return (NULL);
stat = iostat_find(name);
simple_lock(&disklist_slock);
for (diskp = TAILQ_FIRST(&disklist); diskp != NULL;
diskp = TAILQ_NEXT(diskp, dk_link))
if (strcmp(diskp->dk_name, name) == 0) {
simple_unlock(&disklist_slock);
return (diskp);
}
simple_unlock(&disklist_slock);
if ((stat != NULL) && (stat->type == IOSTAT_DISK))
return stat->parent;
return (NULL);
return (NULL);
}
static void
@ -211,8 +196,6 @@ disk_init0(struct disk *diskp)
static void
disk_attach0(struct disk *diskp)
{
int s;
/*
* Allocate and initialize the disklabel structures. Note that
* it's not safe to sleep here, since we're probably going to be
@ -228,19 +211,12 @@ disk_attach0(struct disk *diskp)
memset(diskp->dk_cpulabel, 0, sizeof(struct cpu_disklabel));
/*
* Set the attached timestamp.
* Set up the stats collection.
*/
s = splclock();
diskp->dk_attachtime = mono_time;
splx(s);
diskp->dk_stats = iostat_alloc(IOSTAT_DISK);
diskp->dk_stats->parent = (void *) diskp;
diskp->dk_stats->name = diskp->dk_name;
/*
* Link into the disklist.
*/
simple_lock(&disklist_slock);
TAILQ_INSERT_TAIL(&disklist, diskp, dk_link);
disk_count++;
simple_unlock(&disklist_slock);
}
static void
@ -248,14 +224,9 @@ disk_detach0(struct disk *diskp)
{
/*
* Remove from the disklist.
* Remove from the drivelist.
*/
if (disk_count == 0)
panic("disk_detach: disk_count == 0");
simple_lock(&disklist_slock);
TAILQ_REMOVE(&disklist, diskp, dk_link);
disk_count--;
simple_unlock(&disklist_slock);
iostat_free(diskp->dk_stats);
/*
* Free the space used by the disklabel structures.
@ -316,205 +287,22 @@ pseudo_disk_detach(struct disk *diskp)
disk_detach0(diskp);
}
/*
* Increment a disk's busy counter. If the counter is going from
* 0 to 1, set the timestamp.
* Mark the disk as busy for metrics collection.
*/
void
disk_busy(struct disk *diskp)
{
int s;
/*
* XXX We'd like to use something as accurate as microtime(),
* but that doesn't depend on the system TOD clock.
*/
if (diskp->dk_busy++ == 0) {
s = splclock();
diskp->dk_timestamp = mono_time;
splx(s);
}
iostat_busy(diskp->dk_stats);
}
/*
* Decrement a disk's busy counter, increment the byte count, total busy
* time, and reset the timestamp.
* Finished disk operations, gather metrics.
*/
void
disk_unbusy(struct disk *diskp, long bcount, int read)
{
int s;
struct timeval dv_time, diff_time;
if (diskp->dk_busy-- == 0) {
printf("%s: dk_busy < 0\n", diskp->dk_name);
panic("disk_unbusy");
}
s = splclock();
dv_time = mono_time;
splx(s);
timersub(&dv_time, &diskp->dk_timestamp, &diff_time);
timeradd(&diskp->dk_time, &diff_time, &diskp->dk_time);
diskp->dk_timestamp = dv_time;
if (bcount > 0) {
if (read) {
diskp->dk_rbytes += bcount;
diskp->dk_rxfer++;
} else {
diskp->dk_wbytes += bcount;
diskp->dk_wxfer++;
}
}
}
/*
* Reset the metrics counters on the given disk. Note that we cannot
* reset the busy counter, as it may case a panic in disk_unbusy().
* We also must avoid playing with the timestamp information, as it
* may skew any pending transfer results.
*/
void
disk_resetstat(struct disk *diskp)
{
int s = splbio(), t;
diskp->dk_rxfer = 0;
diskp->dk_rbytes = 0;
diskp->dk_wxfer = 0;
diskp->dk_wbytes = 0;
t = splclock();
diskp->dk_attachtime = mono_time;
splx(t);
timerclear(&diskp->dk_time);
splx(s);
}
int
sysctl_hw_disknames(SYSCTLFN_ARGS)
{
char bf[DK_DISKNAMELEN + 1];
char *where = oldp;
struct disk *diskp;
size_t needed, left, slen;
int error, first;
if (newp != NULL)
return (EPERM);
if (namelen != 0)
return (EINVAL);
first = 1;
error = 0;
needed = 0;
left = *oldlenp;
simple_lock(&disklist_slock);
for (diskp = TAILQ_FIRST(&disklist); diskp != NULL;
diskp = TAILQ_NEXT(diskp, dk_link)) {
if (where == NULL)
needed += strlen(diskp->dk_name) + 1;
else {
memset(bf, 0, sizeof(bf));
if (first) {
strncpy(bf, diskp->dk_name, sizeof(bf));
first = 0;
} else {
bf[0] = ' ';
strncpy(bf + 1, diskp->dk_name,
sizeof(bf) - 1);
}
bf[DK_DISKNAMELEN] = '\0';
slen = strlen(bf);
if (left < slen + 1)
break;
/* +1 to copy out the trailing NUL byte */
error = copyout(bf, where, slen + 1);
if (error)
break;
where += slen;
needed += slen;
left -= slen;
}
}
simple_unlock(&disklist_slock);
*oldlenp = needed;
return (error);
}
int
sysctl_hw_diskstats(SYSCTLFN_ARGS)
{
struct disk_sysctl sdisk;
struct disk *diskp;
char *where = oldp;
size_t tocopy, left;
int error;
if (newp != NULL)
return (EPERM);
/*
* The original hw.diskstats call was broken and did not require
* the userland to pass in it's size of struct disk_sysctl. This
* was fixed after NetBSD 1.6 was released, and any applications
* that do not pass in the size are given an error only, unless
* we care about 1.6 compatibility.
*/
if (namelen == 0)
#ifdef COMPAT_16
tocopy = offsetof(struct disk_sysctl, dk_rxfer);
#else
return (EINVAL);
#endif
else
tocopy = name[0];
if (where == NULL) {
*oldlenp = disk_count * tocopy;
return (0);
}
error = 0;
left = *oldlenp;
memset(&sdisk, 0, sizeof(sdisk));
*oldlenp = 0;
simple_lock(&disklist_slock);
TAILQ_FOREACH(diskp, &disklist, dk_link) {
if (left < tocopy)
break;
strncpy(sdisk.dk_name, diskp->dk_name, sizeof(sdisk.dk_name));
sdisk.dk_xfer = diskp->dk_rxfer + diskp->dk_wxfer;
sdisk.dk_rxfer = diskp->dk_rxfer;
sdisk.dk_wxfer = diskp->dk_wxfer;
sdisk.dk_seek = diskp->dk_seek;
sdisk.dk_bytes = diskp->dk_rbytes + diskp->dk_wbytes;
sdisk.dk_rbytes = diskp->dk_rbytes;
sdisk.dk_wbytes = diskp->dk_wbytes;
sdisk.dk_attachtime_sec = diskp->dk_attachtime.tv_sec;
sdisk.dk_attachtime_usec = diskp->dk_attachtime.tv_usec;
sdisk.dk_timestamp_sec = diskp->dk_timestamp.tv_sec;
sdisk.dk_timestamp_usec = diskp->dk_timestamp.tv_usec;
sdisk.dk_time_sec = diskp->dk_time.tv_sec;
sdisk.dk_time_usec = diskp->dk_time.tv_usec;
sdisk.dk_busy = diskp->dk_busy;
error = copyout(&sdisk, where, min(tocopy, sizeof(sdisk)));
if (error)
break;
where += tocopy;
*oldlenp += tocopy;
left -= tocopy;
}
simple_unlock(&disklist_slock);
return (error);
iostat_unbusy(diskp->dk_stats, bcount, read);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_vfsops.c,v 1.152 2006/02/21 04:32:39 thorpej Exp $ */
/* $NetBSD: nfs_vfsops.c,v 1.153 2006/04/14 13:09:06 blymn Exp $ */
/*
* Copyright (c) 1989, 1993, 1995
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c,v 1.152 2006/02/21 04:32:39 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c,v 1.153 2006/04/14 13:09:06 blymn Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@ -77,6 +77,12 @@ __KERNEL_RCSID(0, "$NetBSD: nfs_vfsops.c,v 1.152 2006/02/21 04:32:39 thorpej Exp
extern struct nfsstats nfsstats;
extern int nfs_ticks;
/*
* keep a count of the nfs mounts to generate ficticious drive names
* for the per drive stats.
*/
unsigned int nfs_mount_count = 0;
MALLOC_DEFINE(M_NFSMNT, "NFS mount", "NFS mount structure");
/*
@ -800,6 +806,13 @@ mountnfs(argp, mp, nam, pth, hst, vpp, l)
nmp->nm_vnode = *vpp;
VOP_UNLOCK(*vpp, 0);
nmp->nm_stats = iostat_alloc(IOSTAT_NFS);
nmp->nm_stats->parent = nmp;
/* generate a ficticious drive name for the nfs mount */
MALLOC(nmp->nm_stats->name, char *, IOSTATNAMELEN, M_NFSMNT, M_WAITOK);
snprintf(nmp->nm_stats->name, IOSTATNAMELEN, "nfs%u", nfs_mount_count);
nfs_mount_count++;
return (0);
bad:
nfs_disconnect(nmp);
@ -868,6 +881,14 @@ nfs_unmount(mp, mntflags, l)
*/
nmp->nm_iflag |= NFSMNT_DISMNT;
/*
* Clean up the stats... note that we carefully avoid decrementing
* nfs_mount_count here for good reason - we may not be unmounting
* the last thing mounted.
*/
FREE(nmp->nm_stats->name, M_NFSMNT);
iostat_free(nmp->nm_stats);
/*
* There are two reference counts to get rid of here
* (see comment in mountnfs()).

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_vnops.c,v 1.231 2006/03/01 12:38:32 yamt Exp $ */
/* $NetBSD: nfs_vnops.c,v 1.232 2006/04/14 13:09:06 blymn Exp $ */
/*
* Copyright (c) 1989, 1993
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.231 2006/03/01 12:38:32 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.232 2006/04/14 13:09:06 blymn Exp $");
#include "opt_inet.h"
#include "opt_nfs.h"
@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.231 2006/03/01 12:38:32 yamt Exp $")
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/buf.h>
#include <sys/disk.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/namei.h>
@ -1240,7 +1241,7 @@ nfs_readrpc(vp, uiop)
caddr_t bpos, dpos, cp2;
struct mbuf *mreq, *mrep, *md, *mb;
struct nfsmount *nmp;
int error = 0, len, retlen, tsiz, eof;
int error = 0, len, retlen, tsiz, eof, byte_count;
const int v3 = NFS_ISV3(vp);
struct nfsnode *np = VTONFS(vp);
#ifndef NFS_V2_ONLY
@ -1254,6 +1255,8 @@ nfs_readrpc(vp, uiop)
tsiz = uiop->uio_resid;
if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
return (EFBIG);
iostat_busy(nmp->nm_stats);
byte_count = 0; /* count bytes actually transferred */
while (tsiz > 0) {
nfsstats.rpccnt[NFSPROC_READ]++;
len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
@ -1288,6 +1291,7 @@ nfs_readrpc(vp, uiop)
nfsm_mtouio(uiop, retlen);
m_freem(mrep);
tsiz -= retlen;
byte_count += retlen;
#ifndef NFS_V2_ONLY
if (v3) {
if (eof || retlen == 0)
@ -1298,6 +1302,7 @@ nfs_readrpc(vp, uiop)
tsiz = 0;
}
nfsmout:
iostat_unbusy(nmp->nm_stats, byte_count, 1);
return (error);
}
@ -1347,7 +1352,7 @@ nfs_writerpc(vp, uiop, iomode, pageprotected, stalewriteverfp)
int committed = NFSV3WRITE_FILESYNC;
struct nfsnode *np = VTONFS(vp);
struct nfs_writerpc_context ctx;
int s;
int s, byte_count;
struct lwp *l = NULL;
size_t origresid;
#ifndef NFS_V2_ONLY
@ -1376,6 +1381,8 @@ nfs_writerpc(vp, uiop, iomode, pageprotected, stalewriteverfp)
retry:
origresid = uiop->uio_resid;
KASSERT(origresid == uiop->uio_iov->iov_len);
iostat_busy(nmp->nm_stats);
byte_count = 0; /* count of bytes actually written */
while (tsiz > 0) {
uint32_t datalen; /* data bytes need to be allocated in mbuf */
uint32_t backup;
@ -1508,6 +1515,7 @@ retry:
if (error)
break;
tsiz -= len;
byte_count += len;
if (stalewriteverf) {
*stalewriteverfp = TRUE;
stalewriteverf = FALSE;
@ -1528,6 +1536,7 @@ retry:
}
}
nfsmout:
iostat_unbusy(nmp->nm_stats, byte_count, 0);
if (pageprotected) {
/*
* wait until mbufs go away.

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsmount.h,v 1.37 2005/12/11 12:25:17 christos Exp $ */
/* $NetBSD: nfsmount.h,v 1.38 2006/04/14 13:09:07 blymn Exp $ */
/*
* Copyright (c) 1989, 1993
@ -37,6 +37,9 @@
#ifndef _NFS_NFSMOUNT_H_
#define _NFS_NFSMOUNT_H_
#ifdef _KERNEL
#include <sys/disk.h>
#endif
/*
* Arguments to mount NFS
@ -167,6 +170,7 @@ struct nfsmount {
int nm_iflag; /* internal flags */
int nm_waiters; /* number of waiting listeners.. */
long nm_wcckludgetime; /* see nfs_check_wccdata() */
struct io_stats *nm_stats; /* per nfs mount statistics */
};
/*

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.82 2006/02/11 17:36:41 jmmv Exp $
# $NetBSD: Makefile,v 1.83 2006/04/14 13:09:07 blymn Exp $
INCSDIR= /usr/include/sys
@ -12,7 +12,7 @@ INCS= acct.h agpio.h ansi.h ataio.h audioio.h \
exec_coff.h exec_ecoff.h exec_elf.h exec_script.h extattr.h extent.h \
fcntl.h fd_set.h fdio.h featuretest.h file.h filedesc.h filio.h \
float_ieee754.h fstypes.h gmon.h gpio.h hash.h \
ieee754.h inttypes.h ioccom.h ioctl.h ioctl_compat.h ipc.h \
ieee754.h inttypes.h ioccom.h ioctl.h ioctl_compat.h iostat.h ipc.h \
joystick.h \
kcore.h kgdb.h ksem.h ksyms.h ktrace.h \
lkm.h localedef.h lock.h lockf.h lwp.h \

View File

@ -1,4 +1,4 @@
/* $NetBSD: disk.h,v 1.33 2005/12/26 18:41:36 perry Exp $ */
/* $NetBSD: disk.h,v 1.34 2006/04/14 13:09:07 blymn Exp $ */
/*-
* Copyright (c) 1996, 1997, 2004 The NetBSD Foundation, Inc.
@ -90,6 +90,7 @@
#include <sys/time.h>
#include <sys/queue.h>
#include <sys/lock.h>
#include <sys/iostat.h>
struct buf;
struct disk;
@ -209,15 +210,7 @@ struct disk {
* Metrics data; note that some metrics may have no meaning
* on certain types of disks.
*/
int dk_busy; /* busy counter */
uint64_t dk_rxfer; /* total number of read transfers */
uint64_t dk_wxfer; /* total number of write transfers */
uint64_t dk_seek; /* total independent seek operations */
uint64_t dk_rbytes; /* total bytes read */
uint64_t dk_wbytes; /* total bytes written */
struct timeval dk_attachtime; /* time disk was attached */
struct timeval dk_timestamp; /* timestamp of last unbusy */
struct timeval dk_time; /* total time spent busy */
struct io_stats *dk_stats;
struct dkdriver *dk_driver; /* pointer to driver */
@ -243,29 +236,6 @@ struct disk {
struct cpu_disklabel *dk_cpulabel;
};
#define DK_DISKNAMELEN 16
/* The following structure is 64-bit alignment safe */
struct disk_sysctl {
char dk_name[DK_DISKNAMELEN];
int32_t dk_busy;
int32_t pad;
uint64_t dk_xfer;
uint64_t dk_seek;
uint64_t dk_bytes;
uint32_t dk_attachtime_sec;
uint32_t dk_attachtime_usec;
uint32_t dk_timestamp_sec;
uint32_t dk_timestamp_usec;
uint32_t dk_time_sec;
uint32_t dk_time_usec;
/* New separate read/write stats */
uint64_t dk_rxfer;
uint64_t dk_rbytes;
uint64_t dk_wxfer;
uint64_t dk_wbytes;
};
struct dkdriver {
void (*d_strategy)(struct buf *);
void (*d_minphys)(struct buf *);
@ -287,11 +257,6 @@ struct dkdriver {
#define DK_OPEN 4 /* label read, drive open */
#define DK_OPENRAW 5 /* open without label */
/*
* disklist_head is defined here so that user-land has access to it.
*/
TAILQ_HEAD(disklist_head, disk); /* the disklist is a TAILQ */
/*
* Bad sector lists per fixed disk
*/
@ -328,10 +293,9 @@ void disk_detach(struct disk *);
void pseudo_disk_init(struct disk *);
void pseudo_disk_attach(struct disk *);
void pseudo_disk_detach(struct disk *);
void disk_busy(struct disk *);
void disk_unbusy(struct disk *, long, int);
void disk_resetstat(struct disk *);
struct disk *disk_find(char *);
void disk_busy(struct disk *);
void disk_unbusy(struct disk *, long, int);
struct disk *disk_find(char *);
int dkwedge_add(struct dkwedge_info *);
int dkwedge_del(struct dkwedge_info *);

115
sys/sys/iostat.h Normal file
View File

@ -0,0 +1,115 @@
/* $NetBSD: iostat.h,v 1.1 2006/04/14 13:09:07 blymn Exp $ */
/*-
* Copyright (c) 1996, 1997, 2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SYS_IOSTAT_H_
#define _SYS_IOSTAT_H_
/*
* Disk device structures.
*/
#include <sys/time.h>
#include <sys/queue.h>
#include <sys/lock.h>
#define IOSTATNAMELEN 16
/* types of drives we can have */
#define IOSTAT_DISK 0
#define IOSTAT_TAPE 1
#define IOSTAT_NFS 2
/* The following structure is 64-bit alignment safe */
struct io_sysctl {
char name[IOSTATNAMELEN];
int32_t busy;
int32_t type;
u_int64_t xfer;
u_int64_t seek;
u_int64_t bytes;
u_int32_t attachtime_sec;
u_int32_t attachtime_usec;
u_int32_t timestamp_sec;
u_int32_t timestamp_usec;
u_int32_t time_sec;
u_int32_t time_usec;
/* New separate read/write stats */
u_int64_t rxfer;
u_int64_t rbytes;
u_int64_t wxfer;
u_int64_t wbytes;
};
/*
* Structure for keeping the in-kernel drive stats - these are linked
* together in drivelist.
*/
struct io_stats
{
char *name; /* device name */
void *parent; /* pointer to what we are attached to */
int type; /* type of device the state belong to */
int busy; /* busy counter */
u_int64_t rxfer; /* total number of read transfers */
u_int64_t wxfer; /* total number of write transfers */
u_int64_t seek; /* total independent seek operations */
u_int64_t rbytes; /* total bytes read */
u_int64_t wbytes; /* total bytes written */
struct timeval attachtime; /* time disk was attached */
struct timeval timestamp; /* timestamp of last unbusy */
struct timeval time; /* total time spent busy */
TAILQ_ENTRY(io_stats) link;
};
/*
* drivelist_head is defined here so that user-land has access to it.
*/
TAILQ_HEAD(iostatlist_head, io_stats); /* the iostatlist is a TAILQ */
#ifdef _KERNEL
void iostat_busy(struct io_stats *);
void iostat_unbusy(struct io_stats *, long, int);
struct io_stats *iostat_find(char *);
struct io_stats *iostat_alloc(int32_t);
void iostat_free(struct io_stats *);
void iostat_seek(struct io_stats *);
#endif
#endif /* _SYS_IOSTAT_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sysctl.h,v 1.153 2006/03/17 08:50:36 kleink Exp $ */
/* $NetBSD: sysctl.h,v 1.154 2006/04/14 13:09:07 blymn Exp $ */
/*
* Copyright (c) 1989, 1993
@ -714,15 +714,14 @@ struct kinfo_file {
#define HW_USERMEM 6 /* int: non-kernel memory (bytes) */
#define HW_PAGESIZE 7 /* int: software page size */
#define HW_DISKNAMES 8 /* string: disk drive names */
#define HW_DISKSTATS 9 /* struct: diskstats[] */
#define HW_IOSTATS 9 /* struct: iostats[] */
#define HW_MACHINE_ARCH 10 /* string: machine architecture */
#define HW_ALIGNBYTES 11 /* int: ALIGNBYTES for the kernel */
#define HW_CNMAGIC 12 /* string: console magic sequence(s) */
#define HW_PHYSMEM64 13 /* quad: total memory (bytes) */
#define HW_USERMEM64 14 /* quad: non-kernel memory (bytes) */
#define HW_TAPENAMES 15 /* string: tape drive names */
#define HW_TAPESTATS 16 /* struct: tapestats[] */
#define HW_MAXID 16 /* number of valid hw ids */
#define HW_IOSTATNAMES 15 /* string: iostat names */
#define HW_MAXID 15 /* number of valid hw ids */
#define CTL_HW_NAMES { \
{ 0, 0 }, \
@ -733,8 +732,8 @@ struct kinfo_file {
{ "physmem", CTLTYPE_INT }, \
{ "usermem", CTLTYPE_INT }, \
{ "pagesize", CTLTYPE_INT }, \
{ "disknames", CTLTYPE_STRING }, \
{ "diskstats", CTLTYPE_STRUCT }, \
{ "drivenames", CTLTYPE_STRING }, \
{ "drivestats", CTLTYPE_STRUCT }, \
{ "machine_arch", CTLTYPE_STRING }, \
{ "alignbytes", CTLTYPE_INT }, \
{ "cnmagic", CTLTYPE_STRING }, \
@ -1085,8 +1084,6 @@ int old_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct lwp *);
* these helpers are in other files (XXX so should the nodes be) or
* are used by more than one node
*/
int sysctl_hw_disknames(SYSCTLFN_PROTO);
int sysctl_hw_diskstats(SYSCTLFN_PROTO);
int sysctl_hw_tapenames(SYSCTLFN_PROTO);
int sysctl_hw_tapestats(SYSCTLFN_PROTO);
int sysctl_kern_vnode(SYSCTLFN_PROTO);