1/*- 2 * Copyright (c) 1982, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 20 unchanged lines hidden (view full) --- 29 * @(#)subr_log.c 8.1 (Berkeley) 6/10/93 30 */ 31 32/* 33 * Error log buffer for kernel printf's. 34 */ 35 36#include <sys/cdefs.h> |
37__FBSDID("$FreeBSD: head/sys/kern/subr_log.c 230866 2012-02-01 14:34:52Z kib $"); |
38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/conf.h> 42#include <sys/proc.h> 43#include <sys/vnode.h> 44#include <sys/filio.h> 45#include <sys/ttycom.h> --- 8 unchanged lines hidden (view full) --- 54 55#define LOG_ASYNC 0x04 56 57static d_open_t logopen; 58static d_close_t logclose; 59static d_read_t logread; 60static d_ioctl_t logioctl; 61static d_poll_t logpoll; |
62static d_kqfilter_t logkqfilter; |
63 64static void logtimeout(void *arg); 65 66static struct cdevsw log_cdevsw = { 67 .d_version = D_VERSION, 68 .d_open = logopen, 69 .d_close = logclose, 70 .d_read = logread, 71 .d_ioctl = logioctl, 72 .d_poll = logpoll, |
73 .d_kqfilter = logkqfilter, |
74 .d_name = "log", 75}; 76 |
77static int logkqread(struct knote *note, long hint); 78static void logkqdetach(struct knote *note); 79 80static struct filterops log_read_filterops = { 81 .f_isfd = 1, 82 .f_attach = NULL, 83 .f_detach = logkqdetach, 84 .f_event = logkqread, 85}; 86 |
87static struct logsoftc { 88 int sc_state; /* see above for possibilities */ 89 struct selinfo sc_selp; /* process waiting on select call */ 90 struct sigio *sc_sigio; /* information for async I/O */ 91 struct callout sc_callout; /* callout to wakeup syslog */ 92} logsoftc; 93 94int log_open; /* also used in log() */ --- 93 unchanged lines hidden (view full) --- 188 revents |= events & (POLLIN | POLLRDNORM); 189 else 190 selrecord(td, &logsoftc.sc_selp); 191 mtx_unlock(&msgbuf_lock); 192 } 193 return (revents); 194} 195 |
196static int 197logkqfilter(struct cdev *dev, struct knote *kn) 198{ 199 200 if (kn->kn_filter != EVFILT_READ) 201 return (EINVAL); 202 203 kn->kn_fop = &log_read_filterops; 204 kn->kn_hook = NULL; 205 206 mtx_lock(&msgbuf_lock); 207 knlist_add(&logsoftc.sc_selp.si_note, kn, 1); 208 mtx_unlock(&msgbuf_lock); 209 return (0); 210} 211 212static int 213logkqread(struct knote *kn, long hint) 214{ 215 216 mtx_assert(&msgbuf_lock, MA_OWNED); 217 kn->kn_data = msgbuf_getcount(msgbufp); 218 return (kn->kn_data != 0); 219} 220 |
221static void |
222logkqdetach(struct knote *kn) 223{ 224 225 mtx_lock(&msgbuf_lock); 226 knlist_remove(&logsoftc.sc_selp.si_note, kn, 1); 227 mtx_unlock(&msgbuf_lock); 228} 229 230static void |
231logtimeout(void *arg) 232{ 233 234 if (!log_open) 235 return; 236 if (log_wakeups_per_second < 1) { 237 printf("syslog wakeup is less than one. Adjusting to 1.\n"); 238 log_wakeups_per_second = 1; 239 } 240 if (msgbuftrigger == 0) { 241 callout_schedule(&logsoftc.sc_callout, 242 hz / log_wakeups_per_second); 243 return; 244 } 245 msgbuftrigger = 0; 246 selwakeuppri(&logsoftc.sc_selp, LOG_RDPRI); |
247 KNOTE_LOCKED(&logsoftc.sc_selp.si_note, 0); |
248 if ((logsoftc.sc_state & LOG_ASYNC) && logsoftc.sc_sigio != NULL) 249 pgsigio(&logsoftc.sc_sigio, SIGIO, 0); 250 cv_broadcastpri(&log_wakeup, LOG_RDPRI); 251 callout_schedule(&logsoftc.sc_callout, hz / log_wakeups_per_second); 252} 253 254/*ARGSUSED*/ 255static int --- 42 unchanged lines hidden (view full) --- 298} 299 300static void 301log_drvinit(void *unused) 302{ 303 304 cv_init(&log_wakeup, "klog"); 305 callout_init_mtx(&logsoftc.sc_callout, &msgbuf_lock, 0); |
306 knlist_init_mtx(&logsoftc.sc_selp.si_note, &msgbuf_lock); |
307 make_dev_credf(MAKEDEV_ETERNAL, &log_cdevsw, 0, NULL, UID_ROOT, 308 GID_WHEEL, 0600, "klog"); 309} 310 311SYSINIT(logdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE,log_drvinit,NULL); |