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