logsubr.c revision ba91f08b676cdb873326906656bad68790a01301
0N/A * The contents of this file are subject to the terms of the 0N/A * Common Development and Distribution License (the "License"). 0N/A * You may not use this file except in compliance with the License. 0N/A * See the License for the specific language governing permissions 0N/A * and limitations under the License. 0N/A * When distributing Covered Code, include this CDDL HEADER in each 0N/A * If applicable, add the following below this CDDL HEADER, with the 0N/A * fields enclosed by brackets "[]" replaced with your own identifying 0N/A * information: Portions Copyright [yyyy] [name of copyright owner] 0N/A * Copyright (c) 2013 Gary Mills 0N/A * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A "emerg",
"alert",
"crit",
"error",
0N/A "warning",
"notice",
"info",
"debug" 0N/A "kern",
"user",
"mail",
"daemon",
0N/A "auth",
"syslog",
"lpr",
"news",
0N/A "uucp",
"altcron",
"authpriv",
"ftp",
0N/A "ntp",
"audit",
"console",
"cron",
0N/A "local0",
"local1",
"local2",
"local3",
0N/A "local4",
"local5",
"local6",
"local7",
196N/A * Get exclusive access to the logging system; this includes all minor 196N/A * devices. We use an rwlock rather than a mutex because hold times 0N/A * are potentially long, so we don't want to waste cycles in adaptive mutex 0N/A * spin (rwlocks always block when contended). Note that we explicitly 0N/A * support recursive calls (e.g. printf() calls foo() calls printf()). 190N/A * Clients may use log_enter() / log_exit() to guarantee that a group 98N/A * of messages is treated atomically (i.e. they appear in order and are 235N/A * not interspersed with any other messages), e.g. for multiline printf(). 98N/A * This could probably be changed to a per-zone lock if contention becomes 0N/A /* lp will be NULL if the queue was created via log_makeq */ 0N/A * Create a minimal queue with just enough fields filled in to support 0N/A * canput(9F), putq(9F), and getq_noenab(9F). We set QNOENB to ensure 0N/A * that the queue will never be enabled. 0N/A * Initialize the log structure for a new zone. 355N/A * Create a backlog queue to consume console messages during periods 355N/A * when there is no console reader (e.g. before syslogd(1M) starts). 368N/A * Create a queue to hold free message of size <= LOG_MSGSIZE. 368N/A * Calls from high-level interrupt handlers will do a getq_noenab() 0N/A * from this queue, so its q_lock must be a maximum SPL spin lock. 0N/A * Create a queue for messages from high-level interrupt context. 0N/A * These messages are drained via softcall, or explicitly by panic(). 0N/A * Create a queue to hold the most recent 8K of console messages. 0N/A * Useful for debugging. Required by the "$<msgbuf" adb macro. 0N/A * Create an id space for clone devices opened via /dev/log. 0N/A * Need to limit the number of zones to avoid exceeding the 0N/A * available minor number space. 0N/A * Put ourselves on the ZSD list. Note that zones have not been 0N/A * initialized yet, but our constructor will be called on the global 0N/A * zone when they are. 0N/A * Initialize backlog structure. 0N/A /* Allocate kmem cache for conslog's log structures */ 0N/A * Let the logging begin. 0N/A * Now that logging is enabled, emit the SunOS banner. 0N/A printf(
"\rSunOS Release %s Version %s %u-bit\n",
0N/A "All rights reserved.\n");
29N/A * Allocate a log device corresponding to supplied device type. 0N/A * Both devices are clonable. /dev/log devices are allocated per zone. * No point allocating log_t until there's a free minor number. /* search for an available /dev/log device for the zone */ /* Indicate which device type */ * Move console messages from src to dst. The time of day isn't known * early in boot, so fix up the message timestamps if necessary. * The ttime is written with 0 in log_sensmsg() only when * good gethrestime_sec() data is not available to store in * the log_ctl_t in the early boot phase. * Look ahead to first early boot message with time. * Calculate hrestime for an early log message with * an invalid time stamp. We know: * - the lbolt of the invalid time stamp. * - the hrestime and lbolt of the first valid * Set the fields in the 'target' clone to the specified values. * Then, look at all clones to determine which message types are * currently active and which clone is the primary console queue. * If the primary console queue changes to or from the backlog * queue, copy all messages from backlog to primary or vice versa. * Need to special case the global zone here since this may be * called before zone_init. return;
/* zone is being destroyed, ignore update */ * We use `tid + 1 <= tidend' here rather than the more traditional * `tid < tidend', since the former ensures that there's at least * `sizeof (trace_ids_t)' bytes available before executing the * loop, whereas the latter only ensures that there's a single byte. * Need to special case the global zone here since this may be * called before zone_init. /* specified zone doesn't exist, free message and return */ * Raise the console queue's q_hiwat to ensure that we * capture all panic messages. /* Message was created while panicking. */ body =
facility +
23;
/* strlen("FACILITY_AND_PRIORITY] ") */ * In the early boot phase hrestime is invalid, then timechanged is 0. * If hrestime is not valid, the ttime is set to 0 here and the correct * ttime is calculated in log_conswitch() later. The log_conswitch() * calculation to determine the correct ttime does not use ttime data * from these log_ctl_t structures; it only uses ttime from log_ctl_t's * that contain good data. * If this is in the global zone, start with the backlog, then * walk through the clone logs. If not, just do the clone logs. * Do the backlog this time, then start on the src +=
body -
2;
/* copy "] " too */ " -- is syslogd(1M) running?");
* Print queued messages to console. * Look ahead to first queued message in the stream. * Check if message is already displayed at /* Strip off the message ID. */ * Using console_printf instead of printf to avoid * queueing messages to log_consq.