summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1997-06-14 21:37:13 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1997-06-14 21:37:13 +0000
commitbe9e68b0d9cd84bf7310511b3e146b0895633780 (patch)
tree1210487499905b6cc8e78ab0d9c917ff6103bf6f
parentc7a19b401046a531612a627a73ed5aea7310eca9 (diff)
split the treatment of the random events
event_q by flipk@ spl fix by deraadt@ gother statistics about whole processing use 'sysctl kern.random' to view what had happened also fix wrong vm.psstrings description
-rw-r--r--sbin/sysctl/sysctl.89
-rw-r--r--sbin/sysctl/sysctl.c26
-rw-r--r--sys/dev/rnd.c161
-rw-r--r--sys/dev/rndioctl.h6
-rw-r--r--sys/dev/rndvar.h21
-rw-r--r--sys/kern/kern_sysctl.c6
-rw-r--r--sys/sys/sysctl.h6
-rw-r--r--usr.sbin/sysctl/sysctl.89
-rw-r--r--usr.sbin/sysctl/sysctl.c26
9 files changed, 220 insertions, 50 deletions
diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8
index 2a9e6fdbeb7..fa0511b8646 100644
--- a/sbin/sysctl/sysctl.8
+++ b/sbin/sysctl/sysctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sysctl.8,v 1.8 1997/06/13 13:50:59 mickey Exp $
+.\" $OpenBSD: sysctl.8,v 1.9 1997/06/14 21:37:11 mickey Exp $
.\" $NetBSD: sysctl.8,v 1.4 1995/09/30 07:12:49 thorpej Exp $
.\"
.\" Copyright (c) 1993
@@ -136,8 +136,9 @@ privilege can change the value.
.It kern.somaxconn integer yes
.It kern.sominconn integer yes
.It kern.usermount integer yes
+.It kern.random struct no
.It vm.loadavg struct no
-.It vm.psstrings struct _ps_strings no
+.It vm.psstrings struct no
.It fs.posix.setuid integer yes
.It net.inet.ip.forwarding integer yes
.It net.inet.ip.redirect integer yes
@@ -226,6 +227,10 @@ sysctl vm.loadavg
.It Pa <sys/sysctl.h>
definitions for top level identifiers, second level kernel and hardware
identifiers, and user level identifiers
+.It Pa <dev/rndvar.h>
+definitions for
+.Xr random 4
+device's statistics structure
.It Pa <sys/socket.h>
definitions for second level network identifiers
.It Pa <sys/gmon.h>
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index a4867ee0deb..196026e9414 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.c,v 1.7 1997/04/06 20:19:22 millert Exp $ */
+/* $OpenBSD: sysctl.c,v 1.8 1997/06/14 21:37:12 mickey Exp $ */
/* $NetBSD: sysctl.c,v 1.9 1995/09/30 07:12:50 thorpej Exp $ */
/*
@@ -44,7 +44,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)sysctl.c 8.1 (Berkeley) 6/6/93";
#else
-static char *rcsid = "$OpenBSD: sysctl.c,v 1.7 1997/04/06 20:19:22 millert Exp $";
+static char *rcsid = "$OpenBSD: sysctl.c,v 1.8 1997/06/14 21:37:12 mickey Exp $";
#endif
#endif /* not lint */
@@ -72,6 +72,7 @@ static char *rcsid = "$OpenBSD: sysctl.c,v 1.7 1997/04/06 20:19:22 millert Exp $
#include <netipx/ipx_var.h>
#include <netipx/spx_var.h>
#include <ddb/db_var.h>
+#include <dev/rndvar.h>
#include <errno.h>
#include <stdio.h>
@@ -123,6 +124,7 @@ int Aflag, aflag, nflag, wflag;
#define CLOCK 0x00000001
#define BOOTTIME 0x00000002
#define CONSDEV 0x00000004
+#define RNDSTATS 0x00000008
/* prototypes */
void usage();
@@ -272,7 +274,7 @@ parse(string, flags)
return;
if (!nflag)
fprintf(stdout, "%s: ", string);
- fprintf(stderr,
+ fprintf(stdout,
"kernel is not compiled for profiling\n");
return;
}
@@ -305,6 +307,9 @@ parse(string, flags)
case KERN_BOOTTIME:
special |= BOOTTIME;
break;
+ case KERN_RND:
+ special |= RNDSTATS;
+ break;
}
break;
@@ -453,6 +458,21 @@ parse(string, flags)
fprintf(stdout, "0x%x\n", dev);
return;
}
+ if (special & RNDSTATS) {
+ struct rndstats *rndstats = (struct rndstats *)buf;
+ if (!nflag)
+ fprintf(stdout, "%s: ", string);
+ fprintf(stdout,
+ "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+ rndstats->rnd_total, rndstats->rnd_used,
+ rndstats->arc4_reads, rndstats->rnd_timer,
+ rndstats->rnd_mouse, rndstats->rnd_tty,
+ rndstats->rnd_disk, rndstats->rnd_net,
+ rndstats->rnd_reads, rndstats->rnd_waits,
+ rndstats->rnd_enqs, rndstats->rnd_deqs,
+ rndstats->rnd_drops);
+ return;
+ }
switch (type) {
case CTLTYPE_INT:
if (newsize == 0) {
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c
index 11e03042228..640006ee3c2 100644
--- a/sys/dev/rnd.c
+++ b/sys/dev/rnd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rnd.c,v 1.22 1997/06/12 02:18:39 mickey Exp $ */
+/* $OpenBSD: rnd.c,v 1.23 1997/06/14 21:37:08 mickey Exp $ */
/*
* random.c -- A strong random number generator
@@ -239,6 +239,7 @@
#include <sys/fcntl.h>
#include <sys/vnode.h>
#include <sys/md5k.h>
+#include <sys/sysctl.h>
#include <net/netisr.h>
@@ -274,6 +275,10 @@ int rnd_debug = 0x0000;
#error No primitive polynomial available for chosen POOLWORDS
#endif
+#define QEVLEN 32
+#define QEVSLOW 16
+#define QEVSBITS 4
+
/* There is actually only one of these, globally. */
struct random_bucket {
u_int add_ptr;
@@ -295,11 +300,20 @@ struct arc4_stream {
u_char s[256];
};
+struct rand_event {
+ struct rand_event *re_next;
+ struct timer_rand_state *re_state;
+ u_char re_nbits;
+ u_long re_time;
+ u_int re_val;
+};
+
/* tags for different random sources */
#define ENT_NET 0x100
#define ENT_DISK 0x200
#define ENT_TTY 0x300
+struct rndstats rndstats;
static struct random_bucket random_state;
static int arc4random_uninitialized = 2;
static struct arc4_stream arc4random_state;
@@ -308,15 +322,20 @@ static struct timer_rand_state extract_timer_state;
static struct timer_rand_state disk_timer_state;
static struct timer_rand_state net_timer_state;
static struct timer_rand_state tty_timer_state;
+static struct rand_event event_space[QEVLEN];
static int rnd_sleep = 0;
static int rnd_attached = 0;
+static int rnd_enqueued = 0;
+static struct rand_event *event_q = NULL;
+static struct rand_event *event_free;
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
static __inline void add_entropy_word __P((const u_int32_t));
-void add_timer_randomness __P((struct timer_rand_state *, u_int));
+static void enqueue_randomness __P((register struct timer_rand_state*, u_int));
+void dequeue_randomness __P((void *));
static __inline int extract_entropy __P((register char *, int));
void arc4_init __P((struct arc4_stream *, u_char *, int));
static __inline void arc4_stir (register struct arc4_stream *);
@@ -361,6 +380,7 @@ arc4_getbyte (register struct arc4_stream *as)
{
register u_char si, sj;
+ rndstats.arc4_reads++;
as->i = (as->i + 1) & 0xff;
si = as->s[as->i];
as->j = (as->j + si) & 0xff;
@@ -370,7 +390,7 @@ arc4_getbyte (register struct arc4_stream *as)
return (as->s[(si + sj) & 0xff]);
}
-static inline void
+static __inline void
arc4maybeinit (void)
{
if (arc4random_uninitialized) {
@@ -385,11 +405,11 @@ arc4maybeinit (void)
u_int32_t
arc4random (void)
{
- arc4maybeinit ();
- return ((arc4_getbyte (&arc4random_state) << 24)
- | (arc4_getbyte (&arc4random_state) << 16)
- | (arc4_getbyte (&arc4random_state) << 8)
- | arc4_getbyte (&arc4random_state));
+ arc4maybeinit ();
+ return ((arc4_getbyte (&arc4random_state) << 24)
+ | (arc4_getbyte (&arc4random_state) << 16)
+ | (arc4_getbyte (&arc4random_state) << 8)
+ | arc4_getbyte (&arc4random_state));
}
void
@@ -397,11 +417,18 @@ randomattach(void)
{
int i;
struct timeval tv;
+ struct rand_event *rep;
random_state.add_ptr = 0;
random_state.entropy_count = 0;
extract_timer_state.dont_count_entropy = 1;
+ bzero(&rndstats, sizeof(rndstats));
+
+ bzero(&event_space, sizeof(event_space));
+ event_free = event_space;
+ for (rep = event_space; rep < &event_space[QEVLEN]; rep++)
+ rep->re_next = rep + 1;
for (i = 0; i < 256; i++)
arc4random_state.s[i] = i;
microtime (&tv);
@@ -488,22 +515,22 @@ add_entropy_word(input)
* are used for a high-resolution timer.
*
*/
-void
-add_timer_randomness(state, num)
- struct timer_rand_state *state;
- u_int num;
+static void
+enqueue_randomness(state, val)
+ register struct timer_rand_state *state;
+ u_int val;
{
int delta, delta2;
u_int nbits;
- u_long time;
struct timeval tv;
+ register struct rand_event *rep;
+ int s;
+ u_long time;
+
+ rndstats.rnd_enqs++;
microtime(&tv);
time = tv.tv_usec ^ tv.tv_sec;
-
- add_entropy_word((u_int32_t)num);
- add_entropy_word(time);
-
/*
* Calculate number of bits of randomness we probably
* added. We take into account the first and second order
@@ -522,22 +549,83 @@ add_timer_randomness(state, num)
for (nbits = 0; delta; nbits++)
delta >>= 1;
- random_state.entropy_count += nbits;
-
+ if (rnd_enqueued > QEVSLOW && nbits < QEVSBITS) {
+ rndstats.rnd_drops++;
+ return;
+ }
+ }
+
+ s = splhigh();
+ if ((rep = event_free) == NULL) {
+ splx(s);
+ rndstats.rnd_drops++;
+ return;
+ }
+ event_free = rep->re_next;
+
+ rep->re_state = state;
+ rep->re_nbits = nbits;
+ rep->re_time = time;
+ rep->re_val = val;
+
+ rep->re_next = event_q;
+ event_q = rep;
+ rep = rep->re_next;
+ splx(s);
+ rndstats.rnd_timer++;
+ rnd_enqueued++;
+
+ if (rep == NULL)
+ timeout(dequeue_randomness, NULL, 1);
+
+}
+
+void
+dequeue_randomness(v)
+ void *v;
+{
+ register struct rand_event *rep;
+ int s;
+
+ rndstats.rnd_deqs++;
+
+ do {
+ s = splhigh();
+ if (event_q == NULL) {
+ splx(s);
+ return;
+ }
+ rep = event_q;
+ event_q = rep->re_next;
+ splx(s);
+
+ add_entropy_word((u_int32_t)rep->re_val);
+ add_entropy_word(rep->re_time);
+
+ random_state.entropy_count += rep->re_nbits;
+ rndstats.rnd_total += rep->re_nbits;
+
/* Prevent overflow */
if (random_state.entropy_count > POOLBITS)
random_state.entropy_count = POOLBITS;
- }
- if (random_state.entropy_count > 8 && rnd_sleep != 0) {
- rnd_sleep--;
+ s = splhigh();
+ rep->re_next = event_free;
+ event_free = rep;
+ splx(s);
+ rnd_enqueued--;
+
+ if (random_state.entropy_count > 8 && rnd_sleep != 0) {
+ rnd_sleep--;
#ifdef DEBUG
- if (rnd_debug & RD_WAIT)
- printf("rnd: wakeup[%d]{%u}\n",
- rnd_sleep, random_state.entropy_count);
+ if (rnd_debug & RD_WAIT)
+ printf("rnd: wakeup[%d]{%u}\n",
+ rnd_sleep, random_state.entropy_count);
#endif
- wakeup(&rnd_sleep);
- }
+ wakeup(&rnd_sleep);
+ }
+ } while(1);
+
}
void
@@ -548,7 +636,8 @@ add_mouse_randomness(mouse_data)
if (!rnd_attached)
return;
- add_timer_randomness(&mouse_timer_state, mouse_data);
+ rndstats.rnd_mouse++;
+ enqueue_randomness(&mouse_timer_state, mouse_data);
}
void
@@ -559,7 +648,8 @@ add_net_randomness(isr)
if (!rnd_attached)
return;
- add_timer_randomness(&net_timer_state, ENT_NET + isr);
+ rndstats.rnd_net++;
+ enqueue_randomness(&net_timer_state, ENT_NET + isr);
}
void
@@ -572,6 +662,7 @@ add_disk_randomness(n)
if (!rnd_attached)
return;
+ rndstats.rnd_disk++;
c = n & 0xff;
n >>= 8;
c ^= n & 0xff;
@@ -579,7 +670,7 @@ add_disk_randomness(n)
c ^= n & 0xff;
n >>= 8;
c ^= n & 0xff;
- add_timer_randomness(&disk_timer_state, ENT_DISK + c);
+ enqueue_randomness(&disk_timer_state, ENT_DISK + c);
}
void
@@ -590,7 +681,8 @@ add_tty_randomness(c)
if (!rnd_attached)
return;
- add_timer_randomness(&tty_timer_state, ENT_TTY + c);
+ rndstats.rnd_tty++;
+ enqueue_randomness(&tty_timer_state, ENT_TTY + c);
}
#if POOLWORDS % 16
@@ -610,7 +702,7 @@ extract_entropy(buf, nbytes)
int ret, i;
MD5_CTX tmp;
- add_timer_randomness(&extract_timer_state, nbytes);
+ enqueue_randomness(&extract_timer_state, nbytes);
/* Redundant, but just in case... */
if (random_state.entropy_count > POOLBITS)
@@ -656,7 +748,7 @@ extract_entropy(buf, nbytes)
bcopy((caddr_t)&tmp.buffer, buf, i);
nbytes -= i;
buf += i;
- add_timer_randomness(&extract_timer_state, nbytes);
+ enqueue_randomness(&extract_timer_state, nbytes);
}
/* Wipe data from memory */
@@ -676,6 +768,7 @@ get_random_bytes(buf, nbytes)
size_t nbytes;
{
extract_entropy((char *) buf, nbytes);
+ rndstats.rnd_used += nbytes * 8;
}
int
@@ -711,6 +804,7 @@ randomread(dev, uio, ioflag)
rnd_sleep);
#endif
rnd_sleep++;
+ rndstats.rnd_waits++;
ret = tsleep(&rnd_sleep, PWAIT | PCATCH,
"rndrd", 0);
#ifdef DEBUG
@@ -721,6 +815,7 @@ randomread(dev, uio, ioflag)
break;
}
n = min(n, random_state.entropy_count / 8);
+ rndstats.rnd_reads++;
#ifdef DEBUG
if (rnd_debug & RD_OUTPUT)
printf("rnd: %u possible output\n", n);
diff --git a/sys/dev/rndioctl.h b/sys/dev/rndioctl.h
index 7a13f6103b1..e198087b734 100644
--- a/sys/dev/rndioctl.h
+++ b/sys/dev/rndioctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rndioctl.h,v 1.2 1996/08/11 07:31:32 dm Exp $ */
+/* $OpenBSD: rndioctl.h,v 1.3 1997/06/14 21:37:08 mickey Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff.
@@ -38,14 +38,14 @@
#ifndef __RNDIOCTL_H__
#define __RNDIOCTL_H__
+/* ioctl()'s for the random number generator */
+
struct rnd_pool_info {
size_t entropy_count;
size_t buf_size;
u_int32_t *buf;
};
-/* ioctl()'s for the random number generator */
-
#define RNDGETENTCNT _IOR('R', 0, sizeof(u_int))
#define RNDADDTOENTCNT _IOW('R', 1, sizeof(u_int))
#define RNDGETPOOL _IOWR('R', 2, sizeof(struct rnd_pool_info))
diff --git a/sys/dev/rndvar.h b/sys/dev/rndvar.h
index 2a9ffaf87b4..0014dfcffa4 100644
--- a/sys/dev/rndvar.h
+++ b/sys/dev/rndvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rndvar.h,v 1.5 1997/01/05 11:08:59 niklas Exp $ */
+/* $OpenBSD: rndvar.h,v 1.6 1997/06/14 21:37:09 mickey Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff.
@@ -46,7 +46,26 @@
#define RND_ARND 4 /* aRC4 based random number generator */
#define RND_NODEV 5 /* First invalid minor device number */
+struct rndstats {
+ u_long rnd_total; /* total bits of entropy generated */
+ u_long rnd_used; /* strong data bits read so far */
+ u_long arc4_reads;/* aRC4 data bytes read so far */
+
+ u_long rnd_timer; /* timer calls */
+ u_long rnd_mouse; /* mouse calls */
+ u_long rnd_tty; /* tty calls */
+ u_long rnd_disk; /* block devices calls */
+ u_long rnd_net; /* net calls */
+
+ u_long rnd_reads; /* strong read calls */
+ u_long rnd_waits; /* sleep for data */
+ u_long rnd_enqs; /* enqueue calls */
+ u_long rnd_deqs; /* dequeue calls */
+ u_long rnd_drops; /* queue-full drops */
+};
+
#ifdef _KERNEL
+extern struct rndstats rndstats;
extern void add_mouse_randomness __P((u_int32_t));
extern void add_net_randomness __P((int));
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index f9d638bf1ce..604564a0aef 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.15 1997/03/27 04:39:35 millert Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.16 1997/06/14 21:37:10 mickey Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -60,6 +60,7 @@
#include <sys/mount.h>
#include <sys/syscallargs.h>
+#include <dev/rndvar.h>
#ifdef DDB
#include <ddb/db_var.h>
@@ -297,6 +298,9 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
return (sysctl_int(oldp, oldlenp, newp, newlen, &sominconn));
case KERN_USERMOUNT:
return (sysctl_int(oldp, oldlenp, newp, newlen, &usermount));
+ case KERN_RND:
+ return (sysctl_rdstruct(oldp, oldlenp, newp, &rndstats,
+ sizeof(rndstats)));
default:
return (EOPNOTSUPP);
}
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 1377c5eef71..7712a632634 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.h,v 1.11 1996/10/04 01:26:45 deraadt Exp $ */
+/* $OpenBSD: sysctl.h,v 1.12 1997/06/14 21:37:10 mickey Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
@@ -141,7 +141,8 @@ struct ctlname {
#define KERN_SOMAXCONN 28 /* int: listen queue maximum */
#define KERN_SOMINCONN 29 /* int: half-open controllable param */
#define KERN_USERMOUNT 30 /* int: users may mount filesystems */
-#define KERN_MAXID 31 /* number of valid kern ids */
+#define KERN_RND 31 /* struct: rnd(4) statistics */
+#define KERN_MAXID 32 /* number of valid kern ids */
#define CTL_KERN_NAMES { \
{ 0, 0 }, \
@@ -175,6 +176,7 @@ struct ctlname {
{ "somaxconn", CTLTYPE_INT }, \
{ "sominconn", CTLTYPE_INT }, \
{ "usermount", CTLTYPE_INT }, \
+ { "random", CTLTYPE_STRUCT }, \
}
/*
diff --git a/usr.sbin/sysctl/sysctl.8 b/usr.sbin/sysctl/sysctl.8
index 2a9e6fdbeb7..fa0511b8646 100644
--- a/usr.sbin/sysctl/sysctl.8
+++ b/usr.sbin/sysctl/sysctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sysctl.8,v 1.8 1997/06/13 13:50:59 mickey Exp $
+.\" $OpenBSD: sysctl.8,v 1.9 1997/06/14 21:37:11 mickey Exp $
.\" $NetBSD: sysctl.8,v 1.4 1995/09/30 07:12:49 thorpej Exp $
.\"
.\" Copyright (c) 1993
@@ -136,8 +136,9 @@ privilege can change the value.
.It kern.somaxconn integer yes
.It kern.sominconn integer yes
.It kern.usermount integer yes
+.It kern.random struct no
.It vm.loadavg struct no
-.It vm.psstrings struct _ps_strings no
+.It vm.psstrings struct no
.It fs.posix.setuid integer yes
.It net.inet.ip.forwarding integer yes
.It net.inet.ip.redirect integer yes
@@ -226,6 +227,10 @@ sysctl vm.loadavg
.It Pa <sys/sysctl.h>
definitions for top level identifiers, second level kernel and hardware
identifiers, and user level identifiers
+.It Pa <dev/rndvar.h>
+definitions for
+.Xr random 4
+device's statistics structure
.It Pa <sys/socket.h>
definitions for second level network identifiers
.It Pa <sys/gmon.h>
diff --git a/usr.sbin/sysctl/sysctl.c b/usr.sbin/sysctl/sysctl.c
index a4867ee0deb..196026e9414 100644
--- a/usr.sbin/sysctl/sysctl.c
+++ b/usr.sbin/sysctl/sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.c,v 1.7 1997/04/06 20:19:22 millert Exp $ */
+/* $OpenBSD: sysctl.c,v 1.8 1997/06/14 21:37:12 mickey Exp $ */
/* $NetBSD: sysctl.c,v 1.9 1995/09/30 07:12:50 thorpej Exp $ */
/*
@@ -44,7 +44,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)sysctl.c 8.1 (Berkeley) 6/6/93";
#else
-static char *rcsid = "$OpenBSD: sysctl.c,v 1.7 1997/04/06 20:19:22 millert Exp $";
+static char *rcsid = "$OpenBSD: sysctl.c,v 1.8 1997/06/14 21:37:12 mickey Exp $";
#endif
#endif /* not lint */
@@ -72,6 +72,7 @@ static char *rcsid = "$OpenBSD: sysctl.c,v 1.7 1997/04/06 20:19:22 millert Exp $
#include <netipx/ipx_var.h>
#include <netipx/spx_var.h>
#include <ddb/db_var.h>
+#include <dev/rndvar.h>
#include <errno.h>
#include <stdio.h>
@@ -123,6 +124,7 @@ int Aflag, aflag, nflag, wflag;
#define CLOCK 0x00000001
#define BOOTTIME 0x00000002
#define CONSDEV 0x00000004
+#define RNDSTATS 0x00000008
/* prototypes */
void usage();
@@ -272,7 +274,7 @@ parse(string, flags)
return;
if (!nflag)
fprintf(stdout, "%s: ", string);
- fprintf(stderr,
+ fprintf(stdout,
"kernel is not compiled for profiling\n");
return;
}
@@ -305,6 +307,9 @@ parse(string, flags)
case KERN_BOOTTIME:
special |= BOOTTIME;
break;
+ case KERN_RND:
+ special |= RNDSTATS;
+ break;
}
break;
@@ -453,6 +458,21 @@ parse(string, flags)
fprintf(stdout, "0x%x\n", dev);
return;
}
+ if (special & RNDSTATS) {
+ struct rndstats *rndstats = (struct rndstats *)buf;
+ if (!nflag)
+ fprintf(stdout, "%s: ", string);
+ fprintf(stdout,
+ "%lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+ rndstats->rnd_total, rndstats->rnd_used,
+ rndstats->arc4_reads, rndstats->rnd_timer,
+ rndstats->rnd_mouse, rndstats->rnd_tty,
+ rndstats->rnd_disk, rndstats->rnd_net,
+ rndstats->rnd_reads, rndstats->rnd_waits,
+ rndstats->rnd_enqs, rndstats->rnd_deqs,
+ rndstats->rnd_drops);
+ return;
+ }
switch (type) {
case CTLTYPE_INT:
if (newsize == 0) {