This source file includes following definitions.
- G_DEFINE_QUARK
- pcmk__result_bounds
- log_assertion_as
- pcmk__abort_as
- fail_assert_as
- crm_abort
- pcmk_errorname
- pcmk_strerror
- pcmk_rc_name
- pcmk_rc_str
- pcmk_rc2legacy
- pcmk_legacy2rc
- crm_exit_name
- crm_exit_str
- pcmk_rc2exitc
- pcmk_rc2ocf
- pcmk__gaierror2rc
- pcmk__bzlib2rc
- crm_exit
- pcmk__set_result
- G_GNUC_PRINTF
- pcmk__set_result_output
- pcmk__reset_result
- pcmk__copy_result
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <bzlib.h>
13 #include <errno.h>
14 #include <netdb.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <sys/types.h>
18 #include <sys/wait.h>
19 #include <qb/qbdefs.h>
20
21 #include <crm/common/mainloop.h>
22 #include <crm/common/xml.h>
23
24 G_DEFINE_QUARK(pcmk-rc-error-quark, pcmk__rc_error)
25 G_DEFINE_QUARK(pcmk-exitc-error-quark, pcmk__exitc_error)
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 int
42 pcmk_result_get_strings(int code, enum pcmk_result_type type, const char **name,
43 const char **desc)
44 {
45 const char *code_name = NULL;
46 const char *code_desc = NULL;
47
48 switch (type) {
49 case pcmk_result_legacy:
50 code_name = pcmk_errorname(code);
51 code_desc = pcmk_strerror(code);
52 break;
53 case pcmk_result_rc:
54 code_name = pcmk_rc_name(code);
55 code_desc = pcmk_rc_str(code);
56 break;
57 case pcmk_result_exitcode:
58 code_name = crm_exit_name(code);
59 code_desc = crm_exit_str((crm_exit_t) code);
60 break;
61 default:
62 return pcmk_rc_undetermined;
63 }
64
65 if (name != NULL) {
66 *name = code_name;
67 }
68
69 if (desc != NULL) {
70 *desc = code_desc;
71 }
72 return pcmk_rc_ok;
73 }
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 int
92 pcmk__result_bounds(enum pcmk_result_type type, int *lower, int *upper)
93 {
94 pcmk__assert((lower != NULL) && (upper != NULL));
95
96 switch (type) {
97 case pcmk_result_legacy:
98 *lower = pcmk_ok;
99 *upper = 256;
100 break;
101 case pcmk_result_rc:
102 *lower = pcmk_rc_error - pcmk__n_rc + 1;
103 *upper = 256;
104 break;
105 case pcmk_result_exitcode:
106 *lower = CRM_EX_OK;
107 *upper = CRM_EX_MAX;
108 break;
109 default:
110 *lower = 0;
111 *upper = -1;
112 return pcmk_rc_undetermined;
113 }
114 return pcmk_rc_ok;
115 }
116
117
118
119
120
121
122
123
124
125
126 static void
127 log_assertion_as(const char *file, const char *function, int line,
128 const char *assert_condition)
129 {
130 if (!pcmk__is_daemon) {
131 crm_enable_stderr(TRUE);
132 }
133 crm_err("%s: Triggered fatal assertion at %s:%d : %s",
134 function, file, line, assert_condition);
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148
149 _Noreturn void
150 pcmk__abort_as(const char *file, const char *function, int line,
151 const char *assert_condition)
152 {
153 log_assertion_as(file, function, line, assert_condition);
154 abort();
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 static void
171 fail_assert_as(const char *file, const char *function, int line,
172 const char *assert_condition)
173 {
174 int status = 0;
175 pid_t pid = 0;
176
177 if (!pcmk__is_daemon) {
178 pcmk__abort_as(file, function, line, assert_condition);
179 }
180
181 pid = fork();
182 switch (pid) {
183 case -1:
184 crm_warn("%s: Cannot dump core for non-fatal assertion at %s:%d "
185 ": %s", function, file, line, assert_condition);
186 break;
187
188 case 0:
189 abort();
190 break;
191
192 default:
193 crm_err("%s: Forked child [%d] to record non-fatal assertion at "
194 "%s:%d : %s", function, pid, file, line, assert_condition);
195 crm_write_blackbox(SIGTRAP, NULL);
196 do {
197 if (waitpid(pid, &status, 0) == pid) {
198 return;
199 }
200 } while (errno == EINTR);
201 if (errno == ECHILD) {
202
203 crm_trace("Cannot wait on forked child [%d] "
204 "(SIGCHLD is probably ignored)", pid);
205 } else {
206 crm_err("Cannot wait on forked child [%d]: %s",
207 pid, pcmk_rc_str(errno));
208 }
209 break;
210 }
211 }
212
213
214 void
215 crm_abort(const char *file, const char *function, int line,
216 const char *assert_condition, gboolean do_core, gboolean do_fork)
217 {
218 if (!do_fork) {
219 pcmk__abort_as(file, function, line, assert_condition);
220 } else if (do_core) {
221 fail_assert_as(file, function, line, assert_condition);
222 } else {
223 log_assertion_as(file, function, line, assert_condition);
224 }
225 }
226
227
228
229
230 const char *
231 pcmk_errorname(int rc)
232 {
233 rc = abs(rc);
234 switch (rc) {
235 case pcmk_err_generic: return "pcmk_err_generic";
236 case pcmk_err_no_quorum: return "pcmk_err_no_quorum";
237 case pcmk_err_schema_validation: return "pcmk_err_schema_validation";
238 case pcmk_err_transform_failed: return "pcmk_err_transform_failed";
239 case pcmk_err_old_data: return "pcmk_err_old_data";
240 case pcmk_err_diff_failed: return "pcmk_err_diff_failed";
241 case pcmk_err_diff_resync: return "pcmk_err_diff_resync";
242 case pcmk_err_cib_modified: return "pcmk_err_cib_modified";
243 case pcmk_err_cib_backup: return "pcmk_err_cib_backup";
244 case pcmk_err_cib_save: return "pcmk_err_cib_save";
245 case pcmk_err_cib_corrupt: return "pcmk_err_cib_corrupt";
246 case pcmk_err_multiple: return "pcmk_err_multiple";
247 case pcmk_err_node_unknown: return "pcmk_err_node_unknown";
248 case pcmk_err_already: return "pcmk_err_already";
249 case pcmk_err_bad_nvpair: return "pcmk_err_bad_nvpair";
250 case pcmk_err_unknown_format: return "pcmk_err_unknown_format";
251 default: return pcmk_rc_name(rc);
252 }
253 }
254
255
256 const char *
257 pcmk_strerror(int rc)
258 {
259 return pcmk_rc_str(pcmk_legacy2rc(rc));
260 }
261
262
263
264
265
266
267
268 static const struct pcmk__rc_info {
269 const char *name;
270 const char *desc;
271 int legacy_rc;
272 } pcmk__rcs[] = {
273 { "pcmk_rc_error",
274 "Error",
275 -pcmk_err_generic,
276 },
277 { "pcmk_rc_unknown_format",
278 "Unknown output format",
279 -pcmk_err_unknown_format,
280 },
281 { "pcmk_rc_bad_nvpair",
282 "Bad name/value pair given",
283 -pcmk_err_bad_nvpair,
284 },
285 { "pcmk_rc_already",
286 "Already in requested state",
287 -pcmk_err_already,
288 },
289 { "pcmk_rc_node_unknown",
290 "Node not found",
291 -pcmk_err_node_unknown,
292 },
293 { "pcmk_rc_multiple",
294 "Resource active on multiple nodes",
295 -pcmk_err_multiple,
296 },
297 { "pcmk_rc_cib_corrupt",
298 "Could not parse on-disk configuration",
299 -pcmk_err_cib_corrupt,
300 },
301 { "pcmk_rc_cib_save",
302 "Could not save new configuration to disk",
303 -pcmk_err_cib_save,
304 },
305 { "pcmk_rc_cib_backup",
306 "Could not archive previous configuration",
307 -pcmk_err_cib_backup,
308 },
309 { "pcmk_rc_cib_modified",
310 "On-disk configuration was manually modified",
311 -pcmk_err_cib_modified,
312 },
313 { "pcmk_rc_diff_resync",
314 "Application of update diff failed, requesting full refresh",
315 -pcmk_err_diff_resync,
316 },
317 { "pcmk_rc_diff_failed",
318 "Application of update diff failed",
319 -pcmk_err_diff_failed,
320 },
321 { "pcmk_rc_old_data",
322 "Update was older than existing configuration",
323 -pcmk_err_old_data,
324 },
325 { "pcmk_rc_transform_failed",
326 "Schema transform failed",
327 -pcmk_err_transform_failed,
328 },
329 { "pcmk_rc_schema_unchanged",
330 "Schema is already the latest available",
331 -pcmk_err_schema_unchanged,
332 },
333 { "pcmk_rc_schema_validation",
334 "Update does not conform to the configured schema",
335 -pcmk_err_schema_validation,
336 },
337 { "pcmk_rc_no_quorum",
338 "Operation requires quorum",
339 -pcmk_err_no_quorum,
340 },
341 { "pcmk_rc_ipc_unauthorized",
342 "IPC server is blocked by unauthorized process",
343 -pcmk_err_generic,
344 },
345 { "pcmk_rc_ipc_unresponsive",
346 "IPC server is unresponsive",
347 -pcmk_err_generic,
348 },
349 { "pcmk_rc_ipc_pid_only",
350 "IPC server process is active but not accepting connections",
351 -pcmk_err_generic,
352 },
353 { "pcmk_rc_op_unsatisfied",
354 "Not applicable under current conditions",
355 -pcmk_err_generic,
356 },
357 { "pcmk_rc_undetermined",
358 "Result undetermined",
359 -pcmk_err_generic,
360 },
361 { "pcmk_rc_before_range",
362 "Result occurs before given range",
363 -pcmk_err_generic,
364 },
365 { "pcmk_rc_within_range",
366 "Result occurs within given range",
367 -pcmk_err_generic,
368 },
369 { "pcmk_rc_after_range",
370 "Result occurs after given range",
371 -pcmk_err_generic,
372 },
373 { "pcmk_rc_no_output",
374 "Output message produced no output",
375 -pcmk_err_generic,
376 },
377 { "pcmk_rc_no_input",
378 "Input file not available",
379 -pcmk_err_generic,
380 },
381 { "pcmk_rc_underflow",
382 "Value too small to be stored in data type",
383 -pcmk_err_generic,
384 },
385 { "pcmk_rc_dot_error",
386 "Error writing dot(1) file",
387 -pcmk_err_generic,
388 },
389 { "pcmk_rc_graph_error",
390 "Error writing graph file",
391 -pcmk_err_generic,
392 },
393 { "pcmk_rc_invalid_transition",
394 "Cluster simulation produced invalid transition",
395 -pcmk_err_generic,
396 },
397 { "pcmk_rc_unpack_error",
398 "Unable to parse CIB XML",
399 -pcmk_err_generic,
400 },
401 { "pcmk_rc_duplicate_id",
402 "Two or more XML elements have the same ID",
403 -pcmk_err_generic,
404 },
405 { "pcmk_rc_disabled",
406 "Disabled",
407 -pcmk_err_generic,
408 },
409 { "pcmk_rc_bad_input",
410 "Bad input value provided",
411 -pcmk_err_generic,
412 },
413 { "pcmk_rc_bad_xml_patch",
414 "Bad XML patch format",
415 -pcmk_err_generic,
416 },
417 { "pcmk_rc_no_transaction",
418 "No active transaction found",
419 -pcmk_err_generic,
420 },
421 { "pcmk_rc_ns_resolution",
422 "Nameserver resolution error",
423 -pcmk_err_generic,
424 },
425 { "pcmk_rc_compression",
426 "Compression/decompression error",
427 -pcmk_err_generic,
428 },
429 };
430
431
432
433
434
435
436
437
438
439 const size_t pcmk__n_rc = PCMK__NELEM(pcmk__rcs);
440
441
442
443
444
445
446
447
448 const char *
449 pcmk_rc_name(int rc)
450 {
451 if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
452 return pcmk__rcs[pcmk_rc_error - rc].name;
453 }
454 switch (rc) {
455 case pcmk_rc_ok: return "pcmk_rc_ok";
456 case E2BIG: return "E2BIG";
457 case EACCES: return "EACCES";
458 case EADDRINUSE: return "EADDRINUSE";
459 case EADDRNOTAVAIL: return "EADDRNOTAVAIL";
460 case EAFNOSUPPORT: return "EAFNOSUPPORT";
461 case EAGAIN: return "EAGAIN";
462 case EALREADY: return "EALREADY";
463 case EBADF: return "EBADF";
464 case EBADMSG: return "EBADMSG";
465 case EBUSY: return "EBUSY";
466 case ECANCELED: return "ECANCELED";
467 case ECHILD: return "ECHILD";
468 case ECOMM: return "ECOMM";
469 case ECONNABORTED: return "ECONNABORTED";
470 case ECONNREFUSED: return "ECONNREFUSED";
471 case ECONNRESET: return "ECONNRESET";
472
473 case EDESTADDRREQ: return "EDESTADDRREQ";
474 case EDOM: return "EDOM";
475 case EDQUOT: return "EDQUOT";
476 case EEXIST: return "EEXIST";
477 case EFAULT: return "EFAULT";
478 case EFBIG: return "EFBIG";
479 case EHOSTDOWN: return "EHOSTDOWN";
480 case EHOSTUNREACH: return "EHOSTUNREACH";
481 case EIDRM: return "EIDRM";
482 case EILSEQ: return "EILSEQ";
483 case EINPROGRESS: return "EINPROGRESS";
484 case EINTR: return "EINTR";
485 case EINVAL: return "EINVAL";
486 case EIO: return "EIO";
487 case EISCONN: return "EISCONN";
488 case EISDIR: return "EISDIR";
489 case ELIBACC: return "ELIBACC";
490 case ELOOP: return "ELOOP";
491 case EMFILE: return "EMFILE";
492 case EMLINK: return "EMLINK";
493 case EMSGSIZE: return "EMSGSIZE";
494 #ifdef EMULTIHOP
495 case EMULTIHOP: return "EMULTIHOP";
496 #endif
497 case ENAMETOOLONG: return "ENAMETOOLONG";
498 case ENETDOWN: return "ENETDOWN";
499 case ENETRESET: return "ENETRESET";
500 case ENETUNREACH: return "ENETUNREACH";
501 case ENFILE: return "ENFILE";
502 case ENOBUFS: return "ENOBUFS";
503 case ENODATA: return "ENODATA";
504 case ENODEV: return "ENODEV";
505 case ENOENT: return "ENOENT";
506 case ENOEXEC: return "ENOEXEC";
507 case ENOKEY: return "ENOKEY";
508 case ENOLCK: return "ENOLCK";
509 #ifdef ENOLINK
510 case ENOLINK: return "ENOLINK";
511 #endif
512 case ENOMEM: return "ENOMEM";
513 case ENOMSG: return "ENOMSG";
514 case ENOPROTOOPT: return "ENOPROTOOPT";
515 case ENOSPC: return "ENOSPC";
516 #ifdef ENOSR
517 case ENOSR: return "ENOSR";
518 #endif
519 #ifdef ENOSTR
520 case ENOSTR: return "ENOSTR";
521 #endif
522 case ENOSYS: return "ENOSYS";
523 case ENOTBLK: return "ENOTBLK";
524 case ENOTCONN: return "ENOTCONN";
525 case ENOTDIR: return "ENOTDIR";
526 case ENOTEMPTY: return "ENOTEMPTY";
527 case ENOTSOCK: return "ENOTSOCK";
528 #if ENOTSUP != EOPNOTSUPP
529 case ENOTSUP: return "ENOTSUP";
530 #endif
531 case ENOTTY: return "ENOTTY";
532 case ENOTUNIQ: return "ENOTUNIQ";
533 case ENXIO: return "ENXIO";
534 case EOPNOTSUPP: return "EOPNOTSUPP";
535 case EOVERFLOW: return "EOVERFLOW";
536 case EPERM: return "EPERM";
537 case EPFNOSUPPORT: return "EPFNOSUPPORT";
538 case EPIPE: return "EPIPE";
539 case EPROTO: return "EPROTO";
540 case EPROTONOSUPPORT: return "EPROTONOSUPPORT";
541 case EPROTOTYPE: return "EPROTOTYPE";
542 case ERANGE: return "ERANGE";
543 case EREMOTE: return "EREMOTE";
544 case EREMOTEIO: return "EREMOTEIO";
545 case EROFS: return "EROFS";
546 case ESHUTDOWN: return "ESHUTDOWN";
547 case ESPIPE: return "ESPIPE";
548 case ESOCKTNOSUPPORT: return "ESOCKTNOSUPPORT";
549 case ESRCH: return "ESRCH";
550 case ESTALE: return "ESTALE";
551 case ETIME: return "ETIME";
552 case ETIMEDOUT: return "ETIMEDOUT";
553 case ETXTBSY: return "ETXTBSY";
554 #ifdef EUNATCH
555 case EUNATCH: return "EUNATCH";
556 #endif
557 case EUSERS: return "EUSERS";
558
559 case EXDEV: return "EXDEV";
560
561 #ifdef EBADE
562 case EBADE: return "EBADE";
563 case EBADFD: return "EBADFD";
564 case EBADSLT: return "EBADSLT";
565 case EDEADLOCK: return "EDEADLOCK";
566 case EBADR: return "EBADR";
567 case EBADRQC: return "EBADRQC";
568 case ECHRNG: return "ECHRNG";
569 #ifdef EISNAM
570 case EISNAM: return "EISNAM";
571 case EKEYEXPIRED: return "EKEYEXPIRED";
572 case EKEYREVOKED: return "EKEYREVOKED";
573 #endif
574 case EKEYREJECTED: return "EKEYREJECTED";
575 case EL2HLT: return "EL2HLT";
576 case EL2NSYNC: return "EL2NSYNC";
577 case EL3HLT: return "EL3HLT";
578 case EL3RST: return "EL3RST";
579 case ELIBBAD: return "ELIBBAD";
580 case ELIBMAX: return "ELIBMAX";
581 case ELIBSCN: return "ELIBSCN";
582 case ELIBEXEC: return "ELIBEXEC";
583 #ifdef ENOMEDIUM
584 case ENOMEDIUM: return "ENOMEDIUM";
585 case EMEDIUMTYPE: return "EMEDIUMTYPE";
586 #endif
587 case ENONET: return "ENONET";
588 case ENOPKG: return "ENOPKG";
589 case EREMCHG: return "EREMCHG";
590 case ERESTART: return "ERESTART";
591 case ESTRPIPE: return "ESTRPIPE";
592 #ifdef EUCLEAN
593 case EUCLEAN: return "EUCLEAN";
594 #endif
595 case EXFULL: return "EXFULL";
596 #endif
597 default: return "Unknown";
598 }
599 }
600
601
602
603
604
605
606
607
608 const char *
609 pcmk_rc_str(int rc)
610 {
611 if (rc == pcmk_rc_ok) {
612 return "OK";
613 }
614 if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
615 return pcmk__rcs[pcmk_rc_error - rc].desc;
616 }
617 if (rc < 0) {
618 return "Error";
619 }
620
621
622 switch (rc) {
623 #ifdef PCMK__ENOTUNIQ
624 case ENOTUNIQ: return "Name not unique on network";
625 #endif
626 #ifdef PCMK__ECOMM
627 case ECOMM: return "Communication error on send";
628 #endif
629 #ifdef PCMK__ELIBACC
630 case ELIBACC: return "Can not access a needed shared library";
631 #endif
632 #ifdef PCMK__EREMOTEIO
633 case EREMOTEIO: return "Remote I/O error";
634 #endif
635 #ifdef PCMK__ENOKEY
636 case ENOKEY: return "Required key not available";
637 #endif
638 #ifdef PCMK__ENODATA
639 case ENODATA: return "No data available";
640 #endif
641 #ifdef PCMK__ETIME
642 case ETIME: return "Timer expired";
643 #endif
644 #ifdef PCMK__EKEYREJECTED
645 case EKEYREJECTED: return "Key was rejected by service";
646 #endif
647 default: return strerror(rc);
648 }
649 }
650
651
652
653 int
654 pcmk_rc2legacy(int rc)
655 {
656 if (rc >= 0) {
657 return -rc;
658 }
659 if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
660 return pcmk__rcs[pcmk_rc_error - rc].legacy_rc;
661 }
662 return -pcmk_err_generic;
663 }
664
665
666 int
667 pcmk_legacy2rc(int legacy_rc)
668 {
669 legacy_rc = abs(legacy_rc);
670 switch (legacy_rc) {
671 case pcmk_err_no_quorum: return pcmk_rc_no_quorum;
672 case pcmk_err_schema_validation: return pcmk_rc_schema_validation;
673 case pcmk_err_schema_unchanged: return pcmk_rc_schema_unchanged;
674 case pcmk_err_transform_failed: return pcmk_rc_transform_failed;
675 case pcmk_err_old_data: return pcmk_rc_old_data;
676 case pcmk_err_diff_failed: return pcmk_rc_diff_failed;
677 case pcmk_err_diff_resync: return pcmk_rc_diff_resync;
678 case pcmk_err_cib_modified: return pcmk_rc_cib_modified;
679 case pcmk_err_cib_backup: return pcmk_rc_cib_backup;
680 case pcmk_err_cib_save: return pcmk_rc_cib_save;
681 case pcmk_err_cib_corrupt: return pcmk_rc_cib_corrupt;
682 case pcmk_err_multiple: return pcmk_rc_multiple;
683 case pcmk_err_node_unknown: return pcmk_rc_node_unknown;
684 case pcmk_err_already: return pcmk_rc_already;
685 case pcmk_err_bad_nvpair: return pcmk_rc_bad_nvpair;
686 case pcmk_err_unknown_format: return pcmk_rc_unknown_format;
687 case pcmk_err_generic: return pcmk_rc_error;
688 case pcmk_ok: return pcmk_rc_ok;
689 default: return legacy_rc;
690 }
691 }
692
693
694
695 const char *
696 crm_exit_name(crm_exit_t exit_code)
697 {
698 switch (exit_code) {
699 case CRM_EX_OK: return "CRM_EX_OK";
700 case CRM_EX_ERROR: return "CRM_EX_ERROR";
701 case CRM_EX_INVALID_PARAM: return "CRM_EX_INVALID_PARAM";
702 case CRM_EX_UNIMPLEMENT_FEATURE: return "CRM_EX_UNIMPLEMENT_FEATURE";
703 case CRM_EX_INSUFFICIENT_PRIV: return "CRM_EX_INSUFFICIENT_PRIV";
704 case CRM_EX_NOT_INSTALLED: return "CRM_EX_NOT_INSTALLED";
705 case CRM_EX_NOT_CONFIGURED: return "CRM_EX_NOT_CONFIGURED";
706 case CRM_EX_NOT_RUNNING: return "CRM_EX_NOT_RUNNING";
707 case CRM_EX_PROMOTED: return "CRM_EX_PROMOTED";
708 case CRM_EX_FAILED_PROMOTED: return "CRM_EX_FAILED_PROMOTED";
709 case CRM_EX_USAGE: return "CRM_EX_USAGE";
710 case CRM_EX_DATAERR: return "CRM_EX_DATAERR";
711 case CRM_EX_NOINPUT: return "CRM_EX_NOINPUT";
712 case CRM_EX_NOUSER: return "CRM_EX_NOUSER";
713 case CRM_EX_NOHOST: return "CRM_EX_NOHOST";
714 case CRM_EX_UNAVAILABLE: return "CRM_EX_UNAVAILABLE";
715 case CRM_EX_SOFTWARE: return "CRM_EX_SOFTWARE";
716 case CRM_EX_OSERR: return "CRM_EX_OSERR";
717 case CRM_EX_OSFILE: return "CRM_EX_OSFILE";
718 case CRM_EX_CANTCREAT: return "CRM_EX_CANTCREAT";
719 case CRM_EX_IOERR: return "CRM_EX_IOERR";
720 case CRM_EX_TEMPFAIL: return "CRM_EX_TEMPFAIL";
721 case CRM_EX_PROTOCOL: return "CRM_EX_PROTOCOL";
722 case CRM_EX_NOPERM: return "CRM_EX_NOPERM";
723 case CRM_EX_CONFIG: return "CRM_EX_CONFIG";
724 case CRM_EX_FATAL: return "CRM_EX_FATAL";
725 case CRM_EX_PANIC: return "CRM_EX_PANIC";
726 case CRM_EX_DISCONNECT: return "CRM_EX_DISCONNECT";
727 case CRM_EX_DIGEST: return "CRM_EX_DIGEST";
728 case CRM_EX_NOSUCH: return "CRM_EX_NOSUCH";
729 case CRM_EX_QUORUM: return "CRM_EX_QUORUM";
730 case CRM_EX_UNSAFE: return "CRM_EX_UNSAFE";
731 case CRM_EX_EXISTS: return "CRM_EX_EXISTS";
732 case CRM_EX_MULTIPLE: return "CRM_EX_MULTIPLE";
733 case CRM_EX_EXPIRED: return "CRM_EX_EXPIRED";
734 case CRM_EX_NOT_YET_IN_EFFECT: return "CRM_EX_NOT_YET_IN_EFFECT";
735 case CRM_EX_INDETERMINATE: return "CRM_EX_INDETERMINATE";
736 case CRM_EX_UNSATISFIED: return "CRM_EX_UNSATISFIED";
737 case CRM_EX_OLD: return "CRM_EX_OLD";
738 case CRM_EX_TIMEOUT: return "CRM_EX_TIMEOUT";
739 case CRM_EX_DEGRADED: return "CRM_EX_DEGRADED";
740 case CRM_EX_DEGRADED_PROMOTED: return "CRM_EX_DEGRADED_PROMOTED";
741 case CRM_EX_NONE: return "CRM_EX_NONE";
742 case CRM_EX_MAX: return "CRM_EX_UNKNOWN";
743 }
744 return "CRM_EX_UNKNOWN";
745 }
746
747 const char *
748 crm_exit_str(crm_exit_t exit_code)
749 {
750 switch (exit_code) {
751 case CRM_EX_OK: return "OK";
752 case CRM_EX_ERROR: return "Error occurred";
753 case CRM_EX_INVALID_PARAM: return "Invalid parameter";
754 case CRM_EX_UNIMPLEMENT_FEATURE: return "Unimplemented";
755 case CRM_EX_INSUFFICIENT_PRIV: return "Insufficient privileges";
756 case CRM_EX_NOT_INSTALLED: return "Not installed";
757 case CRM_EX_NOT_CONFIGURED: return "Not configured";
758 case CRM_EX_NOT_RUNNING: return "Not running";
759 case CRM_EX_PROMOTED: return "Promoted";
760 case CRM_EX_FAILED_PROMOTED: return "Failed in promoted role";
761 case CRM_EX_USAGE: return "Incorrect usage";
762 case CRM_EX_DATAERR: return "Invalid data given";
763 case CRM_EX_NOINPUT: return "Input file not available";
764 case CRM_EX_NOUSER: return "User does not exist";
765 case CRM_EX_NOHOST: return "Host does not exist";
766 case CRM_EX_UNAVAILABLE: return "Necessary service unavailable";
767 case CRM_EX_SOFTWARE: return "Internal software bug";
768 case CRM_EX_OSERR: return "Operating system error occurred";
769 case CRM_EX_OSFILE: return "System file not available";
770 case CRM_EX_CANTCREAT: return "Cannot create output file";
771 case CRM_EX_IOERR: return "I/O error occurred";
772 case CRM_EX_TEMPFAIL: return "Temporary failure, try again";
773 case CRM_EX_PROTOCOL: return "Protocol violated";
774 case CRM_EX_NOPERM: return "Insufficient privileges";
775 case CRM_EX_CONFIG: return "Invalid configuration";
776 case CRM_EX_FATAL: return "Fatal error occurred, will not respawn";
777 case CRM_EX_PANIC: return "System panic required";
778 case CRM_EX_DISCONNECT: return "Not connected";
779 case CRM_EX_DIGEST: return "Digest mismatch";
780 case CRM_EX_NOSUCH: return "No such object";
781 case CRM_EX_QUORUM: return "Quorum required";
782 case CRM_EX_UNSAFE: return "Operation not safe";
783 case CRM_EX_EXISTS: return "Requested item already exists";
784 case CRM_EX_MULTIPLE: return "Multiple items match request";
785 case CRM_EX_EXPIRED: return "Requested item has expired";
786 case CRM_EX_NOT_YET_IN_EFFECT: return "Requested item is not yet in effect";
787 case CRM_EX_INDETERMINATE: return "Could not determine status";
788 case CRM_EX_UNSATISFIED: return "Not applicable under current conditions";
789 case CRM_EX_OLD: return "Update was older than existing configuration";
790 case CRM_EX_TIMEOUT: return "Timeout occurred";
791 case CRM_EX_DEGRADED: return "Service is active but might fail soon";
792 case CRM_EX_DEGRADED_PROMOTED: return "Service is promoted but might fail soon";
793 case CRM_EX_NONE: return "No exit status available";
794 case CRM_EX_MAX: return "Error occurred";
795 }
796 if ((exit_code > 128) && (exit_code < CRM_EX_MAX)) {
797 return "Interrupted by signal";
798 }
799 return "Unknown exit status";
800 }
801
802
803
804
805
806
807
808
809 crm_exit_t
810 pcmk_rc2exitc(int rc)
811 {
812 switch (rc) {
813 case pcmk_rc_ok:
814 case pcmk_rc_no_output:
815 return CRM_EX_OK;
816
817 case pcmk_rc_no_quorum:
818 return CRM_EX_QUORUM;
819
820 case pcmk_rc_old_data:
821 return CRM_EX_OLD;
822
823 case pcmk_rc_schema_validation:
824 case pcmk_rc_transform_failed:
825 case pcmk_rc_unpack_error:
826 return CRM_EX_CONFIG;
827
828 case pcmk_rc_bad_nvpair:
829 return CRM_EX_INVALID_PARAM;
830
831 case EACCES:
832 return CRM_EX_INSUFFICIENT_PRIV;
833
834 case EBADF:
835 case EINVAL:
836 case EFAULT:
837 case ENOSYS:
838 case EOVERFLOW:
839 case pcmk_rc_underflow:
840 case pcmk_rc_compression:
841 return CRM_EX_SOFTWARE;
842
843 case EBADMSG:
844 case EMSGSIZE:
845 case ENOMSG:
846 case ENOPROTOOPT:
847 case EPROTO:
848 case EPROTONOSUPPORT:
849 case EPROTOTYPE:
850 return CRM_EX_PROTOCOL;
851
852 case ECOMM:
853 case ENOMEM:
854 return CRM_EX_OSERR;
855
856 case ECONNABORTED:
857 case ECONNREFUSED:
858 case ECONNRESET:
859 case ENOTCONN:
860 return CRM_EX_DISCONNECT;
861
862 case EEXIST:
863 case pcmk_rc_already:
864 return CRM_EX_EXISTS;
865
866 case EIO:
867 case pcmk_rc_dot_error:
868 case pcmk_rc_graph_error:
869 return CRM_EX_IOERR;
870
871 case ENOTSUP:
872 #if EOPNOTSUPP != ENOTSUP
873 case EOPNOTSUPP:
874 #endif
875 return CRM_EX_UNIMPLEMENT_FEATURE;
876
877 case ENOTUNIQ:
878 case pcmk_rc_multiple:
879 return CRM_EX_MULTIPLE;
880
881 case ENODEV:
882 case ENOENT:
883 case ENXIO:
884 case pcmk_rc_no_transaction:
885 case pcmk_rc_unknown_format:
886 return CRM_EX_NOSUCH;
887
888 case pcmk_rc_node_unknown:
889 case pcmk_rc_ns_resolution:
890 return CRM_EX_NOHOST;
891
892 case ETIME:
893 case ETIMEDOUT:
894 return CRM_EX_TIMEOUT;
895
896 case EAGAIN:
897 case EBUSY:
898 return CRM_EX_UNSATISFIED;
899
900 case pcmk_rc_before_range:
901 return CRM_EX_NOT_YET_IN_EFFECT;
902
903 case pcmk_rc_after_range:
904 return CRM_EX_EXPIRED;
905
906 case pcmk_rc_undetermined:
907 return CRM_EX_INDETERMINATE;
908
909 case pcmk_rc_op_unsatisfied:
910 return CRM_EX_UNSATISFIED;
911
912 case pcmk_rc_within_range:
913 return CRM_EX_OK;
914
915 case pcmk_rc_no_input:
916 return CRM_EX_NOINPUT;
917
918 case pcmk_rc_duplicate_id:
919 return CRM_EX_MULTIPLE;
920
921 case pcmk_rc_bad_input:
922 case pcmk_rc_bad_xml_patch:
923 return CRM_EX_DATAERR;
924
925 default:
926 return CRM_EX_ERROR;
927 }
928 }
929
930
931
932
933
934
935
936
937 enum ocf_exitcode
938 pcmk_rc2ocf(int rc)
939 {
940 switch (rc) {
941 case pcmk_rc_ok:
942 return PCMK_OCF_OK;
943
944 case pcmk_rc_bad_nvpair:
945 return PCMK_OCF_INVALID_PARAM;
946
947 case EACCES:
948 return PCMK_OCF_INSUFFICIENT_PRIV;
949
950 case ENOTSUP:
951 #if EOPNOTSUPP != ENOTSUP
952 case EOPNOTSUPP:
953 #endif
954 return PCMK_OCF_UNIMPLEMENT_FEATURE;
955
956 default:
957 return PCMK_OCF_UNKNOWN_ERROR;
958 }
959 }
960
961
962
963
964
965
966
967
968
969
970
971
972 int
973 pcmk__gaierror2rc(int gai)
974 {
975 switch (gai) {
976 case 0:
977 return pcmk_rc_ok;
978
979 case EAI_AGAIN:
980 return EAGAIN;
981
982 case EAI_BADFLAGS:
983 case EAI_SERVICE:
984 return EINVAL;
985
986 case EAI_FAMILY:
987 return EAFNOSUPPORT;
988
989 case EAI_MEMORY:
990 return ENOMEM;
991
992 case EAI_NONAME:
993 return pcmk_rc_node_unknown;
994
995 case EAI_SOCKTYPE:
996 return ESOCKTNOSUPPORT;
997
998 case EAI_SYSTEM:
999 return errno;
1000
1001 default:
1002 return pcmk_rc_ns_resolution;
1003 }
1004 }
1005
1006
1007
1008
1009
1010
1011
1012
1013 int
1014 pcmk__bzlib2rc(int bz2)
1015 {
1016 switch (bz2) {
1017 case BZ_OK:
1018 case BZ_RUN_OK:
1019 case BZ_FLUSH_OK:
1020 case BZ_FINISH_OK:
1021 case BZ_STREAM_END:
1022 return pcmk_rc_ok;
1023
1024 case BZ_MEM_ERROR:
1025 return ENOMEM;
1026
1027 case BZ_DATA_ERROR:
1028 case BZ_DATA_ERROR_MAGIC:
1029 case BZ_UNEXPECTED_EOF:
1030 return pcmk_rc_bad_input;
1031
1032 case BZ_IO_ERROR:
1033 return EIO;
1034
1035 case BZ_OUTBUFF_FULL:
1036 return EFBIG;
1037
1038 default:
1039 return pcmk_rc_compression;
1040 }
1041 }
1042
1043 crm_exit_t
1044 crm_exit(crm_exit_t exit_status)
1045 {
1046
1047
1048
1049 if ((((int) exit_status) < 0) || (((int) exit_status) > CRM_EX_MAX)) {
1050 exit_status = CRM_EX_ERROR;
1051 }
1052
1053 crm_info("Exiting %s " QB_XS " with status %d (%s: %s)",
1054 pcmk__s(crm_system_name, "process"), exit_status,
1055 crm_exit_name(exit_status), crm_exit_str(exit_status));
1056 pcmk_common_cleanup();
1057 exit(exit_status);
1058 }
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073 void
1074 pcmk__set_result(pcmk__action_result_t *result, int exit_status,
1075 enum pcmk_exec_status exec_status, const char *exit_reason)
1076 {
1077 if (result == NULL) {
1078 return;
1079 }
1080
1081 result->exit_status = exit_status;
1082 result->execution_status = exec_status;
1083
1084 if (!pcmk__str_eq(result->exit_reason, exit_reason, pcmk__str_none)) {
1085 free(result->exit_reason);
1086 result->exit_reason = (exit_reason == NULL)? NULL : strdup(exit_reason);
1087 }
1088 }
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102 G_GNUC_PRINTF(4, 5)
1103 void
1104 pcmk__format_result(pcmk__action_result_t *result, int exit_status,
1105 enum pcmk_exec_status exec_status,
1106 const char *format, ...)
1107 {
1108 va_list ap;
1109 int len = 0;
1110 char *reason = NULL;
1111
1112 if (result == NULL) {
1113 return;
1114 }
1115
1116 result->exit_status = exit_status;
1117 result->execution_status = exec_status;
1118
1119 if (format != NULL) {
1120 va_start(ap, format);
1121 len = vasprintf(&reason, format, ap);
1122 pcmk__assert(len > 0);
1123 va_end(ap);
1124 }
1125 free(result->exit_reason);
1126 result->exit_reason = reason;
1127 }
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142 void
1143 pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
1144 {
1145 if (result == NULL) {
1146 return;
1147 }
1148
1149 free(result->action_stdout);
1150 result->action_stdout = out;
1151
1152 free(result->action_stderr);
1153 result->action_stderr = err;
1154 }
1155
1156
1157
1158
1159
1160
1161
1162 void
1163 pcmk__reset_result(pcmk__action_result_t *result)
1164 {
1165 if (result == NULL) {
1166 return;
1167 }
1168
1169 free(result->exit_reason);
1170 result->exit_reason = NULL;
1171
1172 free(result->action_stdout);
1173 result->action_stdout = NULL;
1174
1175 free(result->action_stderr);
1176 result->action_stderr = NULL;
1177 }
1178
1179
1180
1181
1182
1183
1184
1185
1186 void
1187 pcmk__copy_result(const pcmk__action_result_t *src, pcmk__action_result_t *dst)
1188 {
1189 CRM_CHECK((src != NULL) && (dst != NULL), return);
1190 dst->exit_status = src->exit_status;
1191 dst->execution_status = src->execution_status;
1192 dst->exit_reason = pcmk__str_copy(src->exit_reason);
1193 dst->action_stdout = pcmk__str_copy(src->action_stdout);
1194 dst->action_stderr = pcmk__str_copy(src->action_stderr);
1195 }