| CMN_ERR(9F) | Kernel Functions for Drivers | CMN_ERR(9F) | 
cmn_err, dev_err, vcmn_err, zcmn_err,
    vzcmn_err — display an error message or panic
    the system
#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);
Architecture independent level 1 (DDI/DKI).
cmn_err()dev_err()The dev_err() function works exactly like
    cmn_err(), but includes an additional argument:
vcmn_err()The vcmn_err() function takes
    level and format as described
    for cmn_err(), but its third argument is
  different:
vdev_err()The vdev_err() function takes
    dip, level, and
    format as described for
    dev_err(), but its fourth argument is different:
zcmn_err()The zcmn_err() function works exactly like
    cmn_err(), but includes an additional argument:
vzcmn_err()The vzcmn_err() function works exactly
    like vcmn_err(), but includes an additional
    argument:
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:
cmn_err().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:
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.
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.
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)
cmn_err()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));
    cmn_err(CE_CONT, "?reg=0x%b\n", regval, "\020\3Intr\2Err\1Enable");
reg=0xd<Intr,,Enable>
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);
}
    cmn_err().
    zcmn_err(crgetzoneid(ddi_get_cred()), CE_NOTE, "out of processes");
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
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.
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().
| September 15, 2024 | OmniOS |