cmn_err, vcmn_err, zcmn_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...
#include <sys/varargs.h> void vcmn_err(int level, char *format, va_list ap);
#include <sys/types.h> void zcmn_err(zoneid_t zoneid, int level, char *format...);
Architecture independent level 1 (DDI/DKI).
level
format
The vcmn_err() function takes level and format as described for cmn_err(), but its third argument is different:
ap
The zcmn_err() function works exactly like cmn_err(), but includes an additional argument:
zoneid
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
CE_NOTE
CE_WARN
CE_PANIC
format is the message to be displayed. It is a character string which may contain plain characters and conversion specifications. By default, the message is sent both to the system console and to the system log.
Each conversion specification in format is introduced by the % character, after which the following appear in sequence:
An optional decimal digit specifying a minimum field width for numeric conversion. The converted value will be right-justified and padded with leading zeroes if it has fewer characters than the minimum.
An optional l (ll) specifying that a following d, D, o, O, x, X, or u conversion character applies to a long (long long) integer argument. An l (ll) before any other conversion character is ignored.
A character indicating the type of conversion to be applied:
d,D,o,O,x,X,u
c
b
p
s
%
The first character in format affects where the message will be written:
!
^
?
Refer to syslogd(1M) 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.
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.
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(1M) 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).
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)
The cmn_err() function can be called from user, kernel, interrupt, or high-level interrupt context.
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 processes0);
dmesg(1M), kernel(1M), printf(3C), zones(5), ddi_binding_name(9F), ddi_cred(9F), sprintf(9F), va_arg(9F), va_end(9F), va_start(9F), vsprintf(9F)
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().
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |