1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
|
.\"
.\" The contents of this file are subject to the terms of the
.\" Common Development and Distribution License (the "License").
.\" You may not use this file except in compliance with the License.
.\"
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
.\" or http://www.opensolaris.org/os/licensing.
.\" See the License for the specific language governing permissions
.\" and limitations under the License.
.\"
.\" When distributing Covered Code, include this CDDL HEADER in each
.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
.\" If applicable, add the following below this CDDL HEADER, with the
.\" fields enclosed by brackets "[]" replaced with your own identifying
.\" information: Portions Copyright [yyyy] [name of copyright owner]
.\"
.\"
.\" Copyright 1989 AT&T
.\" Copyright (c) 2006, Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright 2016 Nexenta Systems, Inc.
.\"
.Dd Dec 1, 2016
.Dt CMN_ERR 9F
.Os
.Sh NAME
.Nm cmn_err, dev_err, vcmn_err, zcmn_err, vzcmn_err
.Nd display an error message or panic the system
.Sh SYNOPSIS
.In sys/cmn_err.h
.In sys/ddi.h
.In sys/sunddi.h
.Ft void
.Fo cmn_err
.Fa "int level"
.Fa "char *format"
.Fa ...
.Fc
.Ft void
.Fo dev_err
.Fa "dev_info_t *dip"
.Fa "int level"
.Fa "char *format"
.Fa ...
.Fc
.In sys/varargs.h
.Ft void
.Fo vcmn_err
.Fa "int level"
.Fa "char *format"
.Fa "va_list ap"
.Fc
.In sys/types.h
.Ft void
.Fo zcmn_err
.Fa "zoneid_t zoneid"
.Fa "int level"
.Fa "char *format"
.Fa ...
.Fc
.Ft void
.Fo vzcmn_err
.Fa "zoneid_t zoneid"
.Fa "int level"
.Fa "char *format"
.Fa "va_list ap"
.Fc
.Sh INTERFACE LEVEL
Architecture independent level 1 (DDI/DKI).
.Sh PARAMETERS
.Ss Fn cmn_err
.Bl -tag -width Ds
.It Fa level
A constant indicating the severity of the error condition.
.It Fa format
Message to be displayed.
.El
.Ss Fn dev_err
The
.Fn dev_err
function works exactly like
.Fn cmn_err ,
but includes an additional argument:
.Bl -tag -width Ds
.It Fa dip
A pointer to the device's
.Ft dev_info
structure.
.El
.Ss Fn vcmn_err
The
.Fn vcmn_err
function takes
.Fa level
and
.Fa format
as described for
.Fn cmn_err ,
but its third argument is different:
.Bl -tag -width Ds
.It Fa ap
Variable argument list passed to the function.
.El
.Ss Fn zcmn_err
The
.Fn zcmn_err
function works exactly like
.Fn cmn_err ,
but includes an additional argument:
.Bl -tag -width Ds
.It Fa zoneid
Zone to which log messages should be directed.
See
.Xr zones 5 .
.El
.Ss Fn vzcmn_err
The
.Fn vzcmn_err
function works exactly like
.Fn vcmn_err ,
but includes an additional argument:
.Bl -tag -width Ds
.It Fa zoneid
Zone to which log messages should be directed.
See
.Xr zones 5 .
.El
.Sh DESCRIPTION
.Ss Fn cmn_err
The
.Fn cmn_err
function displays a specified message on the console.
.Fn cmn_err
can also panic the system.
When the system panics, it attempts to save recent changes to data, display a
.Qq panic message
on the console, attempt to write a core file, and halt system processing.
See the
.Sy CE_PANIC
.Fa level
below.
.Pp
.Fa level
is a constant indicating the severity of the error condition.
The four severity levels are:
.Bl -tag -width "CE_PANIC"
.It Sy CE_CONT
Used to continue another message or to display an informative message not
associated with an error.
Note that multiple
.Sy 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
.Xr sprintf 9F
or
.Xr vsprintf 9F
before calling
.Fn cmn_err .
.It Sy CE_NOTE
Used to display a message preceded with
.Sy 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.
.It Sy CE_WARN
Used to display a message preceded with
.Sy 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.
.It Sy CE_PANIC
Used to display a message preceded with
.Qq Sy 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.
.El
.Pp
The
.Fa format
is identical to the one described in
.Xr sprintf 9F
with additional meaning of the first character affecting where the message will
be written:
.Bl -tag -width Ds
.It Sy \!
The message goes only to the system log.
.It Sy ^
The message goes only to the console.
.It Sy \?
If
.Fa level
is also
.Sy 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
.Xr kernel 1M .
If neither condition is met, the
.Qq Sy \?
character has no effect and is simply ignored.
.El
.Pp
Refer to
.Xr syslogd 1M
to determine where the system log is written.
.Pp
The
.Fn cmn_err
function sends log messages to the log of the global zone.
.Fn cmn_err
appends a
.Sy \en
to each
.Fa format ,
except when
.Fa level
is
.Sy CE_CONT .
.Ss Fn dev_err
With the exception of its first argument
.Pq Fa dip ,
.Fn dev_err
is identical to
.Fn cmn_err .
.Fa dip
is a pointer to a device's
.Ft 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
.Xr ddi_driver_name 9F
and
.Xr ddi_get_instance 9F .
.Ss Fn vcmn_err
The
.Fn vcmn_err
function is identical to
.Fn cmn_err
except that its last argument,
.Fa ap ,
is a pointer to a variable list of arguments.
.Fa ap
contains the list of arguments used by the conversion specifications in
.Fa format .
.Fa ap
must be initialized by calling
.Xr va_start 9F .
.Xr 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
.Xr va_start 9F
and
.Xr va_end 9F ,
are possible.
.Ss Fn zcmn_err
With the exception of its first argument
.Pq Fa zoneid ,
.Fn zcmn_err
is identical to
.Fn cmn_err .
.Fa zoneid
is the numeric ID of the zone to which the message should be directed.
Note that
.Fa zoneid
only has an effect if the message is sent to the system log.
Using
.Fa 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
.Xr 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
.Xr crgetzoneid 9F .
.Ss Fn vzcmn_err
With the exception of its first argument
.Pq Fa zoneid ,
.Fn vzcmn_err
is identical to
.Fn vcmn_err .
See the description of
.Fn zcmn_err
above for an explanation on how the
.Fa zoneid
argument is handled.
.Sh CONTEXT
The
.Fn cmn_err
function can be called from user, kernel, interrupt, or high-level interrupt
context.
.Sh RETURN VALUES
None.
However, if an unknown
.Fa level
is passed to
.Fn cmn_err ,
the following panic error message is displayed:
.Bd -literal
panic: unknown level in cmn_err (level=level, msg=format)
.Ed
.Sh EXAMPLES
.Bl -tag -width Ds
.It Sy Example 1 No Using Fn cmn_err
This first example shows how
.Fn cmn_err
can record tracing and debugging information only in the system log
.Pq lines 17 ;
display problems with a device only on the system console
.Pq line 23 ;
or display problems with the device on both the system console and in the system
log
.Pq line 28 .
.Bd -literal
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));
.Ed
.It Sy Example 2 No Using the %b conversion specification
This example shows how to use the
.Sy %b
conversion specification.
Because of the leading
.Qq Sy \?
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.
.Bd -literal
cmn_err(CE_CONT, "?reg=0x%b\en", regval, "\e020\e3Intr\e2Err\e1Enable");
.Ed
.It Sy Example 3 No Using Fa regval
When
.Fa regval
is set to
.Pq decimal
13, the following message would be displayed:
.Bd -literal
reg=0xd<Intr,,Enable>
.Ed
.It Sy Example 4 No 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
.Fn vsprintf
to construct the error message before calling
.Fn cmn_err .
.Bd -literal
#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);
}
.Ed
.It Sy Example 5 No 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
.Fn cmn_err .
.Bd -literal
zcmn_err(crgetzoneid(ddi_get_cred()), CE_NOTE, "out of processes");
.Ed
.El
.Sh SEE ALSO
.Xr dmesg 1M ,
.Xr kernel 1M ,
.Xr zones 5 ,
.Xr ddi_binding_name 9F ,
.Xr ddi_cred 9F ,
.Xr ddi_driver_name 9F ,
.Xr ddi_get_instance 9F ,
.Xr sprintf 9F ,
.Xr va_arg 9F ,
.Xr va_end 9F ,
.Xr va_start 9F
.Pp
Writing Device Drivers
.Sh WARNINGS
The
.Fn cmn_err
function with the
.Sy CE_CONT
argument can be used by driver developers as a driver code debugging tool.
However, using
.Fn cmn_err
in this capacity can change system timing characteristics.
.Sh NOTES
Messages of arbitrary length can be generated using
.Fn cmn_err ,
but if the call to
.Fn 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
.Pq see Pa sys/log.h .
For this reason, callers of
.Fn cmn_err
that require complete and accurate message generation should post down from
high-level interrupt context before calling
.Fn cmn_err .
|