]>
git.saurik.com Git - apple/xnu.git/blob - bsd/kern/subr_log.c
   2  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved. 
   8  * This file contains Original Code and/or Modifications of Original Code 
   9  * as defined in and that are subject to the Apple Public Source License 
  10  * Version 2.0 (the 'License'). You may not use this file except in 
  11  * compliance with the License. Please obtain a copy of the License at 
  12  * http://www.opensource.apple.com/apsl/ and read it before using this 
  15  * The Original Code and all software distributed under the License are 
  16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  20  * Please see the License for the specific language governing rights and 
  21  * limitations under the License. 
  23  * @APPLE_LICENSE_HEADER_END@ 
  25 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ 
  27  * Copyright (c) 1982, 1986, 1993 
  28  *      The Regents of the University of California.  All rights reserved. 
  30  * Redistribution and use in source and binary forms, with or without 
  31  * modification, are permitted provided that the following conditions 
  33  * 1. Redistributions of source code must retain the above copyright 
  34  *    notice, this list of conditions and the following disclaimer. 
  35  * 2. Redistributions in binary form must reproduce the above copyright 
  36  *    notice, this list of conditions and the following disclaimer in the 
  37  *    documentation and/or other materials provided with the distribution. 
  38  * 3. All advertising materials mentioning features or use of this software 
  39  *    must display the following acknowledgement: 
  40  *      This product includes software developed by the University of 
  41  *      California, Berkeley and its contributors. 
  42  * 4. Neither the name of the University nor the names of its contributors 
  43  *    may be used to endorse or promote products derived from this software 
  44  *    without specific prior written permission. 
  46  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  47  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  48  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  49  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  50  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  51  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  52  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  53  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  54  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  55  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  58  *      @(#)subr_log.c  8.3 (Berkeley) 2/14/95 
  62  * Error log buffer for kernel printf's. 
  65 #include <sys/param.h> 
  66 #include <sys/systm.h> 
  68 #include <sys/vnode.h> 
  69 #include <sys/ioctl.h> 
  70 #include <sys/msgbuf.h> 
  72 #include <sys/errno.h> 
  73 #include <sys/select.h> 
  74 #include <kern/thread.h> 
  76 #define LOG_RDPRI       (PZERO + 1) 
  79 #define LOG_ASYNC       0x04 
  80 #define LOG_RDWAIT      0x08 
  83         int     sc_state
;               /* see above for possibilities */ 
  84         struct  selinfo sc_selp
;        /* thread waiting for select */ 
  85         int     sc_pgid
;                /* process/group for async I/O */ 
  88 int     log_open
;                       /* also used in log() */ 
  89 struct msgbuf temp_msgbuf
; 
  90 struct msgbuf 
*msgbufp
; 
  91 static int _logentrypend 
= 0; 
  94  * Serialize log access.  Note that the log can be written at interrupt level, 
  95  * so any log manipulations that can be done from, or affect, another processor 
  96  * at interrupt level must be guarded with a spin lock. 
  98 decl_simple_lock_data(,log_lock
);       /* stop races dead in their tracks */ 
  99 #define LOG_LOCK()      simple_lock(&log_lock) 
 100 #define LOG_UNLOCK()    simple_unlock(&log_lock) 
 101 #define LOG_LOCK_INIT() simple_lock_init(&log_lock) 
 104 logopen(dev
, flags
, mode
, p
) 
 115         logsoftc
.sc_pgid 
= p
->p_pid
;            /* signal process only */ 
 117          * Potential race here with putchar() but since putchar should be 
 118          * called by autoconf, msg_magic should be initialized by the time 
 121         if (msgbufp
->msg_magic 
!= MSG_MAGIC
) { 
 124                 msgbufp
->msg_magic 
= MSG_MAGIC
; 
 125                 msgbufp
->msg_bufx 
= msgbufp
->msg_bufr 
= 0; 
 126                 for (i
=0; i 
< MSG_BSIZE
; i
++) 
 127                         msgbufp
->msg_bufc
[i
] = 0; 
 142         selwakeup(&logsoftc
.sc_selp
); 
 144         selthreadclear(&logsoftc
.sc_selp
); 
 152 logread(dev
, uio
, flag
) 
 162         while (msgbufp
->msg_bufr 
== msgbufp
->msg_bufx
) { 
 163                 if (flag 
& IO_NDELAY
) { 
 165                         return (EWOULDBLOCK
); 
 167                 if (logsoftc
.sc_state 
& LOG_NBIO
) { 
 169                         return (EWOULDBLOCK
); 
 171                 logsoftc
.sc_state 
|= LOG_RDWAIT
; 
 172                 if (error 
= tsleep((caddr_t
)msgbufp
, LOG_RDPRI 
| PCATCH
, 
 179         logsoftc
.sc_state 
&= ~LOG_RDWAIT
; 
 181         while (uio
->uio_resid 
> 0) { 
 182                 l 
= msgbufp
->msg_bufx 
- msgbufp
->msg_bufr
; 
 184                         l 
= MSG_BSIZE 
- msgbufp
->msg_bufr
; 
 185                 l 
= min(l
, uio
->uio_resid
); 
 188                 error 
= uiomove((caddr_t
)&msgbufp
->msg_bufc
[msgbufp
->msg_bufr
], 
 192                 msgbufp
->msg_bufr 
+= l
; 
 193                 if (msgbufp
->msg_bufr 
< 0 || msgbufp
->msg_bufr 
>= MSG_BSIZE
) 
 194                         msgbufp
->msg_bufr 
= 0; 
 201 logselect(dev
, rw
, wql
, p
) 
 212                 if (msgbufp
->msg_bufr 
!= msgbufp
->msg_bufx
) { 
 216                 selrecord(p
, &logsoftc
.sc_selp
, wql
); 
 228         boolean_t funnel_state
; 
 232         funnel_state 
= thread_funnel_set(kernel_flock
, TRUE
); 
 233         selwakeup(&logsoftc
.sc_selp
); 
 234         if (logsoftc
.sc_state 
& LOG_ASYNC
) { 
 236                 pgid 
= logsoftc
.sc_pgid
; 
 239                         gsignal(-pgid
, SIGIO
);  
 240                 else if (p 
= pfind(pgid
)) 
 243         if (logsoftc
.sc_state 
& LOG_RDWAIT
) { 
 244                 wakeup((caddr_t
)msgbufp
); 
 245                 logsoftc
.sc_state 
&= ~LOG_RDWAIT
; 
 247         (void) thread_funnel_set(kernel_flock
, funnel_state
); 
 262 logioctl(dev
, com
, data
, flag
) 
 270         /* return number of characters immediately available */ 
 273                 l 
= msgbufp
->msg_bufx 
- msgbufp
->msg_bufr
; 
 282                         logsoftc
.sc_state 
|= LOG_NBIO
; 
 284                         logsoftc
.sc_state 
&= ~LOG_NBIO
; 
 289                         logsoftc
.sc_state 
|= LOG_ASYNC
; 
 291                         logsoftc
.sc_state 
&= ~LOG_ASYNC
; 
 296                 logsoftc
.sc_pgid 
= *(int *)data
; 
 302                 *(int *)data 
= logsoftc
.sc_pgid
; 
 315         msgbufp 
= &temp_msgbuf
; 
 322         register struct msgbuf 
*mbp
; 
 325                 msgbufp 
=&temp_msgbuf
; 
 328         if (mbp
-> msg_magic 
!= MSG_MAGIC
) {  
 331                 mbp
->msg_magic 
= MSG_MAGIC
; 
 332                 mbp
->msg_bufx 
= mbp
->msg_bufr 
= 0; 
 333                 for (i
=0; i 
< MSG_BSIZE
; i
++) 
 334                         mbp
->msg_bufc
[i
] = 0; 
 336         mbp
->msg_bufc
[mbp
->msg_bufx
++] = c
; 
 338         if (mbp
->msg_bufx 
< 0 || mbp
->msg_bufx 
>= MSG_BSIZE
)