kernel - Major signal path adjustments to fix races, tsleep race fixes, +more
[dragonfly.git] / sys / kern / subr_prf.c
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1986, 1988, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
39 * $FreeBSD: src/sys/kern/subr_prf.c,v 1.61.2.5 2002/08/31 18:22:08 dwmalone Exp $
448f8e02 40 * $DragonFly: src/sys/kern/subr_prf.c,v 1.21 2008/07/17 23:56:23 dillon Exp $
984263bc
MD
41 */
42
a0a36cfd
SW
43#include "opt_ddb.h"
44
984263bc
MD
45#include <sys/param.h>
46#include <sys/systm.h>
47#include <sys/kernel.h>
48#include <sys/msgbuf.h>
49#include <sys/malloc.h>
50#include <sys/proc.h>
895c1f85 51#include <sys/priv.h>
984263bc
MD
52#include <sys/tty.h>
53#include <sys/tprintf.h>
a0a36cfd 54#include <sys/stdint.h>
984263bc
MD
55#include <sys/syslog.h>
56#include <sys/cons.h>
57#include <sys/uio.h>
58#include <sys/sysctl.h>
8a8d5d85 59#include <sys/lock.h>
a0a36cfd 60#include <sys/ctype.h>
28d7e704
MD
61#include <sys/eventhandler.h>
62#include <sys/kthread.h>
a0a36cfd 63
5fddbda2
MD
64#include <sys/thread2.h>
65#include <sys/spinlock2.h>
66
a0a36cfd
SW
67#ifdef DDB
68#include <ddb/ddb.h>
69#endif
984263bc
MD
70
71/*
72 * Note that stdarg.h and the ANSI style va_start macro is used for both
e2565a42
MD
73 * ANSI and traditional C compilers. We use the __ machine version to stay
74 * within the kernel header file set.
984263bc
MD
75 */
76#include <machine/stdarg.h>
77
28d7e704
MD
78#define TOCONS 0x01
79#define TOTTY 0x02
80#define TOLOG 0x04
81#define TOWAKEUP 0x08
984263bc
MD
82
83/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
a0a36cfd 84#define MAXNBUF (sizeof(intmax_t) * NBBY + 1)
984263bc
MD
85
86struct putchar_arg {
87 int flags;
88 int pri;
89 struct tty *tty;
90};
91
92struct snprintf_arg {
93 char *str;
94 size_t remain;
95};
96
97extern int log_open;
98
99struct tty *constty; /* pointer to console "window" tty */
100
984263bc
MD
101static void msglogchar(int c, int pri);
102static void msgaddchar(int c, void *dummy);
0ced1954 103static void kputchar (int ch, void *arg);
a0a36cfd
SW
104static char *ksprintn (char *nbuf, uintmax_t num, int base, int *lenp,
105 int upper);
402ed7e1 106static void snprintf_func (int ch, void *arg);
984263bc
MD
107
108static int consintr = 1; /* Ok to handle console interrupts? */
109static int msgbufmapped; /* Set when safe to use msgbuf */
5fddbda2 110static struct spinlock cons_spin = SPINLOCK_INITIALIZER(cons_spin);
28d7e704 111static thread_t constty_td = NULL;
5fddbda2 112
984263bc
MD
113int msgbuftrigger;
114
115static int log_console_output = 1;
116TUNABLE_INT("kern.log_console_output", &log_console_output);
117SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW,
118 &log_console_output, 0, "");
119
d41cbec3 120static int unprivileged_read_msgbuf = 1;
43a0f7ae 121SYSCTL_INT(_security, OID_AUTO, unprivileged_read_msgbuf, CTLFLAG_RW,
d41cbec3
MD
122 &unprivileged_read_msgbuf, 0,
123 "Unprivileged processes may read the kernel message buffer");
124
984263bc
MD
125/*
126 * Warn that a system table is full.
127 */
128void
129tablefull(const char *tab)
130{
131
132 log(LOG_ERR, "%s: table is full\n", tab);
133}
134
135/*
136 * Uprintf prints to the controlling terminal for the current process.
984263bc
MD
137 */
138int
139uprintf(const char *fmt, ...)
140{
141 struct proc *p = curproc;
e2565a42 142 __va_list ap;
984263bc
MD
143 struct putchar_arg pca;
144 int retval = 0;
145
4643740a 146 if (p && (p->p_flags & P_CONTROLT) && p->p_session->s_ttyvp) {
e2565a42 147 __va_start(ap, fmt);
984263bc
MD
148 pca.tty = p->p_session->s_ttyp;
149 pca.flags = TOTTY;
8a8d5d85 150
379210cb 151 retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
e2565a42 152 __va_end(ap);
984263bc 153 }
a0a36cfd 154 return (retval);
984263bc
MD
155}
156
157tpr_t
dadab5e9 158tprintf_open(struct proc *p)
984263bc 159{
4643740a 160 if ((p->p_flags & P_CONTROLT) && p->p_session->s_ttyvp) {
8b90699b 161 sess_hold(p->p_session);
984263bc
MD
162 return ((tpr_t) p->p_session);
163 }
164 return ((tpr_t) NULL);
165}
166
167void
dadab5e9 168tprintf_close(tpr_t sess)
984263bc 169{
984263bc 170 if (sess)
8b90699b 171 sess_rele((struct session *) sess);
984263bc
MD
172}
173
174/*
175 * tprintf prints on the controlling terminal associated
176 * with the given session.
177 */
178int
179tprintf(tpr_t tpr, const char *fmt, ...)
180{
1fd87d54 181 struct session *sess = (struct session *)tpr;
984263bc
MD
182 struct tty *tp = NULL;
183 int flags = TOLOG;
e2565a42 184 __va_list ap;
984263bc
MD
185 struct putchar_arg pca;
186 int retval;
187
188 if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
189 flags |= TOTTY;
190 tp = sess->s_ttyp;
191 }
e2565a42 192 __va_start(ap, fmt);
984263bc
MD
193 pca.tty = tp;
194 pca.flags = flags;
195 pca.pri = LOG_INFO;
379210cb 196 retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
e2565a42 197 __va_end(ap);
984263bc 198 msgbuftrigger = 1;
a0a36cfd 199 return (retval);
984263bc
MD
200}
201
202/*
203 * Ttyprintf displays a message on a tty; it should be used only by
204 * the tty driver, or anything that knows the underlying tty will not
205 * be revoke(2)'d away. Other callers should use tprintf.
206 */
207int
208ttyprintf(struct tty *tp, const char *fmt, ...)
209{
e2565a42 210 __va_list ap;
984263bc
MD
211 struct putchar_arg pca;
212 int retval;
213
e2565a42 214 __va_start(ap, fmt);
984263bc
MD
215 pca.tty = tp;
216 pca.flags = TOTTY;
379210cb 217 retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
e2565a42 218 __va_end(ap);
a0a36cfd 219 return (retval);
984263bc
MD
220}
221
222/*
223 * Log writes to the log buffer, and guarantees not to sleep (so can be
224 * called by interrupt routines). If there is no process reading the
225 * log yet, it writes to the console also.
226 */
227int
228log(int level, const char *fmt, ...)
229{
e2565a42 230 __va_list ap;
984263bc
MD
231 int retval;
232 struct putchar_arg pca;
233
234 pca.tty = NULL;
235 pca.pri = level;
236 pca.flags = log_open ? TOLOG : TOCONS;
237
e2565a42 238 __va_start(ap, fmt);
379210cb 239 retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
e2565a42 240 __va_end(ap);
984263bc
MD
241
242 msgbuftrigger = 1;
243 return (retval);
244}
245
984263bc
MD
246#define CONSCHUNK 128
247
248void
249log_console(struct uio *uio)
250{
251 int c, i, error, iovlen, nl;
252 struct uio muio;
253 struct iovec *miov = NULL;
254 char *consbuffer;
255 int pri;
256
257 if (!log_console_output)
258 return;
259
260 pri = LOG_INFO | LOG_CONSOLE;
261 muio = *uio;
262 iovlen = uio->uio_iovcnt * sizeof (struct iovec);
263 MALLOC(miov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
264 MALLOC(consbuffer, char *, CONSCHUNK, M_TEMP, M_WAITOK);
265 bcopy((caddr_t)muio.uio_iov, (caddr_t)miov, iovlen);
266 muio.uio_iov = miov;
267 uio = &muio;
268
269 nl = 0;
270 while (uio->uio_resid > 0) {
e54488bb
MD
271 c = (int)szmin(uio->uio_resid, CONSCHUNK);
272 error = uiomove(consbuffer, (size_t)c, uio);
984263bc 273 if (error != 0)
a0a36cfd 274 break;
984263bc
MD
275 for (i = 0; i < c; i++) {
276 msglogchar(consbuffer[i], pri);
277 if (consbuffer[i] == '\n')
278 nl = 1;
279 else
280 nl = 0;
281 }
282 }
283 if (!nl)
284 msglogchar('\n', pri);
285 msgbuftrigger = 1;
286 FREE(miov, M_TEMP);
287 FREE(consbuffer, M_TEMP);
288 return;
289}
290
e02941a7
MD
291/*
292 * Output to the console.
e02941a7 293 */
984263bc 294int
169276ba
MD
295kprintf(const char *fmt, ...)
296{
297 __va_list ap;
298 int savintr;
299 struct putchar_arg pca;
300 int retval;
301
302 savintr = consintr; /* disable interrupts */
303 consintr = 0;
304 __va_start(ap, fmt);
305 pca.tty = NULL;
306 pca.flags = TOCONS | TOLOG;
307 pca.pri = -1;
169276ba 308 retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
169276ba
MD
309 __va_end(ap);
310 if (!panicstr)
311 msgbuftrigger = 1;
312 consintr = savintr; /* reenable interrupts */
a0a36cfd 313 return (retval);
169276ba
MD
314}
315
984263bc 316int
379210cb 317kvprintf(const char *fmt, __va_list ap)
984263bc
MD
318{
319 int savintr;
320 struct putchar_arg pca;
321 int retval;
322
323 savintr = consintr; /* disable interrupts */
324 consintr = 0;
325 pca.tty = NULL;
326 pca.flags = TOCONS | TOLOG;
327 pca.pri = -1;
379210cb 328 retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
984263bc
MD
329 if (!panicstr)
330 msgbuftrigger = 1;
331 consintr = savintr; /* reenable interrupts */
a0a36cfd 332 return (retval);
984263bc
MD
333}
334
335/*
c8dfd00d
MD
336 * Limited rate kprintf. The passed rate structure must be initialized
337 * with the desired reporting frequency. A frequency of 0 will result in
338 * no output.
448f8e02
MD
339 *
340 * count may be initialized to a negative number to allow an initial
341 * burst.
c8dfd00d
MD
342 */
343void
344krateprintf(struct krate *rate, const char *fmt, ...)
345{
346 __va_list ap;
347
1c9c514a
MD
348 if (rate->ticks != (int)time_second) {
349 rate->ticks = (int)time_second;
448f8e02
MD
350 if (rate->count > 0)
351 rate->count = 0;
c8dfd00d
MD
352 }
353 if (rate->count < rate->freq) {
354 ++rate->count;
355 __va_start(ap, fmt);
356 kvprintf(fmt, ap);
357 __va_end(ap);
358 }
359}
360
361/*
137b3005
MD
362 * Print a character to the dmesg log, the console, and/or the user's
363 * terminal.
e02941a7 364 *
28d7e704
MD
365 * NOTE: TOTTY does not require nonblocking operation, but TOCONS
366 * and TOLOG do. When we have a constty we still output to
367 * the real console but we have a monitoring thread which
368 * we wakeup which tracks the log.
984263bc
MD
369 */
370static void
0ced1954 371kputchar(int c, void *arg)
984263bc
MD
372{
373 struct putchar_arg *ap = (struct putchar_arg*) arg;
374 int flags = ap->flags;
375 struct tty *tp = ap->tty;
137b3005 376
984263bc
MD
377 if (panicstr)
378 constty = NULL;
28d7e704
MD
379 if ((flags & TOCONS) && tp == NULL && constty)
380 flags |= TOLOG | TOWAKEUP;
e5104a66
MD
381 if ((flags & TOTTY) && tputchar(c, tp) < 0)
382 ap->flags &= ~TOTTY;
984263bc
MD
383 if ((flags & TOLOG))
384 msglogchar(c, ap->pri);
28d7e704 385 if ((flags & TOCONS) && c)
5fddbda2 386 cnputc(c);
28d7e704
MD
387 if (flags & TOWAKEUP)
388 wakeup(constty_td);
984263bc
MD
389}
390
391/*
392 * Scaled down version of sprintf(3).
393 */
394int
169276ba
MD
395ksprintf(char *buf, const char *cfmt, ...)
396{
397 int retval;
398 __va_list ap;
399
400 __va_start(ap, cfmt);
401 retval = kvcprintf(cfmt, NULL, (void *)buf, 10, ap);
402 buf[retval] = '\0';
403 __va_end(ap);
a0a36cfd 404 return (retval);
169276ba
MD
405}
406
407/*
984263bc
MD
408 * Scaled down version of vsprintf(3).
409 */
410int
379210cb 411kvsprintf(char *buf, const char *cfmt, __va_list ap)
984263bc
MD
412{
413 int retval;
414
379210cb 415 retval = kvcprintf(cfmt, NULL, (void *)buf, 10, ap);
984263bc 416 buf[retval] = '\0';
a0a36cfd 417 return (retval);
984263bc
MD
418}
419
420/*
421 * Scaled down version of snprintf(3).
422 */
423int
169276ba
MD
424ksnprintf(char *str, size_t size, const char *format, ...)
425{
426 int retval;
427 __va_list ap;
984263bc 428
e2565a42 429 __va_start(ap, format);
379210cb 430 retval = kvsnprintf(str, size, format, ap);
e2565a42 431 __va_end(ap);
984263bc
MD
432 return(retval);
433}
434
435/*
436 * Scaled down version of vsnprintf(3).
437 */
438int
379210cb 439kvsnprintf(char *str, size_t size, const char *format, __va_list ap)
984263bc
MD
440{
441 struct snprintf_arg info;
442 int retval;
443
444 info.str = str;
445 info.remain = size;
379210cb 446 retval = kvcprintf(format, snprintf_func, &info, 10, ap);
984263bc
MD
447 if (info.remain >= 1)
448 *info.str++ = '\0';
a0a36cfd 449 return (retval);
984263bc
MD
450}
451
93c46bf9
MD
452int
453ksnrprintf(char *str, size_t size, int radix, const char *format, ...)
454{
455 int retval;
456 __va_list ap;
457
458 __va_start(ap, format);
459 retval = kvsnrprintf(str, size, radix, format, ap);
460 __va_end(ap);
461 return(retval);
462}
463
464int
465kvsnrprintf(char *str, size_t size, int radix, const char *format, __va_list ap)
466{
467 struct snprintf_arg info;
468 int retval;
469
470 info.str = str;
471 info.remain = size;
472 retval = kvcprintf(format, snprintf_func, &info, radix, ap);
473 if (info.remain >= 1)
474 *info.str++ = '\0';
475 return (retval);
476}
477
478int
479kvasnrprintf(char **strp, size_t size, int radix,
480 const char *format, __va_list ap)
481{
482 struct snprintf_arg info;
483 int retval;
484
485 *strp = kmalloc(size, M_TEMP, M_WAITOK);
486 info.str = *strp;
487 info.remain = size;
488 retval = kvcprintf(format, snprintf_func, &info, radix, ap);
489 if (info.remain >= 1)
490 *info.str++ = '\0';
491 return (retval);
492}
493
494void
495kvasfree(char **strp)
496{
497 if (*strp) {
498 kfree(*strp, M_TEMP);
499 *strp = NULL;
500 }
501}
502
984263bc
MD
503static void
504snprintf_func(int ch, void *arg)
505{
506 struct snprintf_arg *const info = arg;
507
508 if (info->remain >= 2) {
509 *info->str++ = ch;
510 info->remain--;
511 }
512}
513
514/*
515 * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
516 * order; return an optional length and a pointer to the last character
517 * written in the buffer (i.e., the first character of the string).
518 * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
519 */
520static char *
a0a36cfd 521ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
984263bc 522{
a0a36cfd 523 char *p, c;
984263bc
MD
524
525 p = nbuf;
526 *p = '\0';
527 do {
a0a36cfd
SW
528 c = hex2ascii(num % base);
529 *++p = upper ? toupper(c) : c;
530 } while (num /= base);
984263bc
MD
531 if (lenp)
532 *lenp = p - nbuf;
533 return (p);
534}
535
536/*
537 * Scaled down version of printf(3).
538 *
539 * Two additional formats:
540 *
541 * The format %b is supported to decode error registers.
542 * Its usage is:
543 *
71681fd7 544 * kprintf("reg=%b\n", regval, "<base><arg>*");
984263bc
MD
545 *
546 * where <base> is the output base expressed as a control character, e.g.
547 * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
548 * the first of which gives the bit number to be inspected (origin 1), and
549 * the next characters (up to a control character, i.e. a character <= 32),
550 * give the name of the register. Thus:
551 *
379210cb 552 * kvcprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
984263bc
MD
553 *
554 * would produce output:
555 *
556 * reg=3<BITTWO,BITONE>
557 *
558 * XXX: %D -- Hexdump, takes pointer and separator string:
559 * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
560 * ("%*D", len, ptr, " " -> XX XX XX XX ...
561 */
5fddbda2
MD
562
563#define PCHAR(c) {int cc=(c); if(func) (*func)(cc,arg); else *d++=cc; retval++;}
564
984263bc 565int
5fddbda2
MD
566kvcprintf(char const *fmt, void (*func)(int, void*), void *arg,
567 int radix, __va_list ap)
984263bc 568{
984263bc 569 char nbuf[MAXNBUF];
a0a36cfd
SW
570 char *d;
571 const char *p, *percent, *q;
984263bc
MD
572 u_char *up;
573 int ch, n;
a0a36cfd
SW
574 uintmax_t num;
575 int base, tmp, width, ladjust, sharpflag, neg, sign, dot;
f481fa5d 576 int cflag, hflag, jflag, lflag, qflag, tflag, zflag;
a0a36cfd 577 int dwidth, upper;
984263bc 578 char padc;
a0a36cfd 579 int retval = 0, stop = 0;
438acbcc
MD
580 int usespin;
581
582 /*
583 * Make a supreme effort to avoid reentrant panics or deadlocks.
3dc9b698
MD
584 *
585 * NOTE! Do nothing that would access mycpu/gd/fs unless the
586 * function is the normal kputchar(), which allows us to
587 * use this function for very early debugging with a special
588 * function.
438acbcc
MD
589 */
590 if (func == kputchar) {
591 if (mycpu->gd_flags & GDF_KPRINTF)
592 return(0);
593 atomic_set_long(&mycpu->gd_flags, GDF_KPRINTF);
594 }
984263bc 595
a0a36cfd 596 num = 0;
984263bc
MD
597 if (!func)
598 d = (char *) arg;
599 else
600 d = NULL;
601
602 if (fmt == NULL)
603 fmt = "(fmt null)\n";
604
605 if (radix < 2 || radix > 36)
606 radix = 10;
607
3dc9b698
MD
608 usespin = (func == kputchar &&
609 panic_cpu_gd != mycpu &&
438acbcc
MD
610 (((struct putchar_arg *)arg)->flags & TOTTY) == 0);
611 if (usespin) {
5fddbda2 612 crit_enter_hard();
287a8577 613 spin_lock(&cons_spin);
5fddbda2
MD
614 }
615
984263bc
MD
616 for (;;) {
617 padc = ' ';
618 width = 0;
a0a36cfd
SW
619 while ((ch = (u_char)*fmt++) != '%' || stop) {
620 if (ch == '\0')
5fddbda2 621 goto done;
984263bc
MD
622 PCHAR(ch);
623 }
a0a36cfd
SW
624 percent = fmt - 1;
625 dot = dwidth = ladjust = neg = sharpflag = sign = upper = 0;
f481fa5d 626 cflag = hflag = jflag = lflag = qflag = tflag = zflag = 0;
a0a36cfd
SW
627
628reswitch:
629 switch (ch = (u_char)*fmt++) {
984263bc
MD
630 case '.':
631 dot = 1;
632 goto reswitch;
633 case '#':
634 sharpflag = 1;
635 goto reswitch;
636 case '+':
637 sign = 1;
638 goto reswitch;
639 case '-':
640 ladjust = 1;
641 goto reswitch;
642 case '%':
643 PCHAR(ch);
644 break;
645 case '*':
646 if (!dot) {
e2565a42 647 width = __va_arg(ap, int);
984263bc
MD
648 if (width < 0) {
649 ladjust = !ladjust;
650 width = -width;
651 }
652 } else {
e2565a42 653 dwidth = __va_arg(ap, int);
984263bc
MD
654 }
655 goto reswitch;
656 case '0':
657 if (!dot) {
658 padc = '0';
659 goto reswitch;
660 }
661 case '1': case '2': case '3': case '4':
662 case '5': case '6': case '7': case '8': case '9':
663 for (n = 0;; ++fmt) {
664 n = n * 10 + ch - '0';
665 ch = *fmt;
666 if (ch < '0' || ch > '9')
667 break;
668 }
669 if (dot)
670 dwidth = n;
671 else
672 width = n;
673 goto reswitch;
674 case 'b':
a0a36cfd 675 num = (u_int)__va_arg(ap, int);
e2565a42 676 p = __va_arg(ap, char *);
a0a36cfd 677 for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
984263bc
MD
678 PCHAR(*q--);
679
a0a36cfd 680 if (num == 0)
984263bc
MD
681 break;
682
683 for (tmp = 0; *p;) {
684 n = *p++;
a0a36cfd 685 if (num & (1 << (n - 1))) {
984263bc
MD
686 PCHAR(tmp ? ',' : '<');
687 for (; (n = *p) > ' '; ++p)
688 PCHAR(n);
689 tmp = 1;
690 } else
691 for (; *p > ' '; ++p)
692 continue;
693 }
694 if (tmp)
695 PCHAR('>');
696 break;
697 case 'c':
e2565a42 698 PCHAR(__va_arg(ap, int));
984263bc
MD
699 break;
700 case 'D':
e2565a42
MD
701 up = __va_arg(ap, u_char *);
702 p = __va_arg(ap, char *);
984263bc
MD
703 if (!width)
704 width = 16;
705 while(width--) {
706 PCHAR(hex2ascii(*up >> 4));
707 PCHAR(hex2ascii(*up & 0x0f));
708 up++;
709 if (width)
710 for (q=p;*q;q++)
711 PCHAR(*q);
712 }
713 break;
714 case 'd':
a0a36cfd 715 case 'i':
984263bc 716 base = 10;
a0a36cfd
SW
717 sign = 1;
718 goto handle_sign;
f481fa5d
SW
719 case 'h':
720 if (hflag) {
721 hflag = 0;
722 cflag = 1;
723 } else
724 hflag = 1;
725 goto reswitch;
a0a36cfd
SW
726 case 'j':
727 jflag = 1;
728 goto reswitch;
984263bc
MD
729 case 'l':
730 if (lflag) {
731 lflag = 0;
732 qflag = 1;
733 } else
734 lflag = 1;
735 goto reswitch;
a0a36cfd 736 case 'n':
f481fa5d
SW
737 if (cflag)
738 *(__va_arg(ap, char *)) = retval;
739 else if (hflag)
740 *(__va_arg(ap, short *)) = retval;
741 else if (jflag)
a0a36cfd 742 *(__va_arg(ap, intmax_t *)) = retval;
984263bc 743 else if (lflag)
a0a36cfd
SW
744 *(__va_arg(ap, long *)) = retval;
745 else if (qflag)
746 *(__va_arg(ap, quad_t *)) = retval;
984263bc 747 else
a0a36cfd
SW
748 *(__va_arg(ap, int *)) = retval;
749 break;
750 case 'o':
984263bc 751 base = 8;
a0a36cfd 752 goto handle_nosign;
984263bc 753 case 'p':
984263bc
MD
754 base = 16;
755 sharpflag = (width == 0);
a0a36cfd
SW
756 sign = 0;
757 num = (uintptr_t)__va_arg(ap, void *);
758 goto number;
984263bc
MD
759 case 'q':
760 qflag = 1;
761 goto reswitch;
984263bc 762 case 'r':
984263bc 763 base = radix;
a0a36cfd
SW
764 if (sign)
765 goto handle_sign;
766 goto handle_nosign;
984263bc 767 case 's':
e2565a42 768 p = __va_arg(ap, char *);
984263bc
MD
769 if (p == NULL)
770 p = "(null)";
771 if (!dot)
772 n = strlen (p);
773 else
774 for (n = 0; n < dwidth && p[n]; n++)
775 continue;
776
777 width -= n;
778
779 if (!ladjust && width > 0)
780 while (width--)
781 PCHAR(padc);
782 while (n--)
783 PCHAR(*p++);
784 if (ladjust && width > 0)
785 while (width--)
786 PCHAR(padc);
787 break;
a0a36cfd
SW
788 case 't':
789 tflag = 1;
790 goto reswitch;
984263bc 791 case 'u':
984263bc 792 base = 10;
a0a36cfd 793 goto handle_nosign;
984263bc 794 case 'X':
a0a36cfd
SW
795 upper = 1;
796 /* FALLTHROUGH */
797 case 'x':
984263bc 798 base = 16;
a0a36cfd 799 goto handle_nosign;
984263bc 800 case 'z':
9c7517ab
MD
801 zflag = 1;
802 goto reswitch;
a0a36cfd
SW
803handle_nosign:
804 sign = 0;
f481fa5d
SW
805 if (cflag)
806 num = (u_char)__va_arg(ap, int);
807 else if (hflag)
808 num = (u_short)__va_arg(ap, int);
809 else if (jflag)
a0a36cfd 810 num = __va_arg(ap, uintmax_t);
984263bc 811 else if (lflag)
a0a36cfd
SW
812 num = __va_arg(ap, u_long);
813 else if (qflag)
814 num = __va_arg(ap, u_quad_t);
815 else if (tflag)
816 num = __va_arg(ap, ptrdiff_t);
9c7517ab
MD
817 else if (zflag)
818 num = __va_arg(ap, size_t);
984263bc 819 else
a0a36cfd 820 num = __va_arg(ap, u_int);
984263bc 821 goto number;
a0a36cfd 822handle_sign:
f481fa5d
SW
823 if (cflag)
824 num = (char)__va_arg(ap, int);
825 else if (hflag)
826 num = (short)__va_arg(ap, int);
827 else if (jflag)
a0a36cfd
SW
828 num = __va_arg(ap, intmax_t);
829 else if (lflag)
830 num = __va_arg(ap, long);
831 else if (qflag)
832 num = __va_arg(ap, quad_t);
833 else if (tflag)
834 num = __va_arg(ap, ptrdiff_t);
9c7517ab
MD
835 else if (zflag)
836 num = __va_arg(ap, ssize_t);
a0a36cfd
SW
837 else
838 num = __va_arg(ap, int);
839number:
840 if (sign && (intmax_t)num < 0) {
841 neg = 1;
842 num = -(intmax_t)num;
984263bc 843 }
a0a36cfd
SW
844 p = ksprintn(nbuf, num, base, &tmp, upper);
845 if (sharpflag && num != 0) {
984263bc
MD
846 if (base == 8)
847 tmp++;
848 else if (base == 16)
849 tmp += 2;
850 }
851 if (neg)
852 tmp++;
853
a0a36cfd
SW
854 if (!ladjust && padc != '0' && width &&
855 (width -= tmp) > 0) {
984263bc
MD
856 while (width--)
857 PCHAR(padc);
a0a36cfd 858 }
984263bc
MD
859 if (neg)
860 PCHAR('-');
a0a36cfd 861 if (sharpflag && num != 0) {
984263bc
MD
862 if (base == 8) {
863 PCHAR('0');
864 } else if (base == 16) {
865 PCHAR('0');
866 PCHAR('x');
867 }
868 }
a0a36cfd
SW
869 if (!ladjust && width && (width -= tmp) > 0)
870 while (width--)
871 PCHAR(padc);
984263bc
MD
872
873 while (*p)
874 PCHAR(*p--);
875
876 if (ladjust && width && (width -= tmp) > 0)
877 while (width--)
878 PCHAR(padc);
879
880 break;
881 default:
a0a36cfd
SW
882 while (percent < fmt)
883 PCHAR(*percent++);
884 /*
885 * Since we ignore an formatting argument it is no
886 * longer safe to obey the remaining formatting
887 * arguments as the arguments will no longer match
888 * the format specs.
889 */
890 stop = 1;
984263bc
MD
891 break;
892 }
893 }
5fddbda2 894done:
438acbcc
MD
895 /*
896 * Cleanup reentrancy issues.
897 */
898 if (func == kputchar)
899 atomic_clear_long(&mycpu->gd_flags, GDF_KPRINTF);
900 if (usespin) {
287a8577 901 spin_unlock(&cons_spin);
5fddbda2
MD
902 crit_exit_hard();
903 }
904 return (retval);
905}
906
984263bc 907#undef PCHAR
5fddbda2
MD
908
909/*
438acbcc
MD
910 * Called from the panic code to try to get the console working
911 * again in case we paniced inside a kprintf().
5fddbda2
MD
912 */
913void
914kvcreinitspin(void)
915{
916 spin_init(&cons_spin);
438acbcc 917 atomic_clear_long(&mycpu->gd_flags, GDF_KPRINTF);
984263bc
MD
918}
919
28d7e704
MD
920/*
921 * Console support thread for constty intercepts. This is needed because
922 * console tty intercepts can block. Instead of having kputchar() attempt
923 * to directly write to the console intercept we just force it to log
924 * and wakeup this baby to track and dump the log to constty.
925 */
926static void
927constty_daemon(void)
928{
929 int rindex = -1;
930 int windex = -1;
931 struct msgbuf *mbp;
932 struct tty *tp;
933
934 EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc,
935 constty_td, SHUTDOWN_PRI_FIRST);
936 constty_td->td_flags |= TDF_SYSTHREAD;
937
938 for (;;) {
939 kproc_suspend_loop();
940
941 crit_enter();
942 mbp = msgbufp;
943 if (mbp == NULL || msgbufmapped == 0 ||
944 windex == mbp->msg_bufx) {
945 tsleep(constty_td, 0, "waiting", hz*60);
946 crit_exit();
947 continue;
948 }
949 windex = mbp->msg_bufx;
950 crit_exit();
951
952 /*
953 * Get message buf FIFO indices. rindex is tracking.
954 */
955 if ((tp = constty) == NULL) {
956 rindex = mbp->msg_bufx;
957 continue;
958 }
959
960 /*
961 * Don't blow up if the message buffer is broken
962 */
963 if (windex < 0 || windex >= mbp->msg_size)
964 continue;
965 if (rindex < 0 || rindex >= mbp->msg_size)
966 rindex = windex;
967
968 /*
969 * And dump it. If constty gets stuck will give up.
970 */
971 while (rindex != windex) {
972 if (tputchar((uint8_t)mbp->msg_ptr[rindex], tp) < 0) {
973 constty = NULL;
974 rindex = mbp->msg_bufx;
975 break;
976 }
977 if (++rindex >= mbp->msg_size)
978 rindex = 0;
979 if (tp->t_outq.c_cc >= tp->t_ohiwat) {
980 tsleep(constty_daemon, 0, "blocked", hz / 10);
981 if (tp->t_outq.c_cc >= tp->t_ohiwat) {
982 rindex = windex;
983 break;
984 }
985 }
986 }
987 }
988}
989
990static struct kproc_desc constty_kp = {
991 "consttyd",
992 constty_daemon,
993 &constty_td
994};
995SYSINIT(bufdaemon, SI_SUB_KTHREAD_UPDATE, SI_ORDER_ANY,
996 kproc_start, &constty_kp)
5fddbda2 997
984263bc
MD
998/*
999 * Put character in log buffer with a particular priority.
e02941a7
MD
1000 *
1001 * MPSAFE
984263bc
MD
1002 */
1003static void
1004msglogchar(int c, int pri)
1005{
1006 static int lastpri = -1;
1007 static int dangling;
1008 char nbuf[MAXNBUF];
1009 char *p;
1010
1011 if (!msgbufmapped)
1012 return;
1013 if (c == '\0' || c == '\r')
1014 return;
1015 if (pri != -1 && pri != lastpri) {
1016 if (dangling) {
1017 msgaddchar('\n', NULL);
1018 dangling = 0;
1019 }
1020 msgaddchar('<', NULL);
a0a36cfd 1021 for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL, 0); *p;)
984263bc
MD
1022 msgaddchar(*p--, NULL);
1023 msgaddchar('>', NULL);
1024 lastpri = pri;
1025 }
1026 msgaddchar(c, NULL);
1027 if (c == '\n') {
1028 dangling = 0;
1029 lastpri = -1;
1030 } else {
1031 dangling = 1;
1032 }
1033}
1034
1035/*
e02941a7
MD
1036 * Put char in log buffer. Make sure nothing blows up beyond repair if
1037 * we have an MP race.
1038 *
1039 * MPSAFE.
984263bc
MD
1040 */
1041static void
1042msgaddchar(int c, void *dummy)
1043{
1044 struct msgbuf *mbp;
e02941a7
MD
1045 int rindex;
1046 int windex;
984263bc
MD
1047
1048 if (!msgbufmapped)
1049 return;
1050 mbp = msgbufp;
e02941a7
MD
1051 windex = mbp->msg_bufx;
1052 mbp->msg_ptr[windex] = c;
1053 if (++windex >= mbp->msg_size)
1054 windex = 0;
1055 rindex = mbp->msg_bufr;
1056 if (windex == rindex) {
1057 rindex += 32;
1058 if (rindex >= mbp->msg_size)
1059 rindex -= mbp->msg_size;
1060 mbp->msg_bufr = rindex;
984263bc 1061 }
e02941a7 1062 mbp->msg_bufx = windex;
984263bc
MD
1063}
1064
1065static void
1066msgbufcopy(struct msgbuf *oldp)
1067{
1068 int pos;
1069
1070 pos = oldp->msg_bufr;
1071 while (pos != oldp->msg_bufx) {
1072 msglogchar(oldp->msg_ptr[pos], -1);
1073 if (++pos >= oldp->msg_size)
1074 pos = 0;
1075 }
1076}
1077
1078void
1079msgbufinit(void *ptr, size_t size)
1080{
1081 char *cp;
1082 static struct msgbuf *oldp = NULL;
1083
1084 size -= sizeof(*msgbufp);
1085 cp = (char *)ptr;
1086 msgbufp = (struct msgbuf *) (cp + size);
1087 if (msgbufp->msg_magic != MSG_MAGIC || msgbufp->msg_size != size ||
1088 msgbufp->msg_bufx >= size || msgbufp->msg_bufr >= size) {
1089 bzero(cp, size);
1090 bzero(msgbufp, sizeof(*msgbufp));
1091 msgbufp->msg_magic = MSG_MAGIC;
1092 msgbufp->msg_size = (char *)msgbufp - cp;
1093 }
1094 msgbufp->msg_ptr = cp;
1095 if (msgbufmapped && oldp != msgbufp)
1096 msgbufcopy(oldp);
1097 msgbufmapped = 1;
1098 oldp = msgbufp;
1099}
1100
1101/* Sysctls for accessing/clearing the msgbuf */
d41cbec3 1102
984263bc
MD
1103static int
1104sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)
1105{
d41cbec3 1106 struct ucred *cred;
984263bc
MD
1107 int error;
1108
1109 /*
d41cbec3
MD
1110 * Only wheel or root can access the message log.
1111 */
1112 if (unprivileged_read_msgbuf == 0) {
1113 KKASSERT(req->td->td_proc);
1114 cred = req->td->td_proc->p_ucred;
1115
1116 if ((cred->cr_prison || groupmember(0, cred) == 0) &&
895c1f85 1117 priv_check(req->td, PRIV_ROOT) != 0
d41cbec3
MD
1118 ) {
1119 return (EPERM);
1120 }
1121 }
1122
1123 /*
984263bc
MD
1124 * Unwind the buffer, so that it's linear (possibly starting with
1125 * some initial nulls).
1126 */
1127 error = sysctl_handle_opaque(oidp, msgbufp->msg_ptr + msgbufp->msg_bufx,
1128 msgbufp->msg_size - msgbufp->msg_bufx, req);
1129 if (error)
1130 return (error);
1131 if (msgbufp->msg_bufx > 0) {
1132 error = sysctl_handle_opaque(oidp, msgbufp->msg_ptr,
1133 msgbufp->msg_bufx, req);
1134 }
1135 return (error);
1136}
1137
1138SYSCTL_PROC(_kern, OID_AUTO, msgbuf, CTLTYPE_STRING | CTLFLAG_RD,
1139 0, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer");
1140
1141static int msgbuf_clear;
1142
1143static int
1144sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS)
1145{
1146 int error;
1147 error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
1148 if (!error && req->newptr) {
1149 /* Clear the buffer and reset write pointer */
1150 bzero(msgbufp->msg_ptr, msgbufp->msg_size);
1151 msgbufp->msg_bufr = msgbufp->msg_bufx = 0;
1152 msgbuf_clear = 0;
1153 }
1154 return (error);
1155}
1156
1157SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear,
a0a36cfd 1158 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, &msgbuf_clear, 0,
984263bc
MD
1159 sysctl_kern_msgbuf_clear, "I", "Clear kernel message buffer");
1160
984263bc 1161#ifdef DDB
984263bc
MD
1162
1163DB_SHOW_COMMAND(msgbuf, db_show_msgbuf)
1164{
1165 int i, j;
1166
1167 if (!msgbufmapped) {
1168 db_printf("msgbuf not mapped yet\n");
1169 return;
1170 }
1171 db_printf("msgbufp = %p\n", msgbufp);
1172 db_printf("magic = %x, size = %d, r= %d, w = %d, ptr = %p\n",
1173 msgbufp->msg_magic, msgbufp->msg_size, msgbufp->msg_bufr,
1174 msgbufp->msg_bufx, msgbufp->msg_ptr);
1175 for (i = 0; i < msgbufp->msg_size; i++) {
1176 j = (i + msgbufp->msg_bufr) % msgbufp->msg_size;
1177 db_printf("%c", msgbufp->msg_ptr[j]);
1178 }
1179 db_printf("\n");
1180}
1181
1182#endif /* DDB */
37f44315
SW
1183
1184
1185void
1186hexdump(const void *ptr, int length, const char *hdr, int flags)
1187{
1188 int i, j, k;
1189 int cols;
1190 const unsigned char *cp;
1191 char delim;
1192
1193 if ((flags & HD_DELIM_MASK) != 0)
1194 delim = (flags & HD_DELIM_MASK) >> 8;
1195 else
1196 delim = ' ';
1197
1198 if ((flags & HD_COLUMN_MASK) != 0)
1199 cols = flags & HD_COLUMN_MASK;
1200 else
1201 cols = 16;
1202
1203 cp = ptr;
1204 for (i = 0; i < length; i+= cols) {
1205 if (hdr != NULL)
1206 kprintf("%s", hdr);
1207
1208 if ((flags & HD_OMIT_COUNT) == 0)
1209 kprintf("%04x ", i);
1210
1211 if ((flags & HD_OMIT_HEX) == 0) {
1212 for (j = 0; j < cols; j++) {
1213 k = i + j;
1214 if (k < length)
1215 kprintf("%c%02x", delim, cp[k]);
1216 else
1217 kprintf(" ");
1218 }
1219 }
1220
1221 if ((flags & HD_OMIT_CHARS) == 0) {
1222 kprintf(" |");
1223 for (j = 0; j < cols; j++) {
1224 k = i + j;
1225 if (k >= length)
1226 kprintf(" ");
1227 else if (cp[k] >= ' ' && cp[k] <= '~')
1228 kprintf("%c", cp[k]);
1229 else
1230 kprintf(".");
1231 }
1232 kprintf("|");
1233 }
1234 kprintf("\n");
1235 }
1236}