1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/varargs.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/stream.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/strsubr.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/strsun.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/log.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/spl.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/syslog.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/console.h> 43*7c478bd9Sstevel@tonic-gate #include <sys/debug.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/id_space.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/zone.h> 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate log_zone_t log_global; 49*7c478bd9Sstevel@tonic-gate queue_t *log_consq; 50*7c478bd9Sstevel@tonic-gate queue_t *log_backlogq; 51*7c478bd9Sstevel@tonic-gate queue_t *log_intrq; 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #define LOG_PRISIZE 8 /* max priority size: 7 characters + null */ 54*7c478bd9Sstevel@tonic-gate #define LOG_FACSIZE 9 /* max priority size: 8 characters + null */ 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate static krwlock_t log_rwlock; 57*7c478bd9Sstevel@tonic-gate static int log_rwlock_depth; 58*7c478bd9Sstevel@tonic-gate static int log_seq_no[SL_CONSOLE + 1]; 59*7c478bd9Sstevel@tonic-gate static stdata_t log_fakestr; 60*7c478bd9Sstevel@tonic-gate static id_space_t *log_minorspace; 61*7c478bd9Sstevel@tonic-gate static log_t log_backlog; 62*7c478bd9Sstevel@tonic-gate static log_t log_conslog; 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate static queue_t *log_recentq; 65*7c478bd9Sstevel@tonic-gate static queue_t *log_freeq; 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate static zone_key_t log_zone_key; 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate static char log_overflow_msg[] = "message overflow on /dev/log minor #%d%s\n"; 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate static char log_pri[LOG_PRIMASK + 1][LOG_PRISIZE] = { 72*7c478bd9Sstevel@tonic-gate "emerg", "alert", "crit", "error", 73*7c478bd9Sstevel@tonic-gate "warning", "notice", "info", "debug" 74*7c478bd9Sstevel@tonic-gate }; 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate static char log_fac[LOG_NFACILITIES + 1][LOG_FACSIZE] = { 77*7c478bd9Sstevel@tonic-gate "kern", "user", "mail", "daemon", 78*7c478bd9Sstevel@tonic-gate "auth", "syslog", "lpr", "news", 79*7c478bd9Sstevel@tonic-gate "uucp", "resv9", "resv10", "resv11", 80*7c478bd9Sstevel@tonic-gate "resv12", "audit", "resv14", "cron", 81*7c478bd9Sstevel@tonic-gate "local0", "local1", "local2", "local3", 82*7c478bd9Sstevel@tonic-gate "local4", "local5", "local6", "local7", 83*7c478bd9Sstevel@tonic-gate "unknown" 84*7c478bd9Sstevel@tonic-gate }; 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate /* 87*7c478bd9Sstevel@tonic-gate * Get exclusive access to the logging system; this includes all minor 88*7c478bd9Sstevel@tonic-gate * devices. We use an rwlock rather than a mutex because hold times 89*7c478bd9Sstevel@tonic-gate * are potentially long, so we don't want to waste cycles in adaptive mutex 90*7c478bd9Sstevel@tonic-gate * spin (rwlocks always block when contended). Note that we explicitly 91*7c478bd9Sstevel@tonic-gate * support recursive calls (e.g. printf() calls foo() calls printf()). 92*7c478bd9Sstevel@tonic-gate * 93*7c478bd9Sstevel@tonic-gate * Clients may use log_enter() / log_exit() to guarantee that a group 94*7c478bd9Sstevel@tonic-gate * of messages is treated atomically (i.e. they appear in order and are 95*7c478bd9Sstevel@tonic-gate * not interspersed with any other messages), e.g. for multiline printf(). 96*7c478bd9Sstevel@tonic-gate * 97*7c478bd9Sstevel@tonic-gate * This could probably be changed to a per-zone lock if contention becomes 98*7c478bd9Sstevel@tonic-gate * an issue. 99*7c478bd9Sstevel@tonic-gate */ 100*7c478bd9Sstevel@tonic-gate void 101*7c478bd9Sstevel@tonic-gate log_enter(void) 102*7c478bd9Sstevel@tonic-gate { 103*7c478bd9Sstevel@tonic-gate if (rw_owner(&log_rwlock) != curthread) 104*7c478bd9Sstevel@tonic-gate rw_enter(&log_rwlock, RW_WRITER); 105*7c478bd9Sstevel@tonic-gate log_rwlock_depth++; 106*7c478bd9Sstevel@tonic-gate } 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate void 109*7c478bd9Sstevel@tonic-gate log_exit(void) 110*7c478bd9Sstevel@tonic-gate { 111*7c478bd9Sstevel@tonic-gate if (--log_rwlock_depth == 0) 112*7c478bd9Sstevel@tonic-gate rw_exit(&log_rwlock); 113*7c478bd9Sstevel@tonic-gate } 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate void 116*7c478bd9Sstevel@tonic-gate log_flushq(queue_t *q) 117*7c478bd9Sstevel@tonic-gate { 118*7c478bd9Sstevel@tonic-gate mblk_t *mp; 119*7c478bd9Sstevel@tonic-gate log_t *lp = (log_t *)q->q_ptr; 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate /* lp will be NULL if the queue was created via log_makeq */ 122*7c478bd9Sstevel@tonic-gate while ((mp = getq_noenab(q)) != NULL) 123*7c478bd9Sstevel@tonic-gate log_sendmsg(mp, lp == NULL ? GLOBAL_ZONEID : lp->log_zoneid); 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate /* 127*7c478bd9Sstevel@tonic-gate * Create a minimal queue with just enough fields filled in to support 128*7c478bd9Sstevel@tonic-gate * canput(9F), putq(9F), and getq_noenab(9F). We set QNOENB to ensure 129*7c478bd9Sstevel@tonic-gate * that the queue will never be enabled. 130*7c478bd9Sstevel@tonic-gate */ 131*7c478bd9Sstevel@tonic-gate static queue_t * 132*7c478bd9Sstevel@tonic-gate log_makeq(size_t lowat, size_t hiwat, void *ibc) 133*7c478bd9Sstevel@tonic-gate { 134*7c478bd9Sstevel@tonic-gate queue_t *q; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate q = kmem_zalloc(sizeof (queue_t), KM_SLEEP); 137*7c478bd9Sstevel@tonic-gate q->q_stream = &log_fakestr; 138*7c478bd9Sstevel@tonic-gate q->q_flag = QISDRV | QMTSAFE | QNOENB | QREADR | QUSE; 139*7c478bd9Sstevel@tonic-gate q->q_nfsrv = q; 140*7c478bd9Sstevel@tonic-gate q->q_lowat = lowat; 141*7c478bd9Sstevel@tonic-gate q->q_hiwat = hiwat; 142*7c478bd9Sstevel@tonic-gate mutex_init(QLOCK(q), NULL, MUTEX_DRIVER, ibc); 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate return (q); 145*7c478bd9Sstevel@tonic-gate } 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate /* 148*7c478bd9Sstevel@tonic-gate * Initialize the log structure for a new zone. 149*7c478bd9Sstevel@tonic-gate */ 150*7c478bd9Sstevel@tonic-gate static void * 151*7c478bd9Sstevel@tonic-gate log_zoneinit(zoneid_t zoneid) 152*7c478bd9Sstevel@tonic-gate { 153*7c478bd9Sstevel@tonic-gate int i; 154*7c478bd9Sstevel@tonic-gate log_zone_t *lzp; 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate if (zoneid == GLOBAL_ZONEID) 157*7c478bd9Sstevel@tonic-gate lzp = &log_global; /* use statically allocated struct */ 158*7c478bd9Sstevel@tonic-gate else 159*7c478bd9Sstevel@tonic-gate lzp = kmem_zalloc(sizeof (log_zone_t), KM_SLEEP); 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate for (i = 0; i < LOG_NUMCLONES; i++) { 162*7c478bd9Sstevel@tonic-gate lzp->lz_clones[i].log_minor = 163*7c478bd9Sstevel@tonic-gate (minor_t)id_alloc(log_minorspace); 164*7c478bd9Sstevel@tonic-gate lzp->lz_clones[i].log_zoneid = zoneid; 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate return (lzp); 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 170*7c478bd9Sstevel@tonic-gate static void 171*7c478bd9Sstevel@tonic-gate log_zonefree(zoneid_t zoneid, void *arg) 172*7c478bd9Sstevel@tonic-gate { 173*7c478bd9Sstevel@tonic-gate log_zone_t *lzp = arg; 174*7c478bd9Sstevel@tonic-gate int i; 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate ASSERT(lzp != &log_global && zoneid != GLOBAL_ZONEID); 177*7c478bd9Sstevel@tonic-gate if (lzp == NULL) 178*7c478bd9Sstevel@tonic-gate return; 179*7c478bd9Sstevel@tonic-gate for (i = 0; i < LOG_NUMCLONES; i++) 180*7c478bd9Sstevel@tonic-gate id_free(log_minorspace, lzp->lz_clones[i].log_minor); 181*7c478bd9Sstevel@tonic-gate kmem_free(lzp, sizeof (log_zone_t)); 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate void 185*7c478bd9Sstevel@tonic-gate log_init(void) 186*7c478bd9Sstevel@tonic-gate { 187*7c478bd9Sstevel@tonic-gate int log_maxzones; 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate /* 190*7c478bd9Sstevel@tonic-gate * Create a backlog queue to consume console messages during periods 191*7c478bd9Sstevel@tonic-gate * when there is no console reader (e.g. before syslogd(1M) starts). 192*7c478bd9Sstevel@tonic-gate */ 193*7c478bd9Sstevel@tonic-gate log_backlogq = log_consq = log_makeq(0, LOG_HIWAT, NULL); 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate /* 196*7c478bd9Sstevel@tonic-gate * Create a queue to hold free message of size <= LOG_MSGSIZE. 197*7c478bd9Sstevel@tonic-gate * Calls from high-level interrupt handlers will do a getq_noenab() 198*7c478bd9Sstevel@tonic-gate * from this queue, so its q_lock must be a maximum SPL spin lock. 199*7c478bd9Sstevel@tonic-gate */ 200*7c478bd9Sstevel@tonic-gate log_freeq = log_makeq(LOG_MINFREE, LOG_MAXFREE, (void *)ipltospl(SPL8)); 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate /* 203*7c478bd9Sstevel@tonic-gate * Create a queue for messages from high-level interrupt context. 204*7c478bd9Sstevel@tonic-gate * These messages are drained via softcall, or explicitly by panic(). 205*7c478bd9Sstevel@tonic-gate */ 206*7c478bd9Sstevel@tonic-gate log_intrq = log_makeq(0, LOG_HIWAT, (void *)ipltospl(SPL8)); 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate /* 209*7c478bd9Sstevel@tonic-gate * Create a queue to hold the most recent 8K of console messages. 210*7c478bd9Sstevel@tonic-gate * Useful for debugging. Required by the "$<msgbuf" adb macro. 211*7c478bd9Sstevel@tonic-gate */ 212*7c478bd9Sstevel@tonic-gate log_recentq = log_makeq(0, LOG_RECENTSIZE, NULL); 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate /* 215*7c478bd9Sstevel@tonic-gate * Create an id space for clone devices opened via /dev/log. 216*7c478bd9Sstevel@tonic-gate * Need to limit the number of zones to avoid exceeding the 217*7c478bd9Sstevel@tonic-gate * available minor number space. 218*7c478bd9Sstevel@tonic-gate */ 219*7c478bd9Sstevel@tonic-gate log_maxzones = (L_MAXMIN32 - LOG_LOGMIN) / LOG_NUMCLONES - 1; 220*7c478bd9Sstevel@tonic-gate if (log_maxzones < maxzones) 221*7c478bd9Sstevel@tonic-gate maxzones = log_maxzones; 222*7c478bd9Sstevel@tonic-gate log_minorspace = id_space_create("logminor_space", LOG_LOGMIN + 1, 223*7c478bd9Sstevel@tonic-gate L_MAXMIN32); 224*7c478bd9Sstevel@tonic-gate /* 225*7c478bd9Sstevel@tonic-gate * Put ourselves on the ZSD list. Note that zones have not been 226*7c478bd9Sstevel@tonic-gate * initialized yet, but our constructor will be called on the global 227*7c478bd9Sstevel@tonic-gate * zone when they are. 228*7c478bd9Sstevel@tonic-gate */ 229*7c478bd9Sstevel@tonic-gate zone_key_create(&log_zone_key, log_zoneinit, NULL, log_zonefree); 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate /* 232*7c478bd9Sstevel@tonic-gate * Initialize backlog structure. 233*7c478bd9Sstevel@tonic-gate */ 234*7c478bd9Sstevel@tonic-gate log_backlog.log_zoneid = GLOBAL_ZONEID; 235*7c478bd9Sstevel@tonic-gate log_backlog.log_minor = LOG_BACKLOG; 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate /* 238*7c478bd9Sstevel@tonic-gate * Initialize conslog structure. 239*7c478bd9Sstevel@tonic-gate */ 240*7c478bd9Sstevel@tonic-gate log_conslog.log_zoneid = GLOBAL_ZONEID; 241*7c478bd9Sstevel@tonic-gate log_conslog.log_minor = LOG_CONSMIN; 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate /* 244*7c478bd9Sstevel@tonic-gate * Let the logging begin. 245*7c478bd9Sstevel@tonic-gate */ 246*7c478bd9Sstevel@tonic-gate log_update(&log_backlog, log_backlogq, SL_CONSOLE, log_console); 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate /* 249*7c478bd9Sstevel@tonic-gate * Now that logging is enabled, emit the SunOS banner. 250*7c478bd9Sstevel@tonic-gate */ 251*7c478bd9Sstevel@tonic-gate printf("\rSunOS Release %s Version %s %u-bit\n", 252*7c478bd9Sstevel@tonic-gate utsname.release, utsname.version, NBBY * (uint_t)sizeof (void *)); 253*7c478bd9Sstevel@tonic-gate printf("Copyright 1983-2005 Sun Microsystems, Inc. " 254*7c478bd9Sstevel@tonic-gate "All rights reserved.\nUse is subject to license terms.\n"); 255*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 256*7c478bd9Sstevel@tonic-gate printf("DEBUG enabled\n"); 257*7c478bd9Sstevel@tonic-gate #endif 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate /* 261*7c478bd9Sstevel@tonic-gate * Allocate a log device corresponding to supplied device type. All 262*7c478bd9Sstevel@tonic-gate * processes within a given zone that open /dev/conslog share the same 263*7c478bd9Sstevel@tonic-gate * device; processes opening /dev/log get distinct devices (if 264*7c478bd9Sstevel@tonic-gate * available). 265*7c478bd9Sstevel@tonic-gate */ 266*7c478bd9Sstevel@tonic-gate log_t * 267*7c478bd9Sstevel@tonic-gate log_alloc(minor_t type) 268*7c478bd9Sstevel@tonic-gate { 269*7c478bd9Sstevel@tonic-gate zone_t *zptr = curproc->p_zone; 270*7c478bd9Sstevel@tonic-gate log_zone_t *lzp; 271*7c478bd9Sstevel@tonic-gate log_t *lp; 272*7c478bd9Sstevel@tonic-gate int i; 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate if (type == LOG_CONSMIN) { 275*7c478bd9Sstevel@tonic-gate /* return the dedicated /dev/conslog device */ 276*7c478bd9Sstevel@tonic-gate return (&log_conslog); 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate ASSERT(type == LOG_LOGMIN); 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate lzp = zone_getspecific(log_zone_key, zptr); 282*7c478bd9Sstevel@tonic-gate ASSERT(lzp != NULL); 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate /* search for an available /dev/log device for the zone */ 285*7c478bd9Sstevel@tonic-gate for (i = LOG_LOGMINIDX; i <= LOG_LOGMAXIDX; i++) { 286*7c478bd9Sstevel@tonic-gate lp = &lzp->lz_clones[i]; 287*7c478bd9Sstevel@tonic-gate if (lp->log_inuse == 0) 288*7c478bd9Sstevel@tonic-gate break; 289*7c478bd9Sstevel@tonic-gate } 290*7c478bd9Sstevel@tonic-gate if (i > LOG_LOGMAXIDX) 291*7c478bd9Sstevel@tonic-gate lp = NULL; 292*7c478bd9Sstevel@tonic-gate return (lp); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate /* 296*7c478bd9Sstevel@tonic-gate * Move console messages from src to dst. The time of day isn't known 297*7c478bd9Sstevel@tonic-gate * early in boot, so fix up the message timestamps if necessary. 298*7c478bd9Sstevel@tonic-gate */ 299*7c478bd9Sstevel@tonic-gate static void 300*7c478bd9Sstevel@tonic-gate log_conswitch(log_t *src, log_t *dst) 301*7c478bd9Sstevel@tonic-gate { 302*7c478bd9Sstevel@tonic-gate mblk_t *mp; 303*7c478bd9Sstevel@tonic-gate mblk_t *hmp = NULL; 304*7c478bd9Sstevel@tonic-gate mblk_t *tmp = NULL; 305*7c478bd9Sstevel@tonic-gate log_ctl_t *hlc; 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate while ((mp = getq_noenab(src->log_q)) != NULL) { 308*7c478bd9Sstevel@tonic-gate log_ctl_t *lc = (log_ctl_t *)mp->b_rptr; 309*7c478bd9Sstevel@tonic-gate lc->flags |= SL_LOGONLY; 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate /* 312*7c478bd9Sstevel@tonic-gate * In the early boot phase hrestime is invalid. 313*7c478bd9Sstevel@tonic-gate * hrestime becomes valid when clock() runs for the first time. 314*7c478bd9Sstevel@tonic-gate * At this time is lbolt == 1. log_sendmsg() saves the lbolt 315*7c478bd9Sstevel@tonic-gate * value in ltime. 316*7c478bd9Sstevel@tonic-gate */ 317*7c478bd9Sstevel@tonic-gate if (lc->ltime < 2) { 318*7c478bd9Sstevel@tonic-gate /* 319*7c478bd9Sstevel@tonic-gate * Look ahead to first early boot message with time. 320*7c478bd9Sstevel@tonic-gate */ 321*7c478bd9Sstevel@tonic-gate if (hmp) { 322*7c478bd9Sstevel@tonic-gate tmp->b_next = mp; 323*7c478bd9Sstevel@tonic-gate tmp = mp; 324*7c478bd9Sstevel@tonic-gate } else 325*7c478bd9Sstevel@tonic-gate hmp = tmp = mp; 326*7c478bd9Sstevel@tonic-gate continue; 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate while (hmp) { 330*7c478bd9Sstevel@tonic-gate tmp = hmp->b_next; 331*7c478bd9Sstevel@tonic-gate hmp->b_next = NULL; 332*7c478bd9Sstevel@tonic-gate hlc = (log_ctl_t *)hmp->b_rptr; 333*7c478bd9Sstevel@tonic-gate /* 334*7c478bd9Sstevel@tonic-gate * Calculate hrestime for an early log message with 335*7c478bd9Sstevel@tonic-gate * an invalid time stamp. We know: 336*7c478bd9Sstevel@tonic-gate * - the lbolt of the invalid time stamp. 337*7c478bd9Sstevel@tonic-gate * - the hrestime and lbolt of the first valid 338*7c478bd9Sstevel@tonic-gate * time stamp. 339*7c478bd9Sstevel@tonic-gate */ 340*7c478bd9Sstevel@tonic-gate hlc->ttime = lc->ttime - (lc->ltime - hlc->ltime) / hz; 341*7c478bd9Sstevel@tonic-gate (void) putq(dst->log_q, hmp); 342*7c478bd9Sstevel@tonic-gate hmp = tmp; 343*7c478bd9Sstevel@tonic-gate } 344*7c478bd9Sstevel@tonic-gate (void) putq(dst->log_q, mp); 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate while (hmp) { 347*7c478bd9Sstevel@tonic-gate tmp = hmp->b_next; 348*7c478bd9Sstevel@tonic-gate hmp->b_next = NULL; 349*7c478bd9Sstevel@tonic-gate hlc = (log_ctl_t *)hmp->b_rptr; 350*7c478bd9Sstevel@tonic-gate hlc->ttime = gethrestime_sec() - (lbolt - hlc->ltime) / hz; 351*7c478bd9Sstevel@tonic-gate (void) putq(dst->log_q, hmp); 352*7c478bd9Sstevel@tonic-gate hmp = tmp; 353*7c478bd9Sstevel@tonic-gate } 354*7c478bd9Sstevel@tonic-gate dst->log_overflow = src->log_overflow; 355*7c478bd9Sstevel@tonic-gate src->log_flags = 0; 356*7c478bd9Sstevel@tonic-gate dst->log_flags = SL_CONSOLE; 357*7c478bd9Sstevel@tonic-gate log_consq = dst->log_q; 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate /* 361*7c478bd9Sstevel@tonic-gate * Set the fields in the 'target' clone to the specified values. 362*7c478bd9Sstevel@tonic-gate * Then, look at all clones to determine which message types are 363*7c478bd9Sstevel@tonic-gate * currently active and which clone is the primary console queue. 364*7c478bd9Sstevel@tonic-gate * If the primary console queue changes to or from the backlog 365*7c478bd9Sstevel@tonic-gate * queue, copy all messages from backlog to primary or vice versa. 366*7c478bd9Sstevel@tonic-gate */ 367*7c478bd9Sstevel@tonic-gate void 368*7c478bd9Sstevel@tonic-gate log_update(log_t *target, queue_t *q, short flags, log_filter_t *filter) 369*7c478bd9Sstevel@tonic-gate { 370*7c478bd9Sstevel@tonic-gate log_t *lp; 371*7c478bd9Sstevel@tonic-gate short active = SL_CONSOLE; 372*7c478bd9Sstevel@tonic-gate zone_t *zptr = NULL; 373*7c478bd9Sstevel@tonic-gate log_zone_t *lzp; 374*7c478bd9Sstevel@tonic-gate zoneid_t zoneid = target->log_zoneid; 375*7c478bd9Sstevel@tonic-gate int i; 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate log_enter(); 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate if (q != NULL) 380*7c478bd9Sstevel@tonic-gate target->log_q = q; 381*7c478bd9Sstevel@tonic-gate target->log_wanted = filter; 382*7c478bd9Sstevel@tonic-gate target->log_flags = flags; 383*7c478bd9Sstevel@tonic-gate target->log_overflow = 0; 384*7c478bd9Sstevel@tonic-gate 385*7c478bd9Sstevel@tonic-gate /* 386*7c478bd9Sstevel@tonic-gate * Need to special case the global zone here since this may be 387*7c478bd9Sstevel@tonic-gate * called before zone_init. 388*7c478bd9Sstevel@tonic-gate */ 389*7c478bd9Sstevel@tonic-gate if (zoneid == GLOBAL_ZONEID) { 390*7c478bd9Sstevel@tonic-gate lzp = &log_global; 391*7c478bd9Sstevel@tonic-gate } else if ((zptr = zone_find_by_id(zoneid)) == NULL) { 392*7c478bd9Sstevel@tonic-gate log_exit(); 393*7c478bd9Sstevel@tonic-gate return; /* zone is being destroyed, ignore update */ 394*7c478bd9Sstevel@tonic-gate } else { 395*7c478bd9Sstevel@tonic-gate lzp = zone_getspecific(log_zone_key, zptr); 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate ASSERT(lzp != NULL); 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate for (i = LOG_LOGMAXIDX; i >= LOG_LOGMINIDX; i--) { 400*7c478bd9Sstevel@tonic-gate lp = &lzp->lz_clones[i]; 401*7c478bd9Sstevel@tonic-gate if (zoneid == GLOBAL_ZONEID && (lp->log_flags & SL_CONSOLE)) 402*7c478bd9Sstevel@tonic-gate log_consq = lp->log_q; 403*7c478bd9Sstevel@tonic-gate active |= lp->log_flags; 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate lzp->lz_active = active; 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate if (zptr) 408*7c478bd9Sstevel@tonic-gate zone_rele(zptr); 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate if (log_consq == target->log_q) { 411*7c478bd9Sstevel@tonic-gate if (flags & SL_CONSOLE) 412*7c478bd9Sstevel@tonic-gate log_conswitch(&log_backlog, target); 413*7c478bd9Sstevel@tonic-gate else 414*7c478bd9Sstevel@tonic-gate log_conswitch(target, &log_backlog); 415*7c478bd9Sstevel@tonic-gate } 416*7c478bd9Sstevel@tonic-gate target->log_q = q; 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate log_exit(); 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 422*7c478bd9Sstevel@tonic-gate int 423*7c478bd9Sstevel@tonic-gate log_error(log_t *lp, log_ctl_t *lc) 424*7c478bd9Sstevel@tonic-gate { 425*7c478bd9Sstevel@tonic-gate if ((lc->pri & LOG_FACMASK) == LOG_KERN) 426*7c478bd9Sstevel@tonic-gate lc->pri = LOG_KERN | LOG_ERR; 427*7c478bd9Sstevel@tonic-gate return (1); 428*7c478bd9Sstevel@tonic-gate } 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate int 431*7c478bd9Sstevel@tonic-gate log_trace(log_t *lp, log_ctl_t *lc) 432*7c478bd9Sstevel@tonic-gate { 433*7c478bd9Sstevel@tonic-gate trace_ids_t *tid = (trace_ids_t *)lp->log_data->b_rptr; 434*7c478bd9Sstevel@tonic-gate trace_ids_t *tidend = (trace_ids_t *)lp->log_data->b_wptr; 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate /* 437*7c478bd9Sstevel@tonic-gate * We use `tid + 1 <= tidend' here rather than the more traditional 438*7c478bd9Sstevel@tonic-gate * `tid < tidend', since the former ensures that there's at least 439*7c478bd9Sstevel@tonic-gate * `sizeof (trace_ids_t)' bytes available before executing the 440*7c478bd9Sstevel@tonic-gate * loop, whereas the latter only ensures that there's a single byte. 441*7c478bd9Sstevel@tonic-gate */ 442*7c478bd9Sstevel@tonic-gate for (; tid + 1 <= tidend; tid++) { 443*7c478bd9Sstevel@tonic-gate if (tid->ti_level < lc->level && tid->ti_level >= 0) 444*7c478bd9Sstevel@tonic-gate continue; 445*7c478bd9Sstevel@tonic-gate if (tid->ti_mid != lc->mid && tid->ti_mid >= 0) 446*7c478bd9Sstevel@tonic-gate continue; 447*7c478bd9Sstevel@tonic-gate if (tid->ti_sid != lc->sid && tid->ti_sid >= 0) 448*7c478bd9Sstevel@tonic-gate continue; 449*7c478bd9Sstevel@tonic-gate if ((lc->pri & LOG_FACMASK) == LOG_KERN) 450*7c478bd9Sstevel@tonic-gate lc->pri = LOG_KERN | LOG_DEBUG; 451*7c478bd9Sstevel@tonic-gate return (1); 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate return (0); 454*7c478bd9Sstevel@tonic-gate } 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 457*7c478bd9Sstevel@tonic-gate int 458*7c478bd9Sstevel@tonic-gate log_console(log_t *lp, log_ctl_t *lc) 459*7c478bd9Sstevel@tonic-gate { 460*7c478bd9Sstevel@tonic-gate if ((lc->pri & LOG_FACMASK) == LOG_KERN) { 461*7c478bd9Sstevel@tonic-gate if (lc->flags & SL_FATAL) 462*7c478bd9Sstevel@tonic-gate lc->pri = LOG_KERN | LOG_CRIT; 463*7c478bd9Sstevel@tonic-gate else if (lc->flags & SL_ERROR) 464*7c478bd9Sstevel@tonic-gate lc->pri = LOG_KERN | LOG_ERR; 465*7c478bd9Sstevel@tonic-gate else if (lc->flags & SL_WARN) 466*7c478bd9Sstevel@tonic-gate lc->pri = LOG_KERN | LOG_WARNING; 467*7c478bd9Sstevel@tonic-gate else if (lc->flags & SL_NOTE) 468*7c478bd9Sstevel@tonic-gate lc->pri = LOG_KERN | LOG_NOTICE; 469*7c478bd9Sstevel@tonic-gate else if (lc->flags & SL_TRACE) 470*7c478bd9Sstevel@tonic-gate lc->pri = LOG_KERN | LOG_DEBUG; 471*7c478bd9Sstevel@tonic-gate else 472*7c478bd9Sstevel@tonic-gate lc->pri = LOG_KERN | LOG_INFO; 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate return (1); 475*7c478bd9Sstevel@tonic-gate } 476*7c478bd9Sstevel@tonic-gate 477*7c478bd9Sstevel@tonic-gate mblk_t * 478*7c478bd9Sstevel@tonic-gate log_makemsg(int mid, int sid, int level, int sl, int pri, void *msg, 479*7c478bd9Sstevel@tonic-gate size_t size, int on_intr) 480*7c478bd9Sstevel@tonic-gate { 481*7c478bd9Sstevel@tonic-gate mblk_t *mp = NULL; 482*7c478bd9Sstevel@tonic-gate mblk_t *mp2; 483*7c478bd9Sstevel@tonic-gate log_ctl_t *lc; 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate if (size <= LOG_MSGSIZE && 486*7c478bd9Sstevel@tonic-gate (on_intr || log_freeq->q_count > log_freeq->q_lowat)) 487*7c478bd9Sstevel@tonic-gate mp = getq_noenab(log_freeq); 488*7c478bd9Sstevel@tonic-gate 489*7c478bd9Sstevel@tonic-gate if (mp == NULL) { 490*7c478bd9Sstevel@tonic-gate if (on_intr || 491*7c478bd9Sstevel@tonic-gate (mp = allocb(sizeof (log_ctl_t), BPRI_HI)) == NULL || 492*7c478bd9Sstevel@tonic-gate (mp2 = allocb(MAX(size, LOG_MSGSIZE), BPRI_HI)) == NULL) { 493*7c478bd9Sstevel@tonic-gate freemsg(mp); 494*7c478bd9Sstevel@tonic-gate return (NULL); 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate DB_TYPE(mp) = M_PROTO; 497*7c478bd9Sstevel@tonic-gate mp->b_wptr += sizeof (log_ctl_t); 498*7c478bd9Sstevel@tonic-gate mp->b_cont = mp2; 499*7c478bd9Sstevel@tonic-gate } else { 500*7c478bd9Sstevel@tonic-gate mp2 = mp->b_cont; 501*7c478bd9Sstevel@tonic-gate mp2->b_wptr = mp2->b_rptr; 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate 504*7c478bd9Sstevel@tonic-gate lc = (log_ctl_t *)mp->b_rptr; 505*7c478bd9Sstevel@tonic-gate lc->mid = mid; 506*7c478bd9Sstevel@tonic-gate lc->sid = sid; 507*7c478bd9Sstevel@tonic-gate lc->level = level; 508*7c478bd9Sstevel@tonic-gate lc->flags = sl; 509*7c478bd9Sstevel@tonic-gate lc->pri = pri; 510*7c478bd9Sstevel@tonic-gate 511*7c478bd9Sstevel@tonic-gate bcopy(msg, mp2->b_wptr, size - 1); 512*7c478bd9Sstevel@tonic-gate mp2->b_wptr[size - 1] = '\0'; 513*7c478bd9Sstevel@tonic-gate mp2->b_wptr += strlen((char *)mp2->b_wptr) + 1; 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate return (mp); 516*7c478bd9Sstevel@tonic-gate } 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate void 519*7c478bd9Sstevel@tonic-gate log_freemsg(mblk_t *mp) 520*7c478bd9Sstevel@tonic-gate { 521*7c478bd9Sstevel@tonic-gate mblk_t *mp2 = mp->b_cont; 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate ASSERT(MBLKL(mp) == sizeof (log_ctl_t)); 524*7c478bd9Sstevel@tonic-gate ASSERT(mp2->b_rptr == mp2->b_datap->db_base); 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate if ((log_freeq->q_flag & QFULL) == 0 && 527*7c478bd9Sstevel@tonic-gate MBLKL(mp2) <= LOG_MSGSIZE && MBLKSIZE(mp2) >= LOG_MSGSIZE) 528*7c478bd9Sstevel@tonic-gate (void) putq(log_freeq, mp); 529*7c478bd9Sstevel@tonic-gate else 530*7c478bd9Sstevel@tonic-gate freemsg(mp); 531*7c478bd9Sstevel@tonic-gate } 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate void 534*7c478bd9Sstevel@tonic-gate log_sendmsg(mblk_t *mp, zoneid_t zoneid) 535*7c478bd9Sstevel@tonic-gate { 536*7c478bd9Sstevel@tonic-gate log_t *lp; 537*7c478bd9Sstevel@tonic-gate char *src, *dst; 538*7c478bd9Sstevel@tonic-gate mblk_t *mp2 = mp->b_cont; 539*7c478bd9Sstevel@tonic-gate log_ctl_t *lc = (log_ctl_t *)mp->b_rptr; 540*7c478bd9Sstevel@tonic-gate int flags, fac; 541*7c478bd9Sstevel@tonic-gate off_t facility = 0; 542*7c478bd9Sstevel@tonic-gate off_t body = 0; 543*7c478bd9Sstevel@tonic-gate zone_t *zptr = NULL; 544*7c478bd9Sstevel@tonic-gate log_zone_t *lzp; 545*7c478bd9Sstevel@tonic-gate int i; 546*7c478bd9Sstevel@tonic-gate int backlog; 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate /* 549*7c478bd9Sstevel@tonic-gate * Need to special case the global zone here since this may be 550*7c478bd9Sstevel@tonic-gate * called before zone_init. 551*7c478bd9Sstevel@tonic-gate */ 552*7c478bd9Sstevel@tonic-gate if (zoneid == GLOBAL_ZONEID) { 553*7c478bd9Sstevel@tonic-gate lzp = &log_global; 554*7c478bd9Sstevel@tonic-gate } else if ((zptr = zone_find_by_id(zoneid)) == NULL) { 555*7c478bd9Sstevel@tonic-gate /* specified zone doesn't exist, free message and return */ 556*7c478bd9Sstevel@tonic-gate log_freemsg(mp); 557*7c478bd9Sstevel@tonic-gate return; 558*7c478bd9Sstevel@tonic-gate } else { 559*7c478bd9Sstevel@tonic-gate lzp = zone_getspecific(log_zone_key, zptr); 560*7c478bd9Sstevel@tonic-gate } 561*7c478bd9Sstevel@tonic-gate ASSERT(lzp != NULL); 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate if ((lc->flags & lzp->lz_active) == 0) { 564*7c478bd9Sstevel@tonic-gate if (zptr) 565*7c478bd9Sstevel@tonic-gate zone_rele(zptr); 566*7c478bd9Sstevel@tonic-gate log_freemsg(mp); 567*7c478bd9Sstevel@tonic-gate return; 568*7c478bd9Sstevel@tonic-gate } 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate if (panicstr) { 571*7c478bd9Sstevel@tonic-gate /* 572*7c478bd9Sstevel@tonic-gate * Raise the console queue's q_hiwat to ensure that we 573*7c478bd9Sstevel@tonic-gate * capture all panic messages. 574*7c478bd9Sstevel@tonic-gate */ 575*7c478bd9Sstevel@tonic-gate log_consq->q_hiwat = 2 * LOG_HIWAT; 576*7c478bd9Sstevel@tonic-gate log_consq->q_flag &= ~QFULL; 577*7c478bd9Sstevel@tonic-gate 578*7c478bd9Sstevel@tonic-gate /* Message was created while panicking. */ 579*7c478bd9Sstevel@tonic-gate lc->flags |= SL_PANICMSG; 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate src = (char *)mp2->b_rptr; 583*7c478bd9Sstevel@tonic-gate dst = strstr(src, "FACILITY_AND_PRIORITY] "); 584*7c478bd9Sstevel@tonic-gate if (dst != NULL) { 585*7c478bd9Sstevel@tonic-gate facility = dst - src; 586*7c478bd9Sstevel@tonic-gate body = facility + 23; /* strlen("FACILITY_AND_PRIORITY] ") */ 587*7c478bd9Sstevel@tonic-gate } 588*7c478bd9Sstevel@tonic-gate 589*7c478bd9Sstevel@tonic-gate log_enter(); 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate lc->ltime = lbolt; 592*7c478bd9Sstevel@tonic-gate lc->ttime = gethrestime_sec(); 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate flags = lc->flags & lzp->lz_active; 595*7c478bd9Sstevel@tonic-gate log_seq_no[flags & SL_ERROR]++; 596*7c478bd9Sstevel@tonic-gate log_seq_no[flags & SL_TRACE]++; 597*7c478bd9Sstevel@tonic-gate log_seq_no[flags & SL_CONSOLE]++; 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate /* 600*7c478bd9Sstevel@tonic-gate * If this is in the global zone, start with the backlog, then 601*7c478bd9Sstevel@tonic-gate * walk through the clone logs. If not, just do the clone logs. 602*7c478bd9Sstevel@tonic-gate */ 603*7c478bd9Sstevel@tonic-gate backlog = (zoneid == GLOBAL_ZONEID); 604*7c478bd9Sstevel@tonic-gate i = LOG_LOGMINIDX; 605*7c478bd9Sstevel@tonic-gate while (i <= LOG_LOGMAXIDX) { 606*7c478bd9Sstevel@tonic-gate if (backlog) { 607*7c478bd9Sstevel@tonic-gate /* 608*7c478bd9Sstevel@tonic-gate * Do the backlog this time, then start on the 609*7c478bd9Sstevel@tonic-gate * others. 610*7c478bd9Sstevel@tonic-gate */ 611*7c478bd9Sstevel@tonic-gate backlog = 0; 612*7c478bd9Sstevel@tonic-gate lp = &log_backlog; 613*7c478bd9Sstevel@tonic-gate } else { 614*7c478bd9Sstevel@tonic-gate lp = &lzp->lz_clones[i++]; 615*7c478bd9Sstevel@tonic-gate } 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate if ((lp->log_flags & flags) && lp->log_wanted(lp, lc)) { 618*7c478bd9Sstevel@tonic-gate if (canput(lp->log_q)) { 619*7c478bd9Sstevel@tonic-gate lp->log_overflow = 0; 620*7c478bd9Sstevel@tonic-gate lc->seq_no = log_seq_no[lp->log_flags]; 621*7c478bd9Sstevel@tonic-gate if ((mp2 = copymsg(mp)) == NULL) 622*7c478bd9Sstevel@tonic-gate break; 623*7c478bd9Sstevel@tonic-gate if (facility != 0) { 624*7c478bd9Sstevel@tonic-gate src = (char *)mp2->b_cont->b_rptr; 625*7c478bd9Sstevel@tonic-gate dst = src + facility; 626*7c478bd9Sstevel@tonic-gate fac = (lc->pri & LOG_FACMASK) >> 3; 627*7c478bd9Sstevel@tonic-gate dst += snprintf(dst, 628*7c478bd9Sstevel@tonic-gate LOG_FACSIZE + LOG_PRISIZE, "%s.%s", 629*7c478bd9Sstevel@tonic-gate log_fac[MIN(fac, LOG_NFACILITIES)], 630*7c478bd9Sstevel@tonic-gate log_pri[lc->pri & LOG_PRIMASK]); 631*7c478bd9Sstevel@tonic-gate src += body - 2; /* copy "] " too */ 632*7c478bd9Sstevel@tonic-gate while (*src != '\0') 633*7c478bd9Sstevel@tonic-gate *dst++ = *src++; 634*7c478bd9Sstevel@tonic-gate *dst++ = '\0'; 635*7c478bd9Sstevel@tonic-gate mp2->b_cont->b_wptr = (uchar_t *)dst; 636*7c478bd9Sstevel@tonic-gate } 637*7c478bd9Sstevel@tonic-gate (void) putq(lp->log_q, mp2); 638*7c478bd9Sstevel@tonic-gate } else if (++lp->log_overflow == 1) { 639*7c478bd9Sstevel@tonic-gate if (lp->log_q == log_consq) { 640*7c478bd9Sstevel@tonic-gate console_printf(log_overflow_msg, 641*7c478bd9Sstevel@tonic-gate lp->log_minor, 642*7c478bd9Sstevel@tonic-gate " -- is syslogd(1M) running?"); 643*7c478bd9Sstevel@tonic-gate } else { 644*7c478bd9Sstevel@tonic-gate printf(log_overflow_msg, 645*7c478bd9Sstevel@tonic-gate lp->log_minor, ""); 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate } 648*7c478bd9Sstevel@tonic-gate } 649*7c478bd9Sstevel@tonic-gate } 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate if (zptr) 652*7c478bd9Sstevel@tonic-gate zone_rele(zptr); 653*7c478bd9Sstevel@tonic-gate 654*7c478bd9Sstevel@tonic-gate if ((flags & SL_CONSOLE) && (lc->pri & LOG_FACMASK) == LOG_KERN) { 655*7c478bd9Sstevel@tonic-gate if ((mp2 == NULL || log_consq == log_backlogq || panicstr) && 656*7c478bd9Sstevel@tonic-gate (lc->flags & SL_LOGONLY) == 0) 657*7c478bd9Sstevel@tonic-gate console_printf("%s", (char *)mp->b_cont->b_rptr + body); 658*7c478bd9Sstevel@tonic-gate if ((lc->flags & SL_CONSONLY) == 0 && 659*7c478bd9Sstevel@tonic-gate (mp2 = copymsg(mp)) != NULL) { 660*7c478bd9Sstevel@tonic-gate mp2->b_cont->b_rptr += body; 661*7c478bd9Sstevel@tonic-gate if (log_recentq->q_flag & QFULL) 662*7c478bd9Sstevel@tonic-gate freemsg(getq_noenab(log_recentq)); 663*7c478bd9Sstevel@tonic-gate (void) putq(log_recentq, mp2); 664*7c478bd9Sstevel@tonic-gate } 665*7c478bd9Sstevel@tonic-gate } 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate log_freemsg(mp); 668*7c478bd9Sstevel@tonic-gate 669*7c478bd9Sstevel@tonic-gate log_exit(); 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate /* 673*7c478bd9Sstevel@tonic-gate * Print queued messages to console. 674*7c478bd9Sstevel@tonic-gate */ 675*7c478bd9Sstevel@tonic-gate void 676*7c478bd9Sstevel@tonic-gate log_printq(queue_t *qfirst) 677*7c478bd9Sstevel@tonic-gate { 678*7c478bd9Sstevel@tonic-gate mblk_t *mp; 679*7c478bd9Sstevel@tonic-gate queue_t *q, *qlast; 680*7c478bd9Sstevel@tonic-gate char *cp, *msgp; 681*7c478bd9Sstevel@tonic-gate log_ctl_t *lc; 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate /* 684*7c478bd9Sstevel@tonic-gate * Look ahead to first queued message in the stream. 685*7c478bd9Sstevel@tonic-gate */ 686*7c478bd9Sstevel@tonic-gate qlast = NULL; 687*7c478bd9Sstevel@tonic-gate do { 688*7c478bd9Sstevel@tonic-gate for (q = qfirst; q->q_next != qlast; q = q->q_next) 689*7c478bd9Sstevel@tonic-gate continue; 690*7c478bd9Sstevel@tonic-gate for (mp = q->q_first; mp != NULL; mp = mp->b_next) { 691*7c478bd9Sstevel@tonic-gate lc = (log_ctl_t *)mp->b_rptr; 692*7c478bd9Sstevel@tonic-gate /* 693*7c478bd9Sstevel@tonic-gate * Check if message is already displayed at 694*7c478bd9Sstevel@tonic-gate * /dev/console. 695*7c478bd9Sstevel@tonic-gate */ 696*7c478bd9Sstevel@tonic-gate if (lc->flags & SL_PANICMSG) 697*7c478bd9Sstevel@tonic-gate continue; 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate cp = (char *)mp->b_cont->b_rptr; 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate /* Strip off the message ID. */ 702*7c478bd9Sstevel@tonic-gate if ((msgp = strstr(cp, "[ID ")) != NULL && 703*7c478bd9Sstevel@tonic-gate (msgp = strstr(msgp, "] ")) != NULL) { 704*7c478bd9Sstevel@tonic-gate cp = msgp + 2; 705*7c478bd9Sstevel@tonic-gate } 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate /* 708*7c478bd9Sstevel@tonic-gate * Using console_printf instead of printf to avoid 709*7c478bd9Sstevel@tonic-gate * queueing messages to log_consq. 710*7c478bd9Sstevel@tonic-gate */ 711*7c478bd9Sstevel@tonic-gate console_printf("%s", cp); 712*7c478bd9Sstevel@tonic-gate } 713*7c478bd9Sstevel@tonic-gate } while ((qlast = q) != qfirst); 714*7c478bd9Sstevel@tonic-gate } 715