Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/vmstat Use the new disk and tty stats sysctls when o...



details:   https://anonhg.NetBSD.org/src/rev/84c4580fbfc3
branches:  trunk
changeset: 521314:84c4580fbfc3
user:      simonb <simonb%NetBSD.org@localhost>
date:      Mon Jan 28 02:15:15 2002 +0000

description:
Use the new disk and tty stats sysctls when operating on a live kernel,
dk*() don't need to worry about setgid() games anymore.

diffstat:

 usr.bin/vmstat/dkstats.c |  175 +++++++++++++++++++++++++++++++---------------
 usr.bin/vmstat/dkstats.h |    6 +-
 usr.bin/vmstat/vmstat.c  |   14 +--
 3 files changed, 125 insertions(+), 70 deletions(-)

diffs (truncated from 308 to 300 lines):

diff -r 7465bd0b7a29 -r 84c4580fbfc3 usr.bin/vmstat/dkstats.c
--- a/usr.bin/vmstat/dkstats.c  Mon Jan 28 02:07:57 2002 +0000
+++ b/usr.bin/vmstat/dkstats.c  Mon Jan 28 02:15:15 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dkstats.c,v 1.13 2001/09/18 18:15:54 wiz Exp $ */
+/*     $NetBSD: dkstats.c,v 1.14 2002/01/28 02:15:15 simonb Exp $      */
 
 /*
  * Copyright (c) 1996 John M. Vinopal
@@ -76,7 +76,9 @@
 extern int     hz;
 
 /* Pointer to list of disks. */
-static struct disk     *dk_drivehead = NULL;
+static struct disk             *dk_drivehead = NULL;
+/* sysctl hw.diskstats buffer. */
+static struct disk_sysctl      *dk_drives = NULL;
 
 /* Backward compatibility references. */
 int            dk_ndrive = 0;
@@ -139,9 +141,8 @@
                timerclear(&(last.dk_time[i]));
                timerset(&tmp_timer, &(last.dk_time[i]));
        }
-       for (i = 0; i < CPUSTATES; i++) {
+       for (i = 0; i < CPUSTATES; i++)
                SWAP(cp_time[i]);
-       }
        SWAP(tk_nin);
        SWAP(tk_nout);
 
@@ -156,19 +157,50 @@
 dkreadstats(void)
 {
        struct disk     cur_disk, *p;
-       size_t          ssize;
-       int             mib[2];
+       size_t          size;
+       int             mib[3];
        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;
+       if (memf == NULL) {
+               mib[0] = CTL_HW;
+               mib[1] = HW_DISKSTATS;
+
+               size = dk_ndrive * sizeof(struct disk_sysctl);
+               if (sysctl(mib, 2, dk_drives, &size, NULL, 0) < 0)
+                       err(1, "sysctl hw.diskstats failed");
+               for (i = 0; i < dk_ndrive; i++) {
+                       cur.dk_xfer[i] = dk_drives[i].dk_xfer;
+                       cur.dk_seek[i] = dk_drives[i].dk_seek;
+                       cur.dk_bytes[i] = dk_drives[i].dk_bytes;
+                       cur.dk_time[i].tv_sec = dk_drives[i].dk_time_sec;
+                       cur.dk_time[i].tv_usec = dk_drives[i].dk_time_usec;
+               }
+
+               mib[0] = CTL_KERN;
+               mib[1] = KERN_TKSTAT;
+               mib[2] = KERN_TKSTAT_NIN;
+               size = sizeof(cur.tk_nin);
+               if (sysctl(mib, 3, &cur.tk_nin, &size, NULL, 0) < 0)
+                       cur.tk_nin = 0;
+
+               mib[2] = KERN_TKSTAT_NOUT;
+               size = sizeof(cur.tk_nout);
+               if (sysctl(mib, 3, &cur.tk_nout, &size, NULL, 0) < 0)
+                       cur.tk_nout = 0;
+       } else {
+               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_TK_NIN, &cur.tk_nin, sizeof(cur.tk_nin));
+               deref_nl(X_TK_NOUT, &cur.tk_nout, sizeof(cur.tk_nout));
        }
 
        /*
@@ -176,17 +208,14 @@
         * XXX in crash dumps.  Just don't report it for now, in that
         * XXX case.
         */
-       ssize = sizeof(cur.cp_time);
-       memset(cur.cp_time, 0, ssize);
+       size = sizeof(cur.cp_time);
+       memset(cur.cp_time, 0, size);
        if (memf == NULL) {
                mib[0] = CTL_KERN;
                mib[1] = KERN_CP_TIME;
-               if (sysctl(mib, 2, cur.cp_time, &ssize, NULL, 0) < 0)
+               if (sysctl(mib, 2, cur.cp_time, &size, NULL, 0) < 0)
                        memset(cur.cp_time, 0, 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));
 }
 
 /*
@@ -194,50 +223,69 @@
  * track disk statistics.
  */
 int
-dkinit(int select, gid_t egid)
+dkinit(int select)
 {
-       gid_t oldgid;
        struct disklist_head disk_head;
        struct disk     cur_disk, *p;
+       struct clockinfo clockinfo;
        char            errbuf[_POSIX2_LINE_MAX];
+       size_t          size;
        static int      once = 0;
-       int             i;
+       int             i, mib[2];
 
        if (once)
                return (1);
 
-       /* Assume privs for kvm access. */
-       oldgid = getegid();
-       (void)setegid(egid);
+       if (memf == NULL) {
+               mib[0] = CTL_KERN;
+               mib[1] = KERN_CLOCKRATE;
+               size = sizeof(clockinfo);
+               if (sysctl(mib, 2, &clockinfo, &size, NULL, 0) == -1)
+                       err(1, "sysctl kern.clockrate failed");
+               hz = clockinfo.stathz;
+               if (!hz)
+                       hz = clockinfo.hz;
 
-       /* Open the kernel. */
-       if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf)) == NULL)
-               errx(1, "kvm_openfiles: %s", errbuf);
-
-       /* We are finished with privs now. */
-       (void)setegid(oldgid);
-
-       /* Obtain the namelist symbols from the kernel. */
-       if (kvm_nlist(kd, namelist))
-               KVM_ERROR("kvm_nlist failed to read symbols.");
+               mib[0] = CTL_HW;
+               mib[1] = HW_DISKSTATS;
+               if (sysctl(mib, 2, NULL, &size, NULL, 0) == -1)
+                       err(1, "sysctl hw.diskstats failed");
+               dk_ndrive = size / sizeof(struct disk_sysctl);
 
-       /* 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);
-       else if (dk_ndrive == 0) {
-               warnx("No drives attached.");
+               if (size == 0) {
+                       warnx("No drives attached.");
+               } else {
+                       dk_drives = (struct disk_sysctl *)malloc(size);
+                       if (dk_drives == NULL)
+                               errx(1, "Memory allocation failure.");
+               }
        } else {
-               /* Get a pointer to the first disk. */
-               deref_nl(X_DISKLIST, &disk_head, sizeof(disk_head));
-               dk_drivehead = disk_head.tqh_first;
-       }
+               /* 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.");
+
+               /* Get the number of attached drives. */
+               deref_nl(X_DISK_COUNT, &dk_ndrive, sizeof(dk_ndrive));
 
-       /* Get ticks per second. */
-       deref_nl(X_STATHZ, &hz, sizeof(hz));
-       if (!hz)
-               deref_nl(X_HZ, &hz, sizeof(hz));
+               if (dk_ndrive < 0)
+                       errx(1, "invalid _disk_count %d.", dk_ndrive);
+               else if (dk_ndrive == 0) {
+                       warnx("No drives attached.");
+               } 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));
+       }
 
        /* Allocate space for the statistics. */
        cur.dk_time = calloc(dk_ndrive, sizeof(struct timeval));
@@ -263,15 +311,26 @@
        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);
-               cur.dk_select[i] = select;
+       if (memf == NULL) {
+               mib[0] = CTL_HW;                /* Should be still set from */
+               mib[1] = HW_DISKSTATS;          /* ... above, but be safe... */
+               if (sysctl(mib, 2, dk_drives, &size, NULL, 0) == -1)
+                       err(1, "sysctl hw.diskstats failed");
+               for (i = 0; i < dk_ndrive; i++) {
+                       cur.dk_name[i] = dk_drives[i].dk_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);
+                       cur.dk_select[i] = select;
 
-               p = cur_disk.dk_link.tqe_next;
+                       p = cur_disk.dk_link.tqe_next;
+               }
        }
 
        /* Never do this initialization again. */
diff -r 7465bd0b7a29 -r 84c4580fbfc3 usr.bin/vmstat/dkstats.h
--- a/usr.bin/vmstat/dkstats.h  Mon Jan 28 02:07:57 2002 +0000
+++ b/usr.bin/vmstat/dkstats.h  Mon Jan 28 02:15:15 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dkstats.h,v 1.3 2000/12/01 02:08:26 simonb Exp $       */
+/*     $NetBSD: dkstats.h,v 1.4 2002/01/28 02:15:16 simonb Exp $       */
 
 /*
  * Copyright (c) 1996 John M. Vinopal
@@ -53,6 +53,6 @@
 extern char            **dr_name;
 extern int             *dk_select, dk_ndrive;
 
-int    dkinit(int, gid_t);
+int    dkinit(int);
+void   dkreadstats(void);
 void   dkswap(void);
-void   dkreadstats(void);
diff -r 7465bd0b7a29 -r 84c4580fbfc3 usr.bin/vmstat/vmstat.c
--- a/usr.bin/vmstat/vmstat.c   Mon Jan 28 02:07:57 2002 +0000
+++ b/usr.bin/vmstat/vmstat.c   Mon Jan 28 02:15:15 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vmstat.c,v 1.94 2001/12/09 03:07:58 chs Exp $ */
+/* $NetBSD: vmstat.c,v 1.95 2002/01/28 02:15:16 simonb Exp $ */
 
 /*-
  * Copyright (c) 1998, 2000, 2001 The NetBSD Foundation, Inc.
@@ -81,7 +81,7 @@
 #if 0
 static char sccsid[] = "@(#)vmstat.c   8.2 (Berkeley) 3/1/95";
 #else
-__RCSID("$NetBSD: vmstat.c,v 1.94 2001/12/09 03:07:58 chs Exp $");
+__RCSID("$NetBSD: vmstat.c,v 1.95 2002/01/28 02:15:16 simonb Exp $");
 #endif
 #endif /* not lint */
 
@@ -372,12 +372,8 @@
        if (kd == NULL)
                errx(1, "kvm_openfiles: %s", errbuf);
 
-       if (nlistf == NULL && memf == NULL) {
-               if (todo & VMSTAT)
-                       (void)setegid(getgid());        /* XXX: dkinit */
-               else
-                       (void)setgid(getgid());
-       }
+       if (nlistf == NULL && memf == NULL)
+               (void)setgid(getgid());
 
        if ((c = kvm_nlist(kd, namelist)) != 0) {
                if (c == -1)
@@ -397,7 +393,7 @@



Home | Main Index | Thread Index | Old Index