tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: locking against myself panic (cprng_strongreseed, filt_rndread)
Short: Your patch seems to work.
Long: I don't quite understand the behaviour, but at least, it doesn't panic.
I wrote a test programm (my first encounter with kqueue, so probably wrong)
to exercise EVFILT_READ.
I created a named pipe and it did approximately what I expected (on start,
it hung in fiford, which I didn't expect).
I wanted to test in on /dev/urandom, it read 512 bytes, then timed out
(program wrote dots) and paniced (same traceback as originally) after
about 15 of them.
On /dev/random, it read 512 bytes, wrote dots and didn't panic (at least
not for 20 seconds). On a second run on /dev/random, it read 512 bytes
and paniced immediately after.
With the patch, it read behaved identically on the first run; on the second,
it read about twenty 512-byte chunks and continued writing dots (if I
remember correctly). In any case, I couldn't make it panic.
#include <stdio.h>
#include <unistd.h>
#include <err.h>
#include <fcntl.h>
#include <sys/event.h>
#include <sys/time.h>
int main(int argc, char *argv[]) {
int fd;
int kq;
struct kevent ev;
int nev;
const struct timespec tout = { 1, 0 };
int i;
char buf[1024];
if (argc != 2)
errx(1, "argc");
if ((fd = open(argv[1], O_RDONLY)) == -1)
err(1, "open %s", argv[1]);
if ((kq = kqueue()) == -1)
err(1, "kqueue");
EV_SET(&ev, fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0);
if (kevent(kq, &ev, 1, NULL, 0, &tout) == -1)
err(1, "kevent1");
for (;;) {
if ((nev = kevent(kq, NULL, 0, &ev, 1, &tout)) == -1)
err(1, "kevent2");
if (nev == 0) {
fputc('.', stdout); fflush(stdout); continue;
}
i = ev.data;
printf("%d", i); fflush(stdout);
if (i > sizeof buf)
i = sizeof buf;
if (read(fd, buf, i) == -1)
err(1, "read");
}
(void)close(kq);
(void)close(fd);
}
Home |
Main Index |
Thread Index |
Old Index