CMN_ERR(9F) Kernel Functions for Drivers CMN_ERR(9F)
NAME
cmn_err, dev_err, vcmn_err, zcmn_err, vzcmn_err - display an error
message or panic the system
SYNOPSIS
#include <sys/cmn_err.h> #include <sys/ddi.h> #include <sys/sunddi.h> void cmn_err(
int level,
char *format,
...);
void dev_err(
dev_info_t *dip,
int level,
char *format,
...);
#include <sys/varargs.h> void vcmn_err(
int level,
char *format,
va_list ap);
void vdev_err(
dev_info_t *dip,
int level,
char *format,
va_list ap);
#include <sys/types.h> void zcmn_err(
zoneid_t zoneid,
int level,
char *format,
...);
void vzcmn_err(
zoneid_t zoneid,
int level,
char *format,
va_list ap);
INTERFACE LEVEL
Architecture independent level 1 (DDI/DKI).
PARAMETERS
cmn_err() level A constant indicating the severity of the error condition.
format Message to be displayed.
dev_err() The
dev_err() function works exactly like
cmn_err(), but includes an
additional argument:
dip A pointer to the device's
dev_info structure.
vcmn_err() The
vcmn_err() function takes
level and
format as described for
cmn_err(), but its third argument is different:
ap Variable argument list passed to the function.
vdev_err() The
vdev_err() function takes
dip,
level, and
format as described for
dev_err(), but its fourth argument is different:
ap Variable argument list passed to the function.
zcmn_err() The
zcmn_err() function works exactly like
cmn_err(), but includes an
additional argument:
zoneid Zone to which log messages should be directed. See
zones(7).
vzcmn_err() The
vzcmn_err() function works exactly like
vcmn_err(), but includes an
additional argument:
zoneid Zone to which log messages should be directed. See
zones(7).
DESCRIPTION
cmn_err() The
cmn_err() function displays a specified message on the console.
cmn_err() can also panic the system. When the system panics, it
attempts to save recent changes to data, display a "panic message" on
the console, attempt to write a core file, and halt system processing.
See the
CE_PANIC level below.
level is a constant indicating the severity of the error condition.
The four severity levels are:
CE_CONT Used to continue another message or to display an informative
message not associated with an error. Note that multiple
CE_CONT messages without a newline may or may not appear on
the system console or in the system log as a single line
message. A single line message may be produced by
constructing the message with
sprintf(9F) or
vsprintf(9F) before calling
cmn_err().
CE_NOTE Used to display a message preceded with
NOTICE. This message
is used to report system events that do not necessarily
require user action, but may interest the system
administrator. For example, a message saying that a sector
on a disk needs to be accessed repeatedly before it can be
accessed correctly might be noteworthy.
CE_WARN Used to display a message preceded with
WARNING. This
message is used to report system events that require
immediate attention, such as those where if an action is not
taken, the system may panic. For example, when a peripheral
device does not initialize correctly, this level should be
used.
CE_PANIC Used to display a message preceded with "
panic", and to panic
the system. Drivers should specify this level only under the
most severe conditions or when debugging a driver. A valid
use of this level is when the system cannot continue to
function. If the error is recoverable, or not essential to
continued system operation, do not panic the system.
The
format is identical to the one described in
sprintf(9F) with
additional meaning of the first character affecting where the message
will be written:
! The message goes only to the system log.
^ The message goes only to the console.
? If
level is also
CE_CONT, the message is always sent to the
system log, but is only written to the console when the system
has been booted in verbose mode. See
kernel(8). If neither
condition is met, the "
?" character has no effect and is simply
ignored.
Refer to
syslogd(8) to determine where the system log is written.
The
cmn_err() function sends log messages to the log of the global
zone.
cmn_err() appends a
\n to each
format, except when
level is
CE_CONT.
dev_err() With the exception of its first argument (
dip),
dev_err() is identical
to
cmn_err().
dip is a pointer to a device's
dev_info structure, which
is used to prepend the driver name and instance number to the message.
The driver name and instance number are retrieved using
ddi_driver_name(9F) and
ddi_get_instance(9F).
vcmn_err() The
vcmn_err() function is identical to
cmn_err() except that its last
argument,
ap, is a pointer to a variable list of arguments.
ap contains the list of arguments used by the conversion specifications in
format.
ap must be initialized by calling
va_start(9F).
va_end(9F) is
used to clean up and must be called after each traversal of the list.
Multiple traversals of the argument list, each bracketed by
va_start(9F) and
va_end(9F), are possible.
vdev_err() The
vdev_err() function is the combination of
vcmn_err() and
dev_err().
It treats its initial arguments,
dip,
level, and
format the same as
dev_err(); however, its last argument
ap is handled the same way as
vcmn_err().
zcmn_err() With the exception of its first argument (
zoneid),
zcmn_err() is
identical to
cmn_err().
zoneid is the numeric ID of the zone to which
the message should be directed. Note that
zoneid only has an effect if
the message is sent to the system log. Using
zoneid will cause
messages to be sent to the log associated with the specified local zone
rather than the log in the global zone. This is accomplished by the
message being received and processed by the
syslogd(8) process running
in the specified zone instead of the one running in the global zone.
You can retrieve a process zone ID from its credential structure using
crgetzoneid(9F).
vzcmn_err() With the exception of its first argument (
zoneid),
vzcmn_err() is
identical to
vcmn_err(). See the description of
zcmn_err() above for
an explanation on how the
zoneid argument is handled.
CONTEXT
The
cmn_err(),
dev_err(),
vcmn_err(),
vdev_err(),
zcmn_err(), and
vzcmn_err() functions can be called from user, kernel, interrupt, or
high-level interrupt context.
RETURN VALUES
None. However, if an unknown
level is passed to
cmn_err(), the
following panic error message is displayed:
panic: unknown level in cmn_err (level=level, msg=format)
EXAMPLES
Example 1 Using
cmn_err()
This first example shows how
cmn_err() can record tracing and
debugging information only in the system log (lines 17);
display problems with a device only on the system console (line
23); or display problems with the device on both the system
console and in the system log (line 28).
1 struct reg {
2 uchar_t data;
3 uchar_t csr;
4 };
5
6 struct xxstate {
7 ...
8 dev_info_t *dip;
9 struct reg *regp;
10 ...
11 };
12
13 dev_t dev;
14 struct xxstate *xsp;
15 ...
16 #ifdef DEBUG /* in debugging mode, log function call */
17 cmn_err(CE_CONT, "!%s%d: xxopen function called.",
18 ddi_binding_name(xsp->dip), getminor(dev));
19 #endif /* end DEBUG */
20 ...
21 /* display device power failure on system console */
22 if ((xsp->regp->csr & POWER) == OFF)
23 cmn_err(CE_NOTE, "^OFF.",
24 ddi_binding_name(xsp->dip), getminor(dev));
25 ...
26 /* display warning if device has bad VTOC */
27 if (xsp->regp->csr & BADVTOC)
28 cmn_err(CE_WARN, "%s%d: xxopen: Bad VTOC.",
29 ddi_binding_name(xsp->dip), getminor(dev));
Example 2 Using the %b conversion specification
This example shows how to use the
%b conversion specification.
Because of the leading "
?" character in the format string, this
message will always be logged, but it will only be displayed
when the kernel is booted in verbose mode.
cmn_err(CE_CONT, "?reg=0x%b\n", regval, "\020\3Intr\2Err\1Enable");
Example 3 Using
regval When
regval is set to (decimal) 13, the following message would
be displayed:
reg=0xd<Intr,,Enable>
Example 4 Error Routine
This example shows an error reporting routine which accepts a
variable number of arguments and displays a single line error
message both in the system log and on the system console. Note
the use of
vsprintf() to construct the error message before
calling
cmn_err().
#include <sys/varargs.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#define MAX_MSG 256;
void
xxerror(dev_info_t *dip, int level, const char *fmt, ...)
{
va_list ap;
int instance;
char buf[MAX_MSG], *name;
instance = ddi_get_instance(dip);
name = ddi_binding_name(dip);
/* format buf using fmt and arguments contained in ap */
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
/* pass formatted string to
cmn_err(9F) */
cmn_err(level, "%s%d: %s", name, instance, buf);
}
Example 5 Log to Current Zone
This example shows how messages can be sent to the log of the
zone in which a thread is currently running, when applicable.
Note that most hardware-related messages should instead be sent
to the global zone using
cmn_err().
zcmn_err(crgetzoneid(ddi_get_cred()), CE_NOTE, "out of processes");
SEE ALSO
zones(7),
dmesg(8),
kernel(8),
ddi_binding_name(9F),
ddi_cred(9F),
ddi_driver_name(9F),
ddi_get_instance(9F),
sprintf(9F),
va_arg(9F),
va_end(9F),
va_start(9F) Writing Device Drivers
WARNINGS
The
cmn_err() function with the
CE_CONT argument can be used by driver
developers as a driver code debugging tool. However, using
cmn_err()
in this capacity can change system timing characteristics.
NOTES
Messages of arbitrary length can be generated using
cmn_err(), but if
the call to
cmn_err() is made from high-level interrupt context and
insufficient memory is available to create a buffer of the specified
size, the message will be truncated to LOG_MSGSIZE bytes (see
sys/log.h). For this reason, callers of
cmn_err() that require
complete and accurate message generation should post down from high-
level interrupt context before calling
cmn_err().
illumos September 15, 2024 illumos