pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
results.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2025 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
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
24G_DEFINE_QUARK(pcmk-rc-error-quark, pcmk__rc_error)
25G_DEFINE_QUARK(pcmk-exitc-error-quark, pcmk__exitc_error)
26
27// General (all result code types)
28
29
41int
43 const char **desc)
44{
45 const char *code_name = NULL;
46 const char *code_desc = NULL;
47
48 switch (type) {
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;
58 code_name = crm_exit_name(code);
59 code_desc = crm_exit_str((crm_exit_t) code);
60 break;
61 default:
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
91int
92pcmk__result_bounds(enum pcmk_result_type type, int *lower, int *upper)
93{
94 pcmk__assert((lower != NULL) && (upper != NULL));
95
96 switch (type) {
98 *lower = pcmk_ok;
99 *upper = 256; // should be enough for almost any system error code
100 break;
101 case pcmk_result_rc:
102 *lower = pcmk_rc_error - pcmk__n_rc + 1;
103 *upper = 256;
104 break;
106 *lower = CRM_EX_OK;
107 *upper = CRM_EX_MAX;
108 break;
109 default:
110 *lower = 0;
111 *upper = -1;
113 }
114 return pcmk_rc_ok;
115}
116
126static void
127log_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); // Make sure command-line user sees message
132 }
133 crm_err("%s: Triggered fatal assertion at %s:%d : %s",
134 function, file, line, assert_condition);
135}
136
137/* coverity[+kill] */
149_Noreturn void
150pcmk__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/* coverity[+kill] */
170static void
171fail_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); // No return
179 }
180
181 pid = fork();
182 switch (pid) {
183 case -1: // Fork failed
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: // Child process: just abort to dump core
189 abort();
190 break;
191
192 default: // Parent process: wait for child
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; // Child finished dumping core
199 }
200 } while (errno == EINTR);
201 if (errno == ECHILD) {
202 // crm_mon ignores SIGCHLD
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/* coverity[+kill] */
214void
215crm_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); // No return
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// @COMPAT Legacy function return codes
228
230const char *
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); // system errno
252 }
253}
254
256const char *
258{
259 return pcmk_rc_str(pcmk_legacy2rc(rc));
260}
261
262// Standard Pacemaker API return codes
263
264/* This array is used only for nonzero values of pcmk_rc_e. Its values must be
265 * kept in the exact reverse order of the enum value numbering (i.e. add new
266 * values to the end of the array).
267 */
268static 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",
276 },
277 { "pcmk_rc_unknown_format",
278 "Unknown output format",
280 },
281 { "pcmk_rc_bad_nvpair",
282 "Bad name/value pair given",
284 },
285 { "pcmk_rc_already",
286 "Already in requested state",
288 },
289 { "pcmk_rc_node_unknown",
290 "Node not found",
292 },
293 { "pcmk_rc_multiple",
294 "Resource active on multiple nodes",
296 },
297 { "pcmk_rc_cib_corrupt",
298 "Could not parse on-disk configuration",
300 },
301 { "pcmk_rc_cib_save",
302 "Could not save new configuration to disk",
304 },
305 { "pcmk_rc_cib_backup",
306 "Could not archive previous configuration",
308 },
309 { "pcmk_rc_cib_modified",
310 "On-disk configuration was manually modified",
312 },
313 { "pcmk_rc_diff_resync",
314 "Application of update diff failed, requesting full refresh",
316 },
317 { "pcmk_rc_diff_failed",
318 "Application of update diff failed",
320 },
321 { "pcmk_rc_old_data",
322 "Update was older than existing configuration",
324 },
325 { "pcmk_rc_transform_failed",
326 "Schema transform failed",
328 },
329 { "pcmk_rc_schema_unchanged",
330 "Schema is already the latest available",
332 },
333 { "pcmk_rc_schema_validation",
334 "Update does not conform to the configured schema",
336 },
337 { "pcmk_rc_no_quorum",
338 "Operation requires quorum",
340 },
341 { "pcmk_rc_ipc_unauthorized",
342 "IPC server is blocked by unauthorized process",
344 },
345 { "pcmk_rc_ipc_unresponsive",
346 "IPC server is unresponsive",
348 },
349 { "pcmk_rc_ipc_pid_only",
350 "IPC server process is active but not accepting connections",
352 },
353 { "pcmk_rc_op_unsatisfied",
354 "Not applicable under current conditions",
356 },
357 { "pcmk_rc_undetermined",
358 "Result undetermined",
360 },
361 { "pcmk_rc_before_range",
362 "Result occurs before given range",
364 },
365 { "pcmk_rc_within_range",
366 "Result occurs within given range",
368 },
369 { "pcmk_rc_after_range",
370 "Result occurs after given range",
372 },
373 { "pcmk_rc_no_output",
374 "Output message produced no output",
376 },
377 { "pcmk_rc_no_input",
378 "Input file not available",
380 },
381 { "pcmk_rc_underflow",
382 "Value too small to be stored in data type",
384 },
385 { "pcmk_rc_dot_error",
386 "Error writing dot(1) file",
388 },
389 { "pcmk_rc_graph_error",
390 "Error writing graph file",
392 },
393 { "pcmk_rc_invalid_transition",
394 "Cluster simulation produced invalid transition",
396 },
397 { "pcmk_rc_unpack_error",
398 "Unable to parse CIB XML",
400 },
401 { "pcmk_rc_duplicate_id",
402 "Two or more XML elements have the same ID",
404 },
405 { "pcmk_rc_disabled",
406 "Disabled",
408 },
409 { "pcmk_rc_bad_input",
410 "Bad input value provided",
412 },
413 { "pcmk_rc_bad_xml_patch",
414 "Bad XML patch format",
416 },
417 { "pcmk_rc_no_transaction",
418 "No active transaction found",
420 },
421 { "pcmk_rc_ns_resolution",
422 "Nameserver resolution error",
424 },
425 { "pcmk_rc_compression",
426 "Compression/decompression error",
428 },
429 { "pcmk_rc_no_dc",
430 "DC is not yet elected",
432 },
433 { "pcmk_rc_ipc_more",
434 "More IPC message fragments to send",
436 },
437};
438
447const size_t pcmk__n_rc = PCMK__NELEM(pcmk__rcs);
448
456const char *
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 /* case EDEADLK: return "EDEADLK"; */
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 // Not available on OpenBSD
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 // Not available on OpenBSD
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 /* case EWOULDBLOCK: return "EWOULDBLOCK"; */
567 case EXDEV: return "EXDEV";
568
569#ifdef EBADE // Not available on OS X
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 // Not available on OS X, Illumos, Solaris
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 // Not available on OS X, Illumos, Solaris
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 // Not available on OS X, Illumos, Solaris
601 case EUCLEAN: return "EUCLEAN";
602#endif
603 case EXFULL: return "EXFULL";
604#endif // EBADE
605 default: return "Unknown";
606 }
607}
608
616const char *
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 // Handle values that could be defined by system or by portability.h
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// This returns negative values for errors
661int
663{
664 if (rc >= 0) {
665 return -rc; // OK or system errno
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
674int
675pcmk_legacy2rc(int legacy_rc)
676{
677 legacy_rc = abs(legacy_rc);
678 switch (legacy_rc) {
695 case pcmk_err_generic: return pcmk_rc_error;
696 case pcmk_ok: return pcmk_rc_ok;
697 default: return legacy_rc; // system errno
698 }
699}
700
701// Exit status codes
702
703const char *
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
756const char *
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
821{
822 switch (rc) {
823 case pcmk_rc_ok:
824 case pcmk_rc_no_output: // quiet mode, or nothing to output
825 return CRM_EX_OK;
826
828 return CRM_EX_QUORUM;
829
830 case pcmk_rc_old_data:
831 return CRM_EX_OLD;
832
837 return CRM_EX_CONFIG;
838
841
842 case EACCES:
844
845 case EBADF:
846 case EINVAL:
847 case EFAULT:
848 case ENOSYS:
849 case EOVERFLOW:
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:
880 return CRM_EX_IOERR;
881
882 case ENOTSUP:
883#if EOPNOTSUPP != ENOTSUP
884 case EOPNOTSUPP:
885#endif
887
888 case ENOTUNIQ:
889 case pcmk_rc_multiple:
890 return CRM_EX_MULTIPLE;
891
892 case ENODEV:
893 case ENOENT:
894 case ENXIO:
897 return CRM_EX_NOSUCH;
898
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
913
915 return CRM_EX_EXPIRED;
916
919
921 return CRM_EX_UNSATISFIED;
922
924 return CRM_EX_OK;
925
926 case pcmk_rc_no_input:
927 return CRM_EX_NOINPUT;
928
930 return CRM_EX_MULTIPLE;
931
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
951enum ocf_exitcode
953{
954 switch (rc) {
955 case pcmk_rc_ok:
956 return PCMK_OCF_OK;
957
960
961 case EACCES:
963
964 case ENOTSUP:
965#if EOPNOTSUPP != ENOTSUP
966 case EOPNOTSUPP:
967#endif
969
970 default:
972 }
973}
974
975
976// Other functions
977
986int
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
1027int
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
1059{
1060 /* A compiler could theoretically use any type for crm_exit_t, but an int
1061 * should always hold it, so cast to int to keep static analysis happy.
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));
1071 exit(exit_status);
1072}
1073
1074/*
1075 * External action results
1076 */
1077
1087void
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
1116G_GNUC_PRINTF(4, 5)
1117void
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
1156void
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
1176void
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
1200void
1202{
1203 CRM_CHECK((src != NULL) && (dst != NULL), return);
1204 dst->exit_status = src->exit_status;
1209}
const char * name
Definition cib.c:26
#define PCMK__NELEM(a)
Definition internal.h:50
bool pcmk__is_daemon
Definition logging.c:47
void pcmk_common_cleanup(void)
Free all memory used by libcrmcommon.
Definition utils.c:55
uint32_t pid
Definition cpg.c:1
enum pcmk_ipc_server type
Definition cpg.c:3
char * crm_system_name
Definition utils.c:45
#define crm_info(fmt, args...)
Definition logging.h:365
void crm_write_blackbox(int nsig, const struct qb_log_callsite *callsite)
Definition logging.c:519
#define crm_warn(fmt, args...)
Definition logging.h:360
void crm_enable_stderr(int enable)
Definition logging.c:1071
#define CRM_CHECK(expr, failure_action)
Definition logging.h:213
#define crm_err(fmt, args...)
Definition logging.h:357
#define crm_trace(fmt, args...)
Definition logging.h:370
Wrappers for and extensions to glib mainloop.
pcmk__action_result_t result
Definition pcmk_fence.c:37
#define ENODATA
Definition portability.h:61
#define ENOKEY
Definition portability.h:56
#define ELIBACC
Definition portability.h:46
#define EREMOTEIO
Definition portability.h:51
#define ETIME
Definition portability.h:66
#define ECOMM
Definition portability.h:41
#define EKEYREJECTED
Definition portability.h:71
#define ENOTUNIQ
Definition portability.h:36
const char * pcmk_rc_name(int rc)
Get a return code constant name as a string.
Definition results.c:457
_Noreturn void pcmk__abort_as(const char *file, const char *function, int line, const char *assert_condition)
Definition results.c:150
const char * pcmk_strerror(int rc)
Definition results.c:257
void pcmk__set_result(pcmk__action_result_t *result, int exit_status, enum pcmk_exec_status exec_status, const char *exit_reason)
Definition results.c:1088
int pcmk__result_bounds(enum pcmk_result_type type, int *lower, int *upper)
Definition results.c:92
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition results.c:617
int pcmk_result_get_strings(int code, enum pcmk_result_type type, const char **name, const char **desc)
Get the name and description of a given result code.
Definition results.c:42
enum ocf_exitcode pcmk_rc2ocf(int rc)
Map a function return code to the most similar OCF exit code.
Definition results.c:952
int pcmk__gaierror2rc(int gai)
Map a getaddrinfo() return code to the most similar Pacemaker return code.
Definition results.c:987
void pcmk__format_result(pcmk__action_result_t *result, int exit_status, enum pcmk_exec_status exec_status, const char *format,...)
Definition results.c:1118
void pcmk__copy_result(const pcmk__action_result_t *src, pcmk__action_result_t *dst)
Definition results.c:1201
const char * crm_exit_name(crm_exit_t exit_code)
Definition results.c:704
const size_t pcmk__n_rc
Definition results.c:447
int pcmk_rc2legacy(int rc)
Definition results.c:662
const char * pcmk_errorname(int rc)
Definition results.c:231
void crm_abort(const char *file, const char *function, int line, const char *assert_condition, gboolean do_core, gboolean do_fork)
Definition results.c:215
const char * crm_exit_str(crm_exit_t exit_code)
Definition results.c:757
void pcmk__reset_result(pcmk__action_result_t *result)
Definition results.c:1177
int pcmk_legacy2rc(int legacy_rc)
Definition results.c:675
crm_exit_t crm_exit(crm_exit_t exit_status)
Definition results.c:1058
void pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
Definition results.c:1157
int pcmk__bzlib2rc(int bz2)
Map a bz2 return code to the most similar Pacemaker return code.
Definition results.c:1028
crm_exit_t pcmk_rc2exitc(int rc)
Map a function return code to the most similar exit code.
Definition results.c:820
#define pcmk_err_cib_corrupt
Definition results.h:85
#define pcmk_err_old_data
Definition results.h:73
#define pcmk_err_node_unknown
Definition results.h:87
#define pcmk_err_unknown_format
Definition results.h:95
#define pcmk_err_generic
Definition results.h:69
#define pcmk_err_cib_modified
Definition results.h:81
#define pcmk_err_schema_unchanged
Definition results.h:84
@ CRM_EX_IOERR
File I/O error.
Definition results.h:257
@ CRM_EX_PANIC
Panic the local host.
Definition results.h:265
@ CRM_EX_PROTOCOL
Protocol violated.
Definition results.h:259
@ CRM_EX_NOSUCH
Requested item does not exist.
Definition results.h:269
@ CRM_EX_DATAERR
User-supplied data incorrect.
Definition results.h:248
@ CRM_EX_UNSATISFIED
Requested item does not satisfy constraints.
Definition results.h:277
@ CRM_EX_UNSAFE
Requires –force or new conditions.
Definition results.h:271
@ CRM_EX_EXISTS
Requested item already exists.
Definition results.h:272
@ CRM_EX_TIMEOUT
Convention from timeout(1)
Definition results.h:281
@ CRM_EX_NOT_RUNNING
Service safely stopped.
Definition results.h:242
@ CRM_EX_MULTIPLE
Requested item has multiple matches.
Definition results.h:273
@ CRM_EX_UNIMPLEMENT_FEATURE
Requested action not implemented.
Definition results.h:238
@ CRM_EX_ERROR
Unspecified error.
Definition results.h:234
@ CRM_EX_NOT_YET_IN_EFFECT
Requested item is not in effect.
Definition results.h:275
@ CRM_EX_DEGRADED
Service active but more likely to fail soon.
Definition results.h:289
@ CRM_EX_FAILED_PROMOTED
Service failed and possibly promoted.
Definition results.h:244
@ CRM_EX_CANTCREAT
File couldn't be created.
Definition results.h:256
@ CRM_EX_NONE
No exit status available.
Definition results.h:297
@ CRM_EX_OLD
Update older than existing config.
Definition results.h:267
@ CRM_EX_SOFTWARE
Internal software bug.
Definition results.h:253
@ CRM_EX_OSFILE
System file not usable.
Definition results.h:255
@ CRM_EX_NOHOST
Host unknown.
Definition results.h:251
@ CRM_EX_CONFIG
Misconfiguration.
Definition results.h:261
@ CRM_EX_NOPERM
Non-file permission issue.
Definition results.h:260
@ CRM_EX_NOT_CONFIGURED
Parameter invalid (inherently)
Definition results.h:241
@ CRM_EX_NOINPUT
Input file not available.
Definition results.h:249
@ CRM_EX_NO_DC
DC is not yet elected, e.g. right after cluster restart.
Definition results.h:278
@ CRM_EX_UNAVAILABLE
Needed service unavailable.
Definition results.h:252
@ CRM_EX_OSERR
External (OS/environmental) problem.
Definition results.h:254
@ CRM_EX_DISCONNECT
Lost connection to something.
Definition results.h:266
@ CRM_EX_FATAL
Do not respawn.
Definition results.h:264
@ CRM_EX_DIGEST
Digest comparison failed.
Definition results.h:268
@ CRM_EX_PROMOTED
Service active and promoted.
Definition results.h:243
@ CRM_EX_EXPIRED
Requested item has expired.
Definition results.h:274
@ CRM_EX_NOUSER
User does not exist.
Definition results.h:250
@ CRM_EX_OK
Success.
Definition results.h:233
@ CRM_EX_DEGRADED_PROMOTED
Service promoted but more likely to fail soon.
Definition results.h:290
@ CRM_EX_USAGE
Command line usage error.
Definition results.h:247
@ CRM_EX_MAX
Ensure crm_exit_t can hold this.
Definition results.h:299
@ CRM_EX_QUORUM
Local partition does not have quorum.
Definition results.h:270
@ CRM_EX_NOT_INSTALLED
Dependencies not available locally.
Definition results.h:240
@ CRM_EX_INVALID_PARAM
Parameter invalid (in local context)
Definition results.h:237
@ CRM_EX_INSUFFICIENT_PRIV
Insufficient privileges.
Definition results.h:239
@ CRM_EX_TEMPFAIL
Try again.
Definition results.h:258
@ CRM_EX_INDETERMINATE
Could not determine status.
Definition results.h:276
ocf_exitcode
Exit status codes for resource agents.
Definition results.h:173
@ PCMK_OCF_INSUFFICIENT_PRIV
Insufficient privileges.
Definition results.h:181
@ PCMK_OCF_UNIMPLEMENT_FEATURE
Requested action not implemented.
Definition results.h:180
@ PCMK_OCF_UNKNOWN_ERROR
Unspecified error.
Definition results.h:177
@ PCMK_OCF_INVALID_PARAM
Parameter invalid (in local context)
Definition results.h:179
@ PCMK_OCF_OK
Success.
Definition results.h:174
#define pcmk_err_schema_validation
Definition results.h:71
@ pcmk_rc_compression
Definition results.h:115
@ pcmk_rc_no_input
Definition results.h:127
@ pcmk_rc_before_range
Definition results.h:131
@ pcmk_rc_ns_resolution
Definition results.h:116
@ pcmk_rc_cib_backup
Definition results.h:145
@ pcmk_rc_no_transaction
Definition results.h:117
@ pcmk_rc_op_unsatisfied
Definition results.h:133
@ pcmk_rc_node_unknown
Definition results.h:149
@ pcmk_rc_transform_failed
Definition results.h:140
@ pcmk_rc_no_output
Definition results.h:128
@ pcmk_rc_multiple
Definition results.h:148
@ pcmk_rc_no_dc
Definition results.h:114
@ pcmk_rc_bad_nvpair
Definition results.h:151
@ pcmk_rc_old_data
Definition results.h:141
@ pcmk_rc_ok
Definition results.h:159
@ pcmk_rc_no_quorum
Definition results.h:137
@ pcmk_rc_schema_validation
Definition results.h:138
@ pcmk_rc_undetermined
Definition results.h:132
@ pcmk_rc_cib_save
Definition results.h:146
@ pcmk_rc_unknown_format
Definition results.h:152
@ pcmk_rc_within_range
Definition results.h:130
@ pcmk_rc_after_range
Definition results.h:129
@ pcmk_rc_schema_unchanged
Definition results.h:139
@ pcmk_rc_unpack_error
Definition results.h:122
@ pcmk_rc_error
Definition results.h:154
@ pcmk_rc_already
Definition results.h:150
@ pcmk_rc_dot_error
Definition results.h:125
@ pcmk_rc_duplicate_id
Definition results.h:121
@ pcmk_rc_diff_resync
Definition results.h:143
@ pcmk_rc_underflow
Definition results.h:126
@ pcmk_rc_diff_failed
Definition results.h:142
@ pcmk_rc_bad_input
Definition results.h:119
@ pcmk_rc_graph_error
Definition results.h:124
@ pcmk_rc_cib_modified
Definition results.h:144
@ pcmk_rc_bad_xml_patch
Definition results.h:118
@ pcmk_rc_cib_corrupt
Definition results.h:147
#define pcmk_err_bad_nvpair
Definition results.h:94
#define pcmk_err_multiple
Definition results.h:86
#define pcmk_err_no_quorum
Definition results.h:70
#define pcmk_err_cib_save
Definition results.h:83
#define pcmk_ok
Definition results.h:65
pcmk_result_type
Types of Pacemaker result codes.
Definition results.h:341
@ pcmk_result_exitcode
Exit status code.
Definition results.h:344
@ pcmk_result_legacy
Legacy API function return code.
Definition results.h:342
@ pcmk_result_rc
Standard Pacemaker return code.
Definition results.h:343
#define pcmk_err_diff_failed
Definition results.h:76
pcmk_exec_status
Execution status.
Definition results.h:308
#define pcmk_err_diff_resync
Definition results.h:79
#define pcmk_err_transform_failed
Definition results.h:72
enum crm_exit_e crm_exit_t
Exit status codes for tools and daemons.
#define pcmk_err_cib_backup
Definition results.h:82
#define pcmk_err_already
Definition results.h:88
#define _Noreturn
Definition results.h:40
#define pcmk__assert(expr)
@ pcmk__str_none
#define pcmk__str_copy(str)
enum pcmk_exec_status execution_status
Wrappers for and extensions to libxml2.