4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
35 #include <libdevinfo.h>
37 #define CFGA_PLUGIN_LIB
38 #include <config_admin.h>
43 static FILE *debug_fp
;
52 return (debug_fp
!= NULL
);
55 if ((ep
= getenv("SBD_DEBUG")) == NULL
)
61 if ((debug_fp
= fopen(ep
, "a")) == NULL
)
64 (void) fprintf(debug_fp
, "\nDebug started, pid=%d\n", (int)getpid());
78 (void) vfprintf(debug_fp
, fmt
, ap
);
85 "command invalid: %s",
86 "%s %s: %s%s%s", /* command failed */
87 "%s %s", /* command nacked */
88 "command not supported: %s %s",
89 "command aborted: %s %s",
91 "option requires value: %s",
92 "option requires no value: %s",
93 "option value invalid: %s %s",
94 "attachment point invalid: %s",
95 "component invalid: %s",
96 "sequence invalid: %s (%s %s) %s",
97 "change signal disposition failed",
98 "cannot get RCM handle",
99 "RCM %s failed for %s",
101 "cannot open %s%s%s",
102 "cannot find symbol %s in %s",
103 "cannot stat %s: %s",
110 #define ap_err_fmt(i) ap_err_fmts[min((uint_t)(i), ERR_NONE)]
116 "System may be temporarily suspended, proceed",
120 "RCM library not found, feature will be disabled\n",
125 #define ap_msg_fmt(i) ap_msg_fmts[min((uint_t)(i), MSG_NONE)]
127 #define STR_BD "board"
129 #define STR_NULL "NULL"
130 #define STR_CMD_UNKNOWN "unknown command"
131 #define STR_ERR_UNKNOWN "unknown error"
132 #define STR_MSG_UNKNOWN "unknown message\n"
133 #define STR_TGT_UNKNOWN "unknown target"
135 #define get_cmd(c, ap, v) \
137 (v) = va_arg((ap), int); \
138 if (((c) = ap_cmd_name((v))) == NULL) \
139 (c) = STR_CMD_UNKNOWN; \
141 #define get_tgt(t, ap) {\
142 (t) = va_arg((ap), char *); \
143 if (!str_valid((t))) \
144 (t) = STR_TGT_UNKNOWN; \
146 #define check_tgt(tgt, t) {\
147 if (str_valid((tgt))) \
150 (t) = STR_TGT_UNKNOWN; \
152 #define get_str(v, ap, d) \
154 (v) = va_arg((ap), char *); \
170 * ap_err() accepts a variable number of message IDs and constructs
171 * a corresponding error string. ap_err() calls dgettext() to
172 * internationalize the proper portions of a message. If a system
173 * error was encountered (errno set), ap_err() looks for the error
174 * string corresponding to the returned error code if one is available.
175 * If not, the standard libc error string is fetched.
178 ap_err(apd_t
*a
, ...)
202 char *rinfostr
= NULL
;
205 DBG("ap_err(%p)\n", (void *)a
);
208 * If there is no descriptor or string pointer or if
209 * there is an outstanding error, just return.
211 if (a
== NULL
|| (errstring
= a
->errstring
) == NULL
||
217 err
= va_arg(ap
, int);
219 if ((fmt
= ap_err_fmt(err
)) == NULL
)
220 fmt
= STR_ERR_UNKNOWN
;
221 fmt
= dgettext(TEXT_DOMAIN
, fmt
);
230 * Get the proper arguments for the error.
237 check_tgt(a
->target
, target
);
238 len
+= strlen(cmd
) + strlen(target
);
239 DBG("<%s><%s>", cmd
, target
);
241 case ERR_CMD_NOTSUPP
:
243 if (a
->tgt
== AP_BOARD
)
246 check_tgt(a
->cname
, target
);
247 len
+= strlen(cmd
) + strlen(target
);
248 DBG("<%s><%s>", cmd
, target
);
251 check_tgt((char *)a
->apid
, target
);
252 len
+= strlen(target
);
261 get_str(option
, ap
, STR_NULL
);
262 len
+= strlen(option
);
264 if (err
!= ERR_OPT_BADVAL
)
266 get_str(value
, ap
, STR_NULL
);
267 len
+= strlen(value
);
270 case ERR_TRANS_INVAL
: {
274 check_tgt(a
->target
, target
);
275 len
+= strlen(cmd
) + strlen(target
);
276 ap_state(a
, &rs
, &os
);
277 rstate
= ap_stnames
[rs
];
278 ostate
= ap_stnames
[os
];
279 len
+= strlen(rstate
) + strlen(ostate
);
280 DBG("<%s><%s><%s><%s>", cmd
, target
, rstate
, ostate
);
286 check_tgt(a
->target
, target
);
287 len
+= strlen(cmd
) + strlen(target
);
288 DBG("<%s><%s>", cmd
, target
);
290 if ((ap_rcm_info(a
, &rinfostr
) == 0) && (rinfostr
!= NULL
)) {
291 len
+= strlen(rinfostr
);
297 get_str(path
, ap
, STR_NULL
);
298 get_str(error
, ap
, "");
299 if (str_valid(error
))
301 DBG("<%s><%s>", path
, error
);
304 get_str(path
, ap
, STR_NULL
);
305 get_str(sym
, ap
, STR_NULL
);
306 DBG("<%s><%s>", path
, sym
);
309 get_str(path
, ap
, STR_NULL
);
312 get_str(msg
, ap
, STR_NULL
);
322 * In case of a system error, get the reason for
323 * the failure as well as the resource if availbale.
324 * If we already got some error info (e.g. from RCM)
325 * don't bother looking.
327 if (!str_valid(error
) && errno
) {
330 if ((syserr
= ap_sys_err(a
, &sysrsrc
)) == NULL
)
331 syserr
= STR_ERR_UNKNOWN
;
335 syserr
= dgettext(TEXT_DOMAIN
, syserr
);
342 len
+= strlen(syserr
) + strlen(sysrsrc
);
344 if (str_valid(sysrsrc
)) {
350 DBG("<%s><%s><%s>", syserr
, rsep
, sysrsrc
);
353 syserr
= rsep
= sysrsrc
= "";
357 if ((p
= (char *)calloc(len
, 1)) != NULL
)
361 * Print the string with appropriate arguments.
365 (void) snprintf(p
, len
, fmt
, cmd
, target
,
366 syserr
, rsep
, sysrsrc
);
370 case ERR_CMD_NOTSUPP
:
371 (void) snprintf(p
, len
, fmt
, cmd
, target
);
374 (void) snprintf(p
, len
, fmt
, target
);
381 (void) snprintf(p
, len
, fmt
, option
);
384 (void) snprintf(p
, len
, fmt
, option
, value
);
386 case ERR_TRANS_INVAL
:
387 (void) snprintf(p
, len
, fmt
, cmd
, rstate
, ostate
, target
);
391 (void) snprintf(p
, len
, fmt
);
395 * If the rinfostr has a string, then the librcm has returned
396 * us a text field of its reasons why the command failed.
398 * If the rinfostr is not returning data, we will use
399 * the standard ap_err_fmts[] for the rcm error.
401 if (rinfostr
!= NULL
)
402 (void) snprintf(p
, len
, "%s", rinfostr
);
404 (void) snprintf(p
, len
, fmt
, cmd
, target
);
407 (void) snprintf(p
, len
, fmt
, path
, sep
, error
);
410 (void) snprintf(p
, len
, fmt
, sym
, path
);
413 (void) snprintf(p
, len
, fmt
, path
, syserr
);
416 (void) snprintf(p
, len
, fmt
);
419 (void) snprintf(p
, len
, fmt
, a
->class, msg
);
430 * ap_msg() accepts a variable number of message IDs and constructs
431 * a corresponding message string which is printed via the message print
432 * routine argument. ap_msg() internationalizes the appropriate portion
436 ap_msg(apd_t
*a
, ...)
444 struct cfga_msg
*msgp
;
447 DBG("ap_msg(%p)\n", (void *)a
);
449 if (a
== NULL
|| ap_getopt(a
, OPT_VERBOSE
) == 0)
454 if (msgp
== NULL
|| msgp
->message_routine
== NULL
)
461 if ((fmt
= ap_msg_fmt(v
)) == NULL
)
462 fmt
= STR_MSG_UNKNOWN
;
463 fmt
= dgettext(TEXT_DOMAIN
, fmt
);
464 len
= strlen(fmt
) + 128; /* slop */
476 DBG("<%s><%s>\n", cmd
, target
);
477 len
+= strlen(cmd
) + strlen(target
);
485 if ((p
= (char *)calloc(len
, 1)) == NULL
)
488 (void) snprintf(p
, len
, fmt
, cmd
, target
);
490 (*msgp
->message_routine
)(msgp
->appdata_ptr
, p
);
499 struct cfga_confirm
*confp
;
506 if (confp
== NULL
|| confp
->confirm
== NULL
)
509 msg
= dgettext(TEXT_DOMAIN
, ap_msg_fmt(MSG_SUSPEND
));
511 rc
= (*confp
->confirm
)(confp
->appdata_ptr
, msg
);