Add kqueue support to /dev/klog.

Submitted by:	Mateusz Guzik <mjguzik gmail com>
PR:	  kern/156423
MFC after:	1 weeks
This commit is contained in:
Konstantin Belousov 2012-02-01 14:34:52 +00:00
parent c72ef339bf
commit 6af519cf18

View File

@ -59,6 +59,7 @@ static d_close_t logclose;
static d_read_t logread;
static d_ioctl_t logioctl;
static d_poll_t logpoll;
static d_kqfilter_t logkqfilter;
static void logtimeout(void *arg);
@ -69,9 +70,20 @@ static struct cdevsw log_cdevsw = {
.d_read = logread,
.d_ioctl = logioctl,
.d_poll = logpoll,
.d_kqfilter = logkqfilter,
.d_name = "log",
};
static int logkqread(struct knote *note, long hint);
static void logkqdetach(struct knote *note);
static struct filterops log_read_filterops = {
.f_isfd = 1,
.f_attach = NULL,
.f_detach = logkqdetach,
.f_event = logkqread,
};
static struct logsoftc {
int sc_state; /* see above for possibilities */
struct selinfo sc_selp; /* process waiting on select call */
@ -181,6 +193,40 @@ logpoll(struct cdev *dev, int events, struct thread *td)
return (revents);
}
static int
logkqfilter(struct cdev *dev, struct knote *kn)
{
if (kn->kn_filter != EVFILT_READ)
return (EINVAL);
kn->kn_fop = &log_read_filterops;
kn->kn_hook = NULL;
mtx_lock(&msgbuf_lock);
knlist_add(&logsoftc.sc_selp.si_note, kn, 1);
mtx_unlock(&msgbuf_lock);
return (0);
}
static int
logkqread(struct knote *kn, long hint)
{
mtx_assert(&msgbuf_lock, MA_OWNED);
kn->kn_data = msgbuf_getcount(msgbufp);
return (kn->kn_data != 0);
}
static void
logkqdetach(struct knote *kn)
{
mtx_lock(&msgbuf_lock);
knlist_remove(&logsoftc.sc_selp.si_note, kn, 1);
mtx_unlock(&msgbuf_lock);
}
static void
logtimeout(void *arg)
{
@ -198,6 +244,7 @@ logtimeout(void *arg)
}
msgbuftrigger = 0;
selwakeuppri(&logsoftc.sc_selp, LOG_RDPRI);
KNOTE_LOCKED(&logsoftc.sc_selp.si_note, 0);
if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL)
pgsigio(&logsoftc.sc_sigio, SIGIO, 0);
cv_broadcastpri(&log_wakeup, LOG_RDPRI);
@ -256,6 +303,7 @@ log_drvinit(void *unused)
cv_init(&log_wakeup, "klog");
callout_init_mtx(&logsoftc.sc_callout, &msgbuf_lock, 0);
knlist_init_mtx(&logsoftc.sc_selp.si_note, &msgbuf_lock);
make_dev_credf(MAKEDEV_ETERNAL, &log_cdevsw, 0, NULL, UID_ROOT,
GID_WHEEL, 0600, "klog");
}