diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2001-05-14 07:20:51 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2001-05-14 07:20:51 +0000 |
commit | 9581c7360fe9a46282e319ba8558223e111bbf79 (patch) | |
tree | f13d93be88a171cb199ab5947e9d46b817f3bf55 /usr.bin/vmstat | |
parent | 96e59681e6a26d269396962e2a9f7dfdc8a1b171 (diff) |
Use the sysctl-based diskstats for live kernels. deraadt@ ok
Diffstat (limited to 'usr.bin/vmstat')
-rw-r--r-- | usr.bin/vmstat/dkstats.c | 178 |
1 files changed, 135 insertions, 43 deletions
diff --git a/usr.bin/vmstat/dkstats.c b/usr.bin/vmstat/dkstats.c index 47066d407b6..aa61612218c 100644 --- a/usr.bin/vmstat/dkstats.c +++ b/usr.bin/vmstat/dkstats.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dkstats.c,v 1.9 2001/01/02 20:09:02 deraadt Exp $ */ +/* $OpenBSD: dkstats.c,v 1.10 2001/05/14 07:20:50 angelos Exp $ */ /* $NetBSD: dkstats.c,v 1.1 1996/05/10 23:19:27 thorpej Exp $ */ /* @@ -33,9 +33,12 @@ * SUCH DAMAGE. */ +#include <sys/param.h> #include <sys/dkstat.h> #include <sys/time.h> #include <sys/disk.h> +#include <sys/sysctl.h> +#include <sys/tty.h> #include <err.h> #include <fcntl.h> @@ -148,21 +151,67 @@ void dkreadstats() { struct disk cur_disk, *p; - int i; - - p = dk_drivehead; - - for (i = 0; i < dk_ndrive; i++) { - deref_kptr(p, &cur_disk, sizeof(cur_disk)); - cur.dk_xfer[i] = cur_disk.dk_xfer; - cur.dk_seek[i] = cur_disk.dk_seek; - cur.dk_bytes[i] = cur_disk.dk_bytes; - timerset(&(cur_disk.dk_time), &(cur.dk_time[i])); - p = cur_disk.dk_link.tqe_next; + int i, mib[3]; + size_t size; + + if (nlistf == NULL && memf == NULL) { + size = dk_ndrive * sizeof(struct disk); + mib[0] = CTL_HW; + mib[1] = HW_DISKSTATS; + p = calloc(size, sizeof(char)); + if (p == NULL) + err(1, NULL); + if (sysctl(mib, 2, p, &size, NULL, 0) < 0) { + warn("could not read hw.diskstats"); + bzero(p, dk_ndrive * sizeof(struct disk)); + } + + for (i = 0; i < dk_ndrive; i++) { + cur.dk_xfer[i] = p[i].dk_xfer; + cur.dk_seek[i] = p[i].dk_seek; + cur.dk_bytes[i] = p[i].dk_bytes; + timerset(&(p[i].dk_time), &(cur.dk_time[i])); + } + + size = sizeof(cur.cp_time); + mib[0] = CTL_KERN; + mib[1] = KERN_CPTIME; + if (sysctl(mib, 2, cur.cp_time, &size, NULL, 0) < 0) { + warnx("could not read kern.cp_time"); + bzero(cur.cp_time, sizeof(cur.cp_time)); + } + size = sizeof(cur.tk_nin); + mib[0] = CTL_KERN; + mib[1] = KERN_TTY; + mib[2] = KERN_TTY_TKNIN; + if (sysctl(mib, 3, &cur.tk_nin, &size, NULL, 0) < 0) { + warnx("could not read kern.tty.tk_nin"); + cur.tk_nin = 0; + } + size = sizeof(cur.tk_nin); + mib[0] = CTL_KERN; + mib[1] = KERN_TTY; + mib[2] = KERN_TTY_TKNOUT; + if (sysctl(mib, 3, &cur.tk_nout, &size, NULL, 0) < 0) { + warnx("could not read kern.tty.tk_nout"); + cur.tk_nout = 0; + } + } else { + p = dk_drivehead; + + for (i = 0; i < dk_ndrive; i++) { + deref_kptr(p, &cur_disk, sizeof(cur_disk)); + cur.dk_xfer[i] = cur_disk.dk_xfer; + cur.dk_seek[i] = cur_disk.dk_seek; + cur.dk_bytes[i] = cur_disk.dk_bytes; + timerset(&(cur_disk.dk_time), &(cur.dk_time[i])); + p = cur_disk.dk_link.tqe_next; + } + + deref_nl(X_CP_TIME, cur.cp_time, sizeof(cur.cp_time)); + deref_nl(X_TK_NIN, &cur.tk_nin, sizeof(cur.tk_nin)); + deref_nl(X_TK_NOUT, &cur.tk_nout, sizeof(cur.tk_nout)); } - deref_nl(X_CP_TIME, cur.cp_time, sizeof(cur.cp_time)); - deref_nl(X_TK_NIN, &cur.tk_nin, sizeof(cur.tk_nin)); - deref_nl(X_TK_NOUT, &cur.tk_nout, sizeof(cur.tk_nout)); } /* @@ -178,34 +227,58 @@ int select; char errbuf[_POSIX2_LINE_MAX]; static int once = 0; extern int hz; - int i; + int i, mib[2]; + size_t size; + struct clockinfo clkinfo; + char *disknames, *name, *bufpp; if (once) return(1); - /* Open the kernel. */ - if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == NULL) - errx(1, "kvm_openfiles: %s", errbuf); + if (nlistf != NULL || memf != NULL) { + /* Open the kernel. */ + if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, + errbuf)) == NULL) + errx(1, "kvm_openfiles: %s", errbuf); + + /* Obtain the namelist symbols from the kernel. */ + if (kvm_nlist(kd, namelist)) + KVM_ERROR("kvm_nlist failed to read symbols."); - /* Obtain the namelist symbols from the kernel. */ - if (kvm_nlist(kd, namelist)) - KVM_ERROR("kvm_nlist failed to read symbols."); + /* Get the number of attached drives. */ + deref_nl(X_DISK_COUNT, &dk_ndrive, sizeof(dk_ndrive)); - /* Get the number of attached drives. */ - deref_nl(X_DISK_COUNT, &dk_ndrive, sizeof(dk_ndrive)); + if (dk_ndrive < 0) + errx(1, "invalid _disk_count %d.", dk_ndrive); - if (dk_ndrive < 0) - errx(1, "invalid _disk_count %d.", dk_ndrive); - else { /* Get a pointer to the first disk. */ deref_nl(X_DISKLIST, &disk_head, sizeof(disk_head)); dk_drivehead = disk_head.tqh_first; - } - /* Get ticks per second. */ - deref_nl(X_STATHZ, &hz, sizeof(hz)); - if (!hz) - deref_nl(X_HZ, &hz, sizeof(hz)); + /* Get ticks per second. */ + deref_nl(X_STATHZ, &hz, sizeof(hz)); + if (!hz) + deref_nl(X_HZ, &hz, sizeof(hz)); + } else { + /* Get the number of attached drives. */ + mib[0] = CTL_HW; + mib[1] = HW_DISKCOUNT; + size = sizeof(dk_ndrive); + if (sysctl(mib, 2, &dk_ndrive, &size, NULL, 0) < 0 ) { + warnx("could not read hw.diskcount"); + dk_ndrive = 0; + } + + /* Get ticks per second. */ + mib[0] = CTL_KERN; + mib[1] = KERN_CLOCKRATE; + size = sizeof(clkinfo); + if (sysctl(mib, 2, &clkinfo, &size, NULL, 0) < 0) { + warnx("could not read kern.clockrate"); + hz = 0; + } else + hz = clkinfo.stathz; + } /* allocate space for the statistics */ cur.dk_time = calloc(dk_ndrive, sizeof(struct timeval)); @@ -229,17 +302,36 @@ int select; dr_name = cur.dk_name; /* Read the disk names and set intial selection. */ - p = dk_drivehead; - for (i = 0; i < dk_ndrive; i++) { - char buf[10]; - deref_kptr(p, &cur_disk, sizeof(cur_disk)); - deref_kptr(cur_disk.dk_name, buf, sizeof(buf)); - cur.dk_name[i] = strdup(buf); - if (!cur.dk_name[i]) - errx(1, "Memory allocation failure."); - cur.dk_select[i] = select; - - p = cur_disk.dk_link.tqe_next; + if (nlistf == NULL && memf == NULL) { + mib[0] = CTL_HW; + mib[1] = HW_DISKNAMES; + size = 0; + if (sysctl(mib, 2, NULL, &size, NULL, 0) < 0) + err(1, "can't get hw.disknames"); + disknames = calloc(size, sizeof(char)); + if (disknames == NULL) + err(1, NULL); + if (sysctl(mib, 2, disknames, &size, NULL, 0) < 0) + err(1, "can't get hw.disknames"); + bufpp = disknames; + i = 0; + while ((name = strsep(&bufpp, ",")) != NULL) { + cur.dk_name[i] = name; + cur.dk_select[i++] = select; + } + } else { + p = dk_drivehead; + for (i = 0; i < dk_ndrive; i++) { + char buf[10]; + deref_kptr(p, &cur_disk, sizeof(cur_disk)); + deref_kptr(cur_disk.dk_name, buf, sizeof(buf)); + cur.dk_name[i] = strdup(buf); + if (!cur.dk_name[i]) + errx(1, "Memory allocation failure."); + cur.dk_select[i] = select; + + p = cur_disk.dk_link.tqe_next; + } } /* Never do this initalization again. */ |