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 { "pcmk_rc_no_dc",
430 "DC is not yet elected",
431 -pcmk_err_generic,
432 },
433 { "pcmk_rc_ipc_more",
434 "More IPC message fragments to send",
435 -pcmk_err_generic,
436 },
437 };
438
439
440
441
442
443
444
445
446
447 const size_t pcmk__n_rc = PCMK__NELEM(pcmk__rcs);
448
449
450
451
452
453
454
455
456 const char *
457 pcmk_rc_name(int rc)
458 {
459 if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
460 return pcmk__rcs[pcmk_rc_error - rc].name;
461 }
462 switch (rc) {
463 case pcmk_rc_ok: return "pcmk_rc_ok";
464 case E2BIG: return "E2BIG";
465 case EACCES: return "EACCES";
466 case EADDRINUSE: return "EADDRINUSE";
467 case EADDRNOTAVAIL: return "EADDRNOTAVAIL";
468 case EAFNOSUPPORT: return "EAFNOSUPPORT";
469 case EAGAIN: return "EAGAIN";
470 case EALREADY: return "EALREADY";
471 case EBADF: return "EBADF";
472 case EBADMSG: return "EBADMSG";
473 case EBUSY: return "EBUSY";
474 case ECANCELED: return "ECANCELED";
475 case ECHILD: return "ECHILD";
476 case ECOMM: return "ECOMM";
477 case ECONNABORTED: return "ECONNABORTED";
478 case ECONNREFUSED: return "ECONNREFUSED";
479 case ECONNRESET: return "ECONNRESET";
480
481 case EDESTADDRREQ: return "EDESTADDRREQ";
482 case EDOM: return "EDOM";
483 case EDQUOT: return "EDQUOT";
484 case EEXIST: return "EEXIST";
485 case EFAULT: return "EFAULT";
486 case EFBIG: return "EFBIG";
487 case EHOSTDOWN: return "EHOSTDOWN";
488 case EHOSTUNREACH: return "EHOSTUNREACH";
489 case EIDRM: return "EIDRM";
490 case EILSEQ: return "EILSEQ";
491 case EINPROGRESS: return "EINPROGRESS";
492 case EINTR: return "EINTR";
493 case EINVAL: return "EINVAL";
494 case EIO: return "EIO";
495 case EISCONN: return "EISCONN";
496 case EISDIR: return "EISDIR";
497 case ELIBACC: return "ELIBACC";
498 case ELOOP: return "ELOOP";
499 case EMFILE: return "EMFILE";
500 case EMLINK: return "EMLINK";
501 case EMSGSIZE: return "EMSGSIZE";
502 #ifdef EMULTIHOP
503 case EMULTIHOP: return "EMULTIHOP";
504 #endif
505 case ENAMETOOLONG: return "ENAMETOOLONG";
506 case ENETDOWN: return "ENETDOWN";
507 case ENETRESET: return "ENETRESET";
508 case ENETUNREACH: return "ENETUNREACH";
509 case ENFILE: return "ENFILE";
510 case ENOBUFS: return "ENOBUFS";
511 case ENODATA: return "ENODATA";
512 case ENODEV: return "ENODEV";
513 case ENOENT: return "ENOENT";
514 case ENOEXEC: return "ENOEXEC";
515 case ENOKEY: return "ENOKEY";
516 case ENOLCK: return "ENOLCK";
517 #ifdef ENOLINK
518 case ENOLINK: return "ENOLINK";
519 #endif
520 case ENOMEM: return "ENOMEM";
521 case ENOMSG: return "ENOMSG";
522 case ENOPROTOOPT: return "ENOPROTOOPT";
523 case ENOSPC: return "ENOSPC";
524 #ifdef ENOSR
525 case ENOSR: return "ENOSR";
526 #endif
527 #ifdef ENOSTR
528 case ENOSTR: return "ENOSTR";
529 #endif
530 case ENOSYS: return "ENOSYS";
531 case ENOTBLK: return "ENOTBLK";
532 case ENOTCONN: return "ENOTCONN";
533 case ENOTDIR: return "ENOTDIR";
534 case ENOTEMPTY: return "ENOTEMPTY";
535 case ENOTSOCK: return "ENOTSOCK";
536 #if ENOTSUP != EOPNOTSUPP
537 case ENOTSUP: return "ENOTSUP";
538 #endif
539 case ENOTTY: return "ENOTTY";
540 case ENOTUNIQ: return "ENOTUNIQ";
541 case ENXIO: return "ENXIO";
542 case EOPNOTSUPP: return "EOPNOTSUPP";
543 case EOVERFLOW: return "EOVERFLOW";
544 case EPERM: return "EPERM";
545 case EPFNOSUPPORT: return "EPFNOSUPPORT";
546 case EPIPE: return "EPIPE";
547 case EPROTO: return "EPROTO";
548 case EPROTONOSUPPORT: return "EPROTONOSUPPORT";
549 case EPROTOTYPE: return "EPROTOTYPE";
550 case ERANGE: return "ERANGE";
551 case EREMOTE: return "EREMOTE";
552 case EREMOTEIO: return "EREMOTEIO";
553 case EROFS: return "EROFS";
554 case ESHUTDOWN: return "ESHUTDOWN";
555 case ESPIPE: return "ESPIPE";
556 case ESOCKTNOSUPPORT: return "ESOCKTNOSUPPORT";
557 case ESRCH: return "ESRCH";
558 case ESTALE: return "ESTALE";
559 case ETIME: return "ETIME";
560 case ETIMEDOUT: return "ETIMEDOUT";
561 case ETXTBSY: return "ETXTBSY";
562 #ifdef EUNATCH
563 case EUNATCH: return "EUNATCH";
564 #endif
565 case EUSERS: return "EUSERS";
566
567 case EXDEV: return "EXDEV";
568
569 #ifdef EBADE
570 case EBADE: return "EBADE";
571 case EBADFD: return "EBADFD";
572 case EBADSLT: return "EBADSLT";
573 case EDEADLOCK: return "EDEADLOCK";
574 case EBADR: return "EBADR";
575 case EBADRQC: return "EBADRQC";
576 case ECHRNG: return "ECHRNG";
577 #ifdef EISNAM
578 case EISNAM: return "EISNAM";
579 case EKEYEXPIRED: return "EKEYEXPIRED";
580 case EKEYREVOKED: return "EKEYREVOKED";
581 #endif
582 case EKEYREJECTED: return "EKEYREJECTED";
583 case EL2HLT: return "EL2HLT";
584 case EL2NSYNC: return "EL2NSYNC";
585 case EL3HLT: return "EL3HLT";
586 case EL3RST: return "EL3RST";
587 case ELIBBAD: return "ELIBBAD";
588 case ELIBMAX: return "ELIBMAX";
589 case ELIBSCN: return "ELIBSCN";
590 case ELIBEXEC: return "ELIBEXEC";
591 #ifdef ENOMEDIUM
592 case ENOMEDIUM: return "ENOMEDIUM";
593 case EMEDIUMTYPE: return "EMEDIUMTYPE";
594 #endif
595 case ENONET: return "ENONET";
596 case ENOPKG: return "ENOPKG";
597 case EREMCHG: return "EREMCHG";
598 case ERESTART: return "ERESTART";
599 case ESTRPIPE: return "ESTRPIPE";
600 #ifdef EUCLEAN
601 case EUCLEAN: return "EUCLEAN";
602 #endif
603 case EXFULL: return "EXFULL";
604 #endif
605 default: return "Unknown";
606 }
607 }
608
609
610
611
612
613
614
615
616 const char *
617 pcmk_rc_str(int rc)
618 {
619 if (rc == pcmk_rc_ok) {
620 return "OK";
621 }
622 if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
623 return pcmk__rcs[pcmk_rc_error - rc].desc;
624 }
625 if (rc < 0) {
626 return "Error";
627 }
628
629
630 switch (rc) {
631 #ifdef PCMK__ENOTUNIQ
632 case ENOTUNIQ: return "Name not unique on network";
633 #endif
634 #ifdef PCMK__ECOMM
635 case ECOMM: return "Communication error on send";
636 #endif
637 #ifdef PCMK__ELIBACC
638 case ELIBACC: return "Can not access a needed shared library";
639 #endif
640 #ifdef PCMK__EREMOTEIO
641 case EREMOTEIO: return "Remote I/O error";
642 #endif
643 #ifdef PCMK__ENOKEY
644 case ENOKEY: return "Required key not available";
645 #endif
646 #ifdef PCMK__ENODATA
647 case ENODATA: return "No data available";
648 #endif
649 #ifdef PCMK__ETIME
650 case ETIME: return "Timer expired";
651 #endif
652 #ifdef PCMK__EKEYREJECTED
653 case EKEYREJECTED: return "Key was rejected by service";
654 #endif
655 default: return strerror(rc);
656 }
657 }
658
659
660
661 int
662 pcmk_rc2legacy(int rc)
663 {
664 if (rc >= 0) {
665 return -rc;
666 }
667 if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
668 return pcmk__rcs[pcmk_rc_error - rc].legacy_rc;
669 }
670 return -pcmk_err_generic;
671 }
672
673
674 int
675 pcmk_legacy2rc(int legacy_rc)
676 {
677 legacy_rc = abs(legacy_rc);
678 switch (legacy_rc) {
679 case pcmk_err_no_quorum: return pcmk_rc_no_quorum;
680 case pcmk_err_schema_validation: return pcmk_rc_schema_validation;
681 case pcmk_err_schema_unchanged: return pcmk_rc_schema_unchanged;
682 case pcmk_err_transform_failed: return pcmk_rc_transform_failed;
683 case pcmk_err_old_data: return pcmk_rc_old_data;
684 case pcmk_err_diff_failed: return pcmk_rc_diff_failed;
685 case pcmk_err_diff_resync: return pcmk_rc_diff_resync;
686 case pcmk_err_cib_modified: return pcmk_rc_cib_modified;
687 case pcmk_err_cib_backup: return pcmk_rc_cib_backup;
688 case pcmk_err_cib_save: return pcmk_rc_cib_save;
689 case pcmk_err_cib_corrupt: return pcmk_rc_cib_corrupt;
690 case pcmk_err_multiple: return pcmk_rc_multiple;
691 case pcmk_err_node_unknown: return pcmk_rc_node_unknown;
692 case pcmk_err_already: return pcmk_rc_already;
693 case pcmk_err_bad_nvpair: return pcmk_rc_bad_nvpair;
694 case pcmk_err_unknown_format: return pcmk_rc_unknown_format;
695 case pcmk_err_generic: return pcmk_rc_error;
696 case pcmk_ok: return pcmk_rc_ok;
697 default: return legacy_rc;
698 }
699 }
700
701
702
703 const char *
704 crm_exit_name(crm_exit_t exit_code)
705 {
706 switch (exit_code) {
707 case CRM_EX_OK: return "CRM_EX_OK";
708 case CRM_EX_ERROR: return "CRM_EX_ERROR";
709 case CRM_EX_INVALID_PARAM: return "CRM_EX_INVALID_PARAM";
710 case CRM_EX_UNIMPLEMENT_FEATURE: return "CRM_EX_UNIMPLEMENT_FEATURE";
711 case CRM_EX_INSUFFICIENT_PRIV: return "CRM_EX_INSUFFICIENT_PRIV";
712 case CRM_EX_NOT_INSTALLED: return "CRM_EX_NOT_INSTALLED";
713 case CRM_EX_NOT_CONFIGURED: return "CRM_EX_NOT_CONFIGURED";
714 case CRM_EX_NOT_RUNNING: return "CRM_EX_NOT_RUNNING";
715 case CRM_EX_PROMOTED: return "CRM_EX_PROMOTED";
716 case CRM_EX_FAILED_PROMOTED: return "CRM_EX_FAILED_PROMOTED";
717 case CRM_EX_USAGE: return "CRM_EX_USAGE";
718 case CRM_EX_DATAERR: return "CRM_EX_DATAERR";
719 case CRM_EX_NOINPUT: return "CRM_EX_NOINPUT";
720 case CRM_EX_NOUSER: return "CRM_EX_NOUSER";
721 case CRM_EX_NOHOST: return "CRM_EX_NOHOST";
722 case CRM_EX_UNAVAILABLE: return "CRM_EX_UNAVAILABLE";
723 case CRM_EX_SOFTWARE: return "CRM_EX_SOFTWARE";
724 case CRM_EX_OSERR: return "CRM_EX_OSERR";
725 case CRM_EX_OSFILE: return "CRM_EX_OSFILE";
726 case CRM_EX_CANTCREAT: return "CRM_EX_CANTCREAT";
727 case CRM_EX_IOERR: return "CRM_EX_IOERR";
728 case CRM_EX_TEMPFAIL: return "CRM_EX_TEMPFAIL";
729 case CRM_EX_PROTOCOL: return "CRM_EX_PROTOCOL";
730 case CRM_EX_NOPERM: return "CRM_EX_NOPERM";
731 case CRM_EX_CONFIG: return "CRM_EX_CONFIG";
732 case CRM_EX_FATAL: return "CRM_EX_FATAL";
733 case CRM_EX_PANIC: return "CRM_EX_PANIC";
734 case CRM_EX_DISCONNECT: return "CRM_EX_DISCONNECT";
735 case CRM_EX_DIGEST: return "CRM_EX_DIGEST";
736 case CRM_EX_NOSUCH: return "CRM_EX_NOSUCH";
737 case CRM_EX_QUORUM: return "CRM_EX_QUORUM";
738 case CRM_EX_UNSAFE: return "CRM_EX_UNSAFE";
739 case CRM_EX_EXISTS: return "CRM_EX_EXISTS";
740 case CRM_EX_MULTIPLE: return "CRM_EX_MULTIPLE";
741 case CRM_EX_EXPIRED: return "CRM_EX_EXPIRED";
742 case CRM_EX_NOT_YET_IN_EFFECT: return "CRM_EX_NOT_YET_IN_EFFECT";
743 case CRM_EX_INDETERMINATE: return "CRM_EX_INDETERMINATE";
744 case CRM_EX_UNSATISFIED: return "CRM_EX_UNSATISFIED";
745 case CRM_EX_NO_DC: return "CRM_EX_NO_DC";
746 case CRM_EX_OLD: return "CRM_EX_OLD";
747 case CRM_EX_TIMEOUT: return "CRM_EX_TIMEOUT";
748 case CRM_EX_DEGRADED: return "CRM_EX_DEGRADED";
749 case CRM_EX_DEGRADED_PROMOTED: return "CRM_EX_DEGRADED_PROMOTED";
750 case CRM_EX_NONE: return "CRM_EX_NONE";
751 case CRM_EX_MAX: return "CRM_EX_UNKNOWN";
752 }
753 return "CRM_EX_UNKNOWN";
754 }
755
756 const char *
757 crm_exit_str(crm_exit_t exit_code)
758 {
759 switch (exit_code) {
760 case CRM_EX_OK: return "OK";
761 case CRM_EX_ERROR: return "Error occurred";
762 case CRM_EX_INVALID_PARAM: return "Invalid parameter";
763 case CRM_EX_UNIMPLEMENT_FEATURE: return "Unimplemented";
764 case CRM_EX_INSUFFICIENT_PRIV: return "Insufficient privileges";
765 case CRM_EX_NOT_INSTALLED: return "Not installed";
766 case CRM_EX_NOT_CONFIGURED: return "Not configured";
767 case CRM_EX_NOT_RUNNING: return "Not running";
768 case CRM_EX_PROMOTED: return "Promoted";
769 case CRM_EX_FAILED_PROMOTED: return "Failed in promoted role";
770 case CRM_EX_USAGE: return "Incorrect usage";
771 case CRM_EX_DATAERR: return "Invalid data given";
772 case CRM_EX_NOINPUT: return "Input file not available";
773 case CRM_EX_NOUSER: return "User does not exist";
774 case CRM_EX_NOHOST: return "Host does not exist";
775 case CRM_EX_UNAVAILABLE: return "Necessary service unavailable";
776 case CRM_EX_SOFTWARE: return "Internal software bug";
777 case CRM_EX_OSERR: return "Operating system error occurred";
778 case CRM_EX_OSFILE: return "System file not available";
779 case CRM_EX_CANTCREAT: return "Cannot create output file";
780 case CRM_EX_IOERR: return "I/O error occurred";
781 case CRM_EX_TEMPFAIL: return "Temporary failure, try again";
782 case CRM_EX_PROTOCOL: return "Protocol violated";
783 case CRM_EX_NOPERM: return "Insufficient privileges";
784 case CRM_EX_CONFIG: return "Invalid configuration";
785 case CRM_EX_FATAL: return "Fatal error occurred, will not respawn";
786 case CRM_EX_PANIC: return "System panic required";
787 case CRM_EX_DISCONNECT: return "Not connected";
788 case CRM_EX_DIGEST: return "Digest mismatch";
789 case CRM_EX_NOSUCH: return "No such object";
790 case CRM_EX_QUORUM: return "Quorum required";
791 case CRM_EX_UNSAFE: return "Operation not safe";
792 case CRM_EX_EXISTS: return "Requested item already exists";
793 case CRM_EX_MULTIPLE: return "Multiple items match request";
794 case CRM_EX_EXPIRED: return "Requested item has expired";
795 case CRM_EX_NOT_YET_IN_EFFECT: return "Requested item is not yet in effect";
796 case CRM_EX_INDETERMINATE: return "Could not determine status";
797 case CRM_EX_UNSATISFIED: return "Not applicable under current conditions";
798 case CRM_EX_NO_DC: return "DC is not yet elected";
799 case CRM_EX_OLD: return "Update was older than existing configuration";
800 case CRM_EX_TIMEOUT: return "Timeout occurred";
801 case CRM_EX_DEGRADED: return "Service is active but might fail soon";
802 case CRM_EX_DEGRADED_PROMOTED: return "Service is promoted but might fail soon";
803 case CRM_EX_NONE: return "No exit status available";
804 case CRM_EX_MAX: return "Error occurred";
805 }
806 if ((exit_code > 128) && (exit_code < CRM_EX_MAX)) {
807 return "Interrupted by signal";
808 }
809 return "Unknown exit status";
810 }
811
812
813
814
815
816
817
818
819 crm_exit_t
820 pcmk_rc2exitc(int rc)
821 {
822 switch (rc) {
823 case pcmk_rc_ok:
824 case pcmk_rc_no_output:
825 return CRM_EX_OK;
826
827 case pcmk_rc_no_quorum:
828 return CRM_EX_QUORUM;
829
830 case pcmk_rc_old_data:
831 return CRM_EX_OLD;
832
833 case pcmk_rc_cib_corrupt:
834 case pcmk_rc_schema_validation:
835 case pcmk_rc_transform_failed:
836 case pcmk_rc_unpack_error:
837 return CRM_EX_CONFIG;
838
839 case pcmk_rc_bad_nvpair:
840 return CRM_EX_INVALID_PARAM;
841
842 case EACCES:
843 return CRM_EX_INSUFFICIENT_PRIV;
844
845 case EBADF:
846 case EINVAL:
847 case EFAULT:
848 case ENOSYS:
849 case EOVERFLOW:
850 case pcmk_rc_underflow:
851 case pcmk_rc_compression:
852 return CRM_EX_SOFTWARE;
853
854 case EBADMSG:
855 case EMSGSIZE:
856 case ENOMSG:
857 case ENOPROTOOPT:
858 case EPROTO:
859 case EPROTONOSUPPORT:
860 case EPROTOTYPE:
861 return CRM_EX_PROTOCOL;
862
863 case ECOMM:
864 case ENOMEM:
865 return CRM_EX_OSERR;
866
867 case ECONNABORTED:
868 case ECONNREFUSED:
869 case ECONNRESET:
870 case ENOTCONN:
871 return CRM_EX_DISCONNECT;
872
873 case EEXIST:
874 case pcmk_rc_already:
875 return CRM_EX_EXISTS;
876
877 case EIO:
878 case pcmk_rc_dot_error:
879 case pcmk_rc_graph_error:
880 return CRM_EX_IOERR;
881
882 case ENOTSUP:
883 #if EOPNOTSUPP != ENOTSUP
884 case EOPNOTSUPP:
885 #endif
886 return CRM_EX_UNIMPLEMENT_FEATURE;
887
888 case ENOTUNIQ:
889 case pcmk_rc_multiple:
890 return CRM_EX_MULTIPLE;
891
892 case ENODEV:
893 case ENOENT:
894 case ENXIO:
895 case pcmk_rc_no_transaction:
896 case pcmk_rc_unknown_format:
897 return CRM_EX_NOSUCH;
898
899 case pcmk_rc_node_unknown:
900 case pcmk_rc_ns_resolution:
901 return CRM_EX_NOHOST;
902
903 case ETIME:
904 case ETIMEDOUT:
905 return CRM_EX_TIMEOUT;
906
907 case EAGAIN:
908 case EBUSY:
909 return CRM_EX_UNSATISFIED;
910
911 case pcmk_rc_before_range:
912 return CRM_EX_NOT_YET_IN_EFFECT;
913
914 case pcmk_rc_after_range:
915 return CRM_EX_EXPIRED;
916
917 case pcmk_rc_undetermined:
918 return CRM_EX_INDETERMINATE;
919
920 case pcmk_rc_op_unsatisfied:
921 return CRM_EX_UNSATISFIED;
922
923 case pcmk_rc_within_range:
924 return CRM_EX_OK;
925
926 case pcmk_rc_no_input:
927 return CRM_EX_NOINPUT;
928
929 case pcmk_rc_duplicate_id:
930 return CRM_EX_MULTIPLE;
931
932 case pcmk_rc_bad_input:
933 case pcmk_rc_bad_xml_patch:
934 return CRM_EX_DATAERR;
935
936 case pcmk_rc_no_dc:
937 return CRM_EX_NO_DC;
938
939 default:
940 return CRM_EX_ERROR;
941 }
942 }
943
944
945
946
947
948
949
950
951 enum ocf_exitcode
952 pcmk_rc2ocf(int rc)
953 {
954 switch (rc) {
955 case pcmk_rc_ok:
956 return PCMK_OCF_OK;
957
958 case pcmk_rc_bad_nvpair:
959 return PCMK_OCF_INVALID_PARAM;
960
961 case EACCES:
962 return PCMK_OCF_INSUFFICIENT_PRIV;
963
964 case ENOTSUP:
965 #if EOPNOTSUPP != ENOTSUP
966 case EOPNOTSUPP:
967 #endif
968 return PCMK_OCF_UNIMPLEMENT_FEATURE;
969
970 default:
971 return PCMK_OCF_UNKNOWN_ERROR;
972 }
973 }
974
975
976
977
978
979
980
981
982
983
984
985
986 int
987 pcmk__gaierror2rc(int gai)
988 {
989 switch (gai) {
990 case 0:
991 return pcmk_rc_ok;
992
993 case EAI_AGAIN:
994 return EAGAIN;
995
996 case EAI_BADFLAGS:
997 case EAI_SERVICE:
998 return EINVAL;
999
1000 case EAI_FAMILY:
1001 return EAFNOSUPPORT;
1002
1003 case EAI_MEMORY:
1004 return ENOMEM;
1005
1006 case EAI_NONAME:
1007 return pcmk_rc_node_unknown;
1008
1009 case EAI_SOCKTYPE:
1010 return ESOCKTNOSUPPORT;
1011
1012 case EAI_SYSTEM:
1013 return errno;
1014
1015 default:
1016 return pcmk_rc_ns_resolution;
1017 }
1018 }
1019
1020
1021
1022
1023
1024
1025
1026
1027 int
1028 pcmk__bzlib2rc(int bz2)
1029 {
1030 switch (bz2) {
1031 case BZ_OK:
1032 case BZ_RUN_OK:
1033 case BZ_FLUSH_OK:
1034 case BZ_FINISH_OK:
1035 case BZ_STREAM_END:
1036 return pcmk_rc_ok;
1037
1038 case BZ_MEM_ERROR:
1039 return ENOMEM;
1040
1041 case BZ_DATA_ERROR:
1042 case BZ_DATA_ERROR_MAGIC:
1043 case BZ_UNEXPECTED_EOF:
1044 return pcmk_rc_bad_input;
1045
1046 case BZ_IO_ERROR:
1047 return EIO;
1048
1049 case BZ_OUTBUFF_FULL:
1050 return EFBIG;
1051
1052 default:
1053 return pcmk_rc_compression;
1054 }
1055 }
1056
1057 crm_exit_t
1058 crm_exit(crm_exit_t exit_status)
1059 {
1060
1061
1062
1063 if ((((int) exit_status) < 0) || (((int) exit_status) > CRM_EX_MAX)) {
1064 exit_status = CRM_EX_ERROR;
1065 }
1066
1067 crm_info("Exiting %s " QB_XS " with status %d (%s: %s)",
1068 pcmk__s(crm_system_name, "process"), exit_status,
1069 crm_exit_name(exit_status), crm_exit_str(exit_status));
1070 pcmk_common_cleanup();
1071 exit(exit_status);
1072 }
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087 void
1088 pcmk__set_result(pcmk__action_result_t *result, int exit_status,
1089 enum pcmk_exec_status exec_status, const char *exit_reason)
1090 {
1091 if (result == NULL) {
1092 return;
1093 }
1094
1095 result->exit_status = exit_status;
1096 result->execution_status = exec_status;
1097
1098 if (!pcmk__str_eq(result->exit_reason, exit_reason, pcmk__str_none)) {
1099 free(result->exit_reason);
1100 result->exit_reason = (exit_reason == NULL)? NULL : strdup(exit_reason);
1101 }
1102 }
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116 G_GNUC_PRINTF(4, 5)
1117 void
1118 pcmk__format_result(pcmk__action_result_t *result, int exit_status,
1119 enum pcmk_exec_status exec_status,
1120 const char *format, ...)
1121 {
1122 va_list ap;
1123 int len = 0;
1124 char *reason = NULL;
1125
1126 if (result == NULL) {
1127 return;
1128 }
1129
1130 result->exit_status = exit_status;
1131 result->execution_status = exec_status;
1132
1133 if (format != NULL) {
1134 va_start(ap, format);
1135 len = vasprintf(&reason, format, ap);
1136 pcmk__assert(len > 0);
1137 va_end(ap);
1138 }
1139 free(result->exit_reason);
1140 result->exit_reason = reason;
1141 }
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156 void
1157 pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
1158 {
1159 if (result == NULL) {
1160 return;
1161 }
1162
1163 free(result->action_stdout);
1164 result->action_stdout = out;
1165
1166 free(result->action_stderr);
1167 result->action_stderr = err;
1168 }
1169
1170
1171
1172
1173
1174
1175
1176 void
1177 pcmk__reset_result(pcmk__action_result_t *result)
1178 {
1179 if (result == NULL) {
1180 return;
1181 }
1182
1183 free(result->exit_reason);
1184 result->exit_reason = NULL;
1185
1186 free(result->action_stdout);
1187 result->action_stdout = NULL;
1188
1189 free(result->action_stderr);
1190 result->action_stderr = NULL;
1191 }
1192
1193
1194
1195
1196
1197
1198
1199
1200 void
1201 pcmk__copy_result(const pcmk__action_result_t *src, pcmk__action_result_t *dst)
1202 {
1203 CRM_CHECK((src != NULL) && (dst != NULL), return);
1204 dst->exit_status = src->exit_status;
1205 dst->execution_status = src->execution_status;
1206 dst->exit_reason = pcmk__str_copy(src->exit_reason);
1207 dst->action_stdout = pcmk__str_copy(src->action_stdout);
1208 dst->action_stderr = pcmk__str_copy(src->action_stderr);
1209 }