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 $ 40 * $DragonFly: src/sys/kern/subr_prf.c,v 1.21 2008/07/17 23:56:23 dillon Exp $ 41 */ 42 43 #include "opt_ddb.h" 44 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> 51 #include <sys/priv.h> 52 #include <sys/tty.h> 53 #include <sys/tprintf.h> 54 #include <sys/stdint.h> 55 #include <sys/syslog.h> 56 #include <sys/cons.h> 57 #include <sys/uio.h> 58 #include <sys/sysctl.h> 59 #include <sys/lock.h> 60 #include <sys/ctype.h> 61 #include <sys/eventhandler.h> 62 #include <sys/kthread.h> 63 64 #include <sys/thread2.h> 65 #include <sys/spinlock2.h> 66 67 #ifdef DDB 68 #include <ddb/ddb.h> 69 #endif 70 71 /* 72 * Note that stdarg.h and the ANSI style va_start macro is used for both 73 * ANSI and traditional C compilers. We use the __ machine version to stay 74 * within the kernel header file set. 75 */ 76 #include <machine/stdarg.h> 77 78 #define TOCONS 0x01 79 #define TOTTY 0x02 80 #define TOLOG 0x04 81 #define TOWAKEUP 0x08 82 83 /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */ 84 #define MAXNBUF (sizeof(intmax_t) * NBBY + 1) 85 86 struct putchar_arg { 87 int flags; 88 int pri; 89 struct tty *tty; 90 }; 91 92 struct snprintf_arg { 93 char *str; 94 size_t remain; 95 }; 96 97 extern int log_open; 98 99 struct tty *constty; /* pointer to console "window" tty */ 100 101 static void msglogchar(int c, int pri); 102 static void msgaddchar(int c, void *dummy); 103 static void kputchar (int ch, void *arg); 104 static char *ksprintn (char *nbuf, uintmax_t num, int base, int *lenp, 105 int upper); 106 static void snprintf_func (int ch, void *arg); 107 108 static int consintr = 1; /* Ok to handle console interrupts? */ 109 static int msgbufmapped; /* Set when safe to use msgbuf */ 110 static struct spinlock cons_spin = SPINLOCK_INITIALIZER(cons_spin); 111 static thread_t constty_td = NULL; 112 113 int msgbuftrigger; 114 115 static int log_console_output = 1; 116 TUNABLE_INT("kern.log_console_output", &log_console_output); 117 SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW, 118 &log_console_output, 0, ""); 119 120 static int unprivileged_read_msgbuf = 1; 121 SYSCTL_INT(_security, OID_AUTO, unprivileged_read_msgbuf, CTLFLAG_RW, 122 &unprivileged_read_msgbuf, 0, 123 "Unprivileged processes may read the kernel message buffer"); 124 125 /* 126 * Warn that a system table is full. 127 */ 128 void 129 tablefull(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. 137 */ 138 int 139 uprintf(const char *fmt, ...) 140 { 141 struct proc *p = curproc; 142 __va_list ap; 143 struct putchar_arg pca; 144 int retval = 0; 145 146 if (p && (p->p_flags & P_CONTROLT) && p->p_session->s_ttyvp) { 147 __va_start(ap, fmt); 148 pca.tty = p->p_session->s_ttyp; 149 pca.flags = TOTTY; 150 151 retval = kvcprintf(fmt, kputchar, &pca, 10, ap); 152 __va_end(ap); 153 } 154 return (retval); 155 } 156 157 tpr_t 158 tprintf_open(struct proc *p) 159 { 160 if ((p->p_flags & P_CONTROLT) && p->p_session->s_ttyvp) { 161 sess_hold(p->p_session); 162 return ((tpr_t) p->p_session); 163 } 164 return ((tpr_t) NULL); 165 } 166 167 void 168 tprintf_close(tpr_t sess) 169 { 170 if (sess) 171 sess_rele((struct session *) sess); 172 } 173 174 /* 175 * tprintf prints on the controlling terminal associated 176 * with the given session. 177 */ 178 int 179 tprintf(tpr_t tpr, const char *fmt, ...) 180 { 181 struct session *sess = (struct session *)tpr; 182 struct tty *tp = NULL; 183 int flags = TOLOG; 184 __va_list ap; 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 } 192 __va_start(ap, fmt); 193 pca.tty = tp; 194 pca.flags = flags; 195 pca.pri = LOG_INFO; 196 retval = kvcprintf(fmt, kputchar, &pca, 10, ap); 197 __va_end(ap); 198 msgbuftrigger = 1; 199 return (retval); 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 */ 207 int 208 ttyprintf(struct tty *tp, const char *fmt, ...) 209 { 210 __va_list ap; 211 struct putchar_arg pca; 212 int retval; 213 214 __va_start(ap, fmt); 215 pca.tty = tp; 216 pca.flags = TOTTY; 217 retval = kvcprintf(fmt, kputchar, &pca, 10, ap); 218 __va_end(ap); 219 return (retval); 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 */ 227 int 228 log(int level, const char *fmt, ...) 229 { 230 __va_list ap; 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 238 __va_start(ap, fmt); 239 retval = kvcprintf(fmt, kputchar, &pca, 10, ap); 240 __va_end(ap); 241 242 msgbuftrigger = 1; 243 return (retval); 244 } 245 246 #define CONSCHUNK 128 247 248 void 249 log_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) { 271 c = (int)szmin(uio->uio_resid, CONSCHUNK); 272 error = uiomove(consbuffer, (size_t)c, uio); 273 if (error != 0) 274 break; 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 291 /* 292 * Output to the console. 293 */ 294 int 295 kprintf(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; 308 retval = kvcprintf(fmt, kputchar, &pca, 10, ap); 309 __va_end(ap); 310 if (!panicstr) 311 msgbuftrigger = 1; 312 consintr = savintr; /* reenable interrupts */ 313 return (retval); 314 } 315 316 int 317 kvprintf(const char *fmt, __va_list ap) 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; 328 retval = kvcprintf(fmt, kputchar, &pca, 10, ap); 329 if (!panicstr) 330 msgbuftrigger = 1; 331 consintr = savintr; /* reenable interrupts */ 332 return (retval); 333 } 334 335 /* 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. 339 * 340 * count may be initialized to a negative number to allow an initial 341 * burst. 342 */ 343 void 344 krateprintf(struct krate *rate, const char *fmt, ...) 345 { 346 __va_list ap; 347 348 if (rate->ticks != (int)time_second) { 349 rate->ticks = (int)time_second; 350 if (rate->count > 0) 351 rate->count = 0; 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 /* 362 * Print a character to the dmesg log, the console, and/or the user's 363 * terminal. 364 * 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. 369 */ 370 static void 371 kputchar(int c, void *arg) 372 { 373 struct putchar_arg *ap = (struct putchar_arg*) arg; 374 int flags = ap->flags; 375 struct tty *tp = ap->tty; 376 377 if (panicstr) 378 constty = NULL; 379 if ((flags & TOCONS) && tp == NULL && constty) 380 flags |= TOLOG | TOWAKEUP; 381 if ((flags & TOTTY) && tputchar(c, tp) < 0) 382 ap->flags &= ~TOTTY; 383 if ((flags & TOLOG)) 384 msglogchar(c, ap->pri); 385 if ((flags & TOCONS) && c) 386 cnputc(c); 387 if (flags & TOWAKEUP) 388 wakeup(constty_td); 389 } 390 391 /* 392 * Scaled down version of sprintf(3). 393 */ 394 int 395 ksprintf(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); 404 return (retval); 405 } 406 407 /* 408 * Scaled down version of vsprintf(3). 409 */ 410 int 411 kvsprintf(char *buf, const char *cfmt, __va_list ap) 412 { 413 int retval; 414 415 retval = kvcprintf(cfmt, NULL, (void *)buf, 10, ap); 416 buf[retval] = '\0'; 417 return (retval); 418 } 419 420 /* 421 * Scaled down version of snprintf(3). 422 */ 423 int 424 ksnprintf(char *str, size_t size, const char *format, ...) 425 { 426 int retval; 427 __va_list ap; 428 429 __va_start(ap, format); 430 retval = kvsnprintf(str, size, format, ap); 431 __va_end(ap); 432 return(retval); 433 } 434 435 /* 436 * Scaled down version of vsnprintf(3). 437 */ 438 int 439 kvsnprintf(char *str, size_t size, const char *format, __va_list ap) 440 { 441 struct snprintf_arg info; 442 int retval; 443 444 info.str = str; 445 info.remain = size; 446 retval = kvcprintf(format, snprintf_func, &info, 10, ap); 447 if (info.remain >= 1) 448 *info.str++ = '\0'; 449 return (retval); 450 } 451 452 int 453 ksnrprintf(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 464 int 465 kvsnrprintf(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 478 int 479 kvasnrprintf(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 494 void 495 kvasfree(char **strp) 496 { 497 if (*strp) { 498 kfree(*strp, M_TEMP); 499 *strp = NULL; 500 } 501 } 502 503 static void 504 snprintf_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 */ 520 static char * 521 ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper) 522 { 523 char *p, c; 524 525 p = nbuf; 526 *p = '\0'; 527 do { 528 c = hex2ascii(num % base); 529 *++p = upper ? toupper(c) : c; 530 } while (num /= base); 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 * 544 * kprintf("reg=%b\n", regval, "<base><arg>*"); 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 * 552 * kvcprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 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 */ 562 563 #define PCHAR(c) {int cc=(c); if(func) (*func)(cc,arg); else *d++=cc; retval++;} 564 565 int 566 kvcprintf(char const *fmt, void (*func)(int, void*), void *arg, 567 int radix, __va_list ap) 568 { 569 char nbuf[MAXNBUF]; 570 char *d; 571 const char *p, *percent, *q; 572 u_char *up; 573 int ch, n; 574 uintmax_t num; 575 int base, tmp, width, ladjust, sharpflag, neg, sign, dot; 576 int cflag, hflag, jflag, lflag, qflag, tflag, zflag; 577 int dwidth, upper; 578 char padc; 579 int retval = 0, stop = 0; 580 int usespin; 581 582 /* 583 * Make a supreme effort to avoid reentrant panics or deadlocks. 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. 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 } 595 596 num = 0; 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 608 usespin = (func == kputchar && 609 panic_cpu_gd != mycpu && 610 (((struct putchar_arg *)arg)->flags & TOTTY) == 0); 611 if (usespin) { 612 crit_enter_hard(); 613 spin_lock(&cons_spin); 614 } 615 616 for (;;) { 617 padc = ' '; 618 width = 0; 619 while ((ch = (u_char)*fmt++) != '%' || stop) { 620 if (ch == '\0') 621 goto done; 622 PCHAR(ch); 623 } 624 percent = fmt - 1; 625 dot = dwidth = ladjust = neg = sharpflag = sign = upper = 0; 626 cflag = hflag = jflag = lflag = qflag = tflag = zflag = 0; 627 628 reswitch: 629 switch (ch = (u_char)*fmt++) { 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) { 647 width = __va_arg(ap, int); 648 if (width < 0) { 649 ladjust = !ladjust; 650 width = -width; 651 } 652 } else { 653 dwidth = __va_arg(ap, int); 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': 675 num = (u_int)__va_arg(ap, int); 676 p = __va_arg(ap, char *); 677 for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;) 678 PCHAR(*q--); 679 680 if (num == 0) 681 break; 682 683 for (tmp = 0; *p;) { 684 n = *p++; 685 if (num & (1 << (n - 1))) { 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': 698 PCHAR(__va_arg(ap, int)); 699 break; 700 case 'D': 701 up = __va_arg(ap, u_char *); 702 p = __va_arg(ap, char *); 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': 715 case 'i': 716 base = 10; 717 sign = 1; 718 goto handle_sign; 719 case 'h': 720 if (hflag) { 721 hflag = 0; 722 cflag = 1; 723 } else 724 hflag = 1; 725 goto reswitch; 726 case 'j': 727 jflag = 1; 728 goto reswitch; 729 case 'l': 730 if (lflag) { 731 lflag = 0; 732 qflag = 1; 733 } else 734 lflag = 1; 735 goto reswitch; 736 case 'n': 737 if (cflag) 738 *(__va_arg(ap, char *)) = retval; 739 else if (hflag) 740 *(__va_arg(ap, short *)) = retval; 741 else if (jflag) 742 *(__va_arg(ap, intmax_t *)) = retval; 743 else if (lflag) 744 *(__va_arg(ap, long *)) = retval; 745 else if (qflag) 746 *(__va_arg(ap, quad_t *)) = retval; 747 else 748 *(__va_arg(ap, int *)) = retval; 749 break; 750 case 'o': 751 base = 8; 752 goto handle_nosign; 753 case 'p': 754 base = 16; 755 sharpflag = (width == 0); 756 sign = 0; 757 num = (uintptr_t)__va_arg(ap, void *); 758 goto number; 759 case 'q': 760 qflag = 1; 761 goto reswitch; 762 case 'r': 763 base = radix; 764 if (sign) 765 goto handle_sign; 766 goto handle_nosign; 767 case 's': 768 p = __va_arg(ap, char *); 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; 788 case 't': 789 tflag = 1; 790 goto reswitch; 791 case 'u': 792 base = 10; 793 goto handle_nosign; 794 case 'X': 795 upper = 1; 796 /* FALLTHROUGH */ 797 case 'x': 798 base = 16; 799 goto handle_nosign; 800 case 'z': 801 zflag = 1; 802 goto reswitch; 803 handle_nosign: 804 sign = 0; 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) 810 num = __va_arg(ap, uintmax_t); 811 else if (lflag) 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); 817 else if (zflag) 818 num = __va_arg(ap, size_t); 819 else 820 num = __va_arg(ap, u_int); 821 goto number; 822 handle_sign: 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) 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); 835 else if (zflag) 836 num = __va_arg(ap, ssize_t); 837 else 838 num = __va_arg(ap, int); 839 number: 840 if (sign && (intmax_t)num < 0) { 841 neg = 1; 842 num = -(intmax_t)num; 843 } 844 p = ksprintn(nbuf, num, base, &tmp, upper); 845 if (sharpflag && num != 0) { 846 if (base == 8) 847 tmp++; 848 else if (base == 16) 849 tmp += 2; 850 } 851 if (neg) 852 tmp++; 853 854 if (!ladjust && padc != '0' && width && 855 (width -= tmp) > 0) { 856 while (width--) 857 PCHAR(padc); 858 } 859 if (neg) 860 PCHAR('-'); 861 if (sharpflag && num != 0) { 862 if (base == 8) { 863 PCHAR('0'); 864 } else if (base == 16) { 865 PCHAR('0'); 866 PCHAR('x'); 867 } 868 } 869 if (!ladjust && width && (width -= tmp) > 0) 870 while (width--) 871 PCHAR(padc); 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: 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; 891 break; 892 } 893 } 894 done: 895 /* 896 * Cleanup reentrancy issues. 897 */ 898 if (func == kputchar) 899 atomic_clear_long(&mycpu->gd_flags, GDF_KPRINTF); 900 if (usespin) { 901 spin_unlock(&cons_spin); 902 crit_exit_hard(); 903 } 904 return (retval); 905 } 906 907 #undef PCHAR 908 909 /* 910 * Called from the panic code to try to get the console working 911 * again in case we paniced inside a kprintf(). 912 */ 913 void 914 kvcreinitspin(void) 915 { 916 spin_init(&cons_spin); 917 atomic_clear_long(&mycpu->gd_flags, GDF_KPRINTF); 918 } 919 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 */ 926 static void 927 constty_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 990 static struct kproc_desc constty_kp = { 991 "consttyd", 992 constty_daemon, 993 &constty_td 994 }; 995 SYSINIT(bufdaemon, SI_SUB_KTHREAD_UPDATE, SI_ORDER_ANY, 996 kproc_start, &constty_kp) 997 998 /* 999 * Put character in log buffer with a particular priority. 1000 * 1001 * MPSAFE 1002 */ 1003 static void 1004 msglogchar(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); 1021 for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL, 0); *p;) 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 /* 1036 * Put char in log buffer. Make sure nothing blows up beyond repair if 1037 * we have an MP race. 1038 * 1039 * MPSAFE. 1040 */ 1041 static void 1042 msgaddchar(int c, void *dummy) 1043 { 1044 struct msgbuf *mbp; 1045 int rindex; 1046 int windex; 1047 1048 if (!msgbufmapped) 1049 return; 1050 mbp = msgbufp; 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; 1061 } 1062 mbp->msg_bufx = windex; 1063 } 1064 1065 static void 1066 msgbufcopy(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 1078 void 1079 msgbufinit(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 */ 1102 1103 static int 1104 sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS) 1105 { 1106 struct ucred *cred; 1107 int error; 1108 1109 /* 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) && 1117 priv_check(req->td, PRIV_ROOT) != 0 1118 ) { 1119 return (EPERM); 1120 } 1121 } 1122 1123 /* 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 1138 SYSCTL_PROC(_kern, OID_AUTO, msgbuf, CTLTYPE_STRING | CTLFLAG_RD, 1139 0, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer"); 1140 1141 static int msgbuf_clear; 1142 1143 static int 1144 sysctl_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 1157 SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear, 1158 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, &msgbuf_clear, 0, 1159 sysctl_kern_msgbuf_clear, "I", "Clear kernel message buffer"); 1160 1161 #ifdef DDB 1162 1163 DB_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 */ 1183 1184 1185 void 1186 hexdump(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 } 1237