pacemaker  2.1.9-49aab99839
Scalable High-Availability cluster resource manager
results.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2024 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 #ifndef _GNU_SOURCE
13 # define _GNU_SOURCE
14 #endif
15 
16 #include <bzlib.h>
17 #include <errno.h>
18 #include <netdb.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <qb/qbdefs.h>
24 
25 #include <crm/common/mainloop.h>
26 #include <crm/common/xml.h>
27 
28 G_DEFINE_QUARK(pcmk-rc-error-quark, pcmk__rc_error)
29 G_DEFINE_QUARK(pcmk-exitc-error-quark, pcmk__exitc_error)
30 
31 // General (all result code types)
32 
33 
45 int
46 pcmk_result_get_strings(int code, enum pcmk_result_type type, const char **name,
47  const char **desc)
48 {
49  const char *code_name = NULL;
50  const char *code_desc = NULL;
51 
52  switch (type) {
53  case pcmk_result_legacy:
54  code_name = pcmk_errorname(code);
55  code_desc = pcmk_strerror(code);
56  break;
57  case pcmk_result_rc:
58  code_name = pcmk_rc_name(code);
59  code_desc = pcmk_rc_str(code);
60  break;
62  code_name = crm_exit_name(code);
63  code_desc = crm_exit_str((crm_exit_t) code);
64  break;
65  default:
66  return pcmk_rc_undetermined;
67  }
68 
69  if (name != NULL) {
70  *name = code_name;
71  }
72 
73  if (desc != NULL) {
74  *desc = code_desc;
75  }
76  return pcmk_rc_ok;
77 }
78 
95 int
96 pcmk__result_bounds(enum pcmk_result_type type, int *lower, int *upper)
97 {
98  pcmk__assert((lower != NULL) && (upper != NULL));
99 
100  switch (type) {
101  case pcmk_result_legacy:
102  *lower = pcmk_ok;
103  *upper = 256; // should be enough for almost any system error code
104  break;
105  case pcmk_result_rc:
106  *lower = pcmk_rc_error - pcmk__n_rc + 1;
107  *upper = 256;
108  break;
110  *lower = CRM_EX_OK;
111  *upper = CRM_EX_MAX;
112  break;
113  default:
114  *lower = 0;
115  *upper = -1;
116  return pcmk_rc_undetermined;
117  }
118  return pcmk_rc_ok;
119 }
120 
121 // @COMPAT Legacy function return codes
122 
124 const char *
126 {
127  rc = abs(rc);
128  switch (rc) {
129  case pcmk_err_generic: return "pcmk_err_generic";
130  case pcmk_err_no_quorum: return "pcmk_err_no_quorum";
131  case pcmk_err_schema_validation: return "pcmk_err_schema_validation";
132  case pcmk_err_transform_failed: return "pcmk_err_transform_failed";
133  case pcmk_err_old_data: return "pcmk_err_old_data";
134  case pcmk_err_diff_failed: return "pcmk_err_diff_failed";
135  case pcmk_err_diff_resync: return "pcmk_err_diff_resync";
136  case pcmk_err_cib_modified: return "pcmk_err_cib_modified";
137  case pcmk_err_cib_backup: return "pcmk_err_cib_backup";
138  case pcmk_err_cib_save: return "pcmk_err_cib_save";
139  case pcmk_err_cib_corrupt: return "pcmk_err_cib_corrupt";
140  case pcmk_err_multiple: return "pcmk_err_multiple";
141  case pcmk_err_node_unknown: return "pcmk_err_node_unknown";
142  case pcmk_err_already: return "pcmk_err_already";
143  case pcmk_err_bad_nvpair: return "pcmk_err_bad_nvpair";
144  case pcmk_err_unknown_format: return "pcmk_err_unknown_format";
145  default: return pcmk_rc_name(rc); // system errno
146  }
147 }
148 
150 const char *
152 {
153  return pcmk_rc_str(pcmk_legacy2rc(rc));
154 }
155 
156 // Standard Pacemaker API return codes
157 
158 /* This array is used only for nonzero values of pcmk_rc_e. Its values must be
159  * kept in the exact reverse order of the enum value numbering (i.e. add new
160  * values to the end of the array).
161  */
162 static const struct pcmk__rc_info {
163  const char *name;
164  const char *desc;
165  int legacy_rc;
166 } pcmk__rcs[] = {
167  { "pcmk_rc_error",
168  "Error",
170  },
171  { "pcmk_rc_unknown_format",
172  "Unknown output format",
174  },
175  { "pcmk_rc_bad_nvpair",
176  "Bad name/value pair given",
178  },
179  { "pcmk_rc_already",
180  "Already in requested state",
182  },
183  { "pcmk_rc_node_unknown",
184  "Node not found",
186  },
187  { "pcmk_rc_multiple",
188  "Resource active on multiple nodes",
190  },
191  { "pcmk_rc_cib_corrupt",
192  "Could not parse on-disk configuration",
194  },
195  { "pcmk_rc_cib_save",
196  "Could not save new configuration to disk",
198  },
199  { "pcmk_rc_cib_backup",
200  "Could not archive previous configuration",
202  },
203  { "pcmk_rc_cib_modified",
204  "On-disk configuration was manually modified",
206  },
207  { "pcmk_rc_diff_resync",
208  "Application of update diff failed, requesting full refresh",
210  },
211  { "pcmk_rc_diff_failed",
212  "Application of update diff failed",
214  },
215  { "pcmk_rc_old_data",
216  "Update was older than existing configuration",
218  },
219  { "pcmk_rc_transform_failed",
220  "Schema transform failed",
222  },
223  { "pcmk_rc_schema_unchanged",
224  "Schema is already the latest available",
226  },
227  { "pcmk_rc_schema_validation",
228  "Update does not conform to the configured schema",
230  },
231  { "pcmk_rc_no_quorum",
232  "Operation requires quorum",
234  },
235  { "pcmk_rc_ipc_unauthorized",
236  "IPC server is blocked by unauthorized process",
238  },
239  { "pcmk_rc_ipc_unresponsive",
240  "IPC server is unresponsive",
242  },
243  { "pcmk_rc_ipc_pid_only",
244  "IPC server process is active but not accepting connections",
246  },
247  { "pcmk_rc_op_unsatisfied",
248  "Not applicable under current conditions",
250  },
251  { "pcmk_rc_undetermined",
252  "Result undetermined",
254  },
255  { "pcmk_rc_before_range",
256  "Result occurs before given range",
258  },
259  { "pcmk_rc_within_range",
260  "Result occurs within given range",
262  },
263  { "pcmk_rc_after_range",
264  "Result occurs after given range",
266  },
267  { "pcmk_rc_no_output",
268  "Output message produced no output",
270  },
271  { "pcmk_rc_no_input",
272  "Input file not available",
274  },
275  { "pcmk_rc_underflow",
276  "Value too small to be stored in data type",
278  },
279  { "pcmk_rc_dot_error",
280  "Error writing dot(1) file",
282  },
283  { "pcmk_rc_graph_error",
284  "Error writing graph file",
286  },
287  { "pcmk_rc_invalid_transition",
288  "Cluster simulation produced invalid transition",
290  },
291  { "pcmk_rc_unpack_error",
292  "Unable to parse CIB XML",
294  },
295  { "pcmk_rc_duplicate_id",
296  "Two or more XML elements have the same ID",
298  },
299  { "pcmk_rc_disabled",
300  "Disabled",
302  },
303  { "pcmk_rc_bad_input",
304  "Bad input value provided",
306  },
307  { "pcmk_rc_bad_xml_patch",
308  "Bad XML patch format",
310  },
311  { "pcmk_rc_no_transaction",
312  "No active transaction found",
314  },
315  { "pcmk_rc_ns_resolution",
316  "Nameserver resolution error",
318  },
319  { "pcmk_rc_compression",
320  "Compression/decompression error",
322  },
323 };
324 
333 const size_t pcmk__n_rc = PCMK__NELEM(pcmk__rcs);
334 
342 const char *
344 {
345  if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
346  return pcmk__rcs[pcmk_rc_error - rc].name;
347  }
348  switch (rc) {
349  case pcmk_rc_ok: return "pcmk_rc_ok";
350  case E2BIG: return "E2BIG";
351  case EACCES: return "EACCES";
352  case EADDRINUSE: return "EADDRINUSE";
353  case EADDRNOTAVAIL: return "EADDRNOTAVAIL";
354  case EAFNOSUPPORT: return "EAFNOSUPPORT";
355  case EAGAIN: return "EAGAIN";
356  case EALREADY: return "EALREADY";
357  case EBADF: return "EBADF";
358  case EBADMSG: return "EBADMSG";
359  case EBUSY: return "EBUSY";
360  case ECANCELED: return "ECANCELED";
361  case ECHILD: return "ECHILD";
362  case ECOMM: return "ECOMM";
363  case ECONNABORTED: return "ECONNABORTED";
364  case ECONNREFUSED: return "ECONNREFUSED";
365  case ECONNRESET: return "ECONNRESET";
366  /* case EDEADLK: return "EDEADLK"; */
367  case EDESTADDRREQ: return "EDESTADDRREQ";
368  case EDOM: return "EDOM";
369  case EDQUOT: return "EDQUOT";
370  case EEXIST: return "EEXIST";
371  case EFAULT: return "EFAULT";
372  case EFBIG: return "EFBIG";
373  case EHOSTDOWN: return "EHOSTDOWN";
374  case EHOSTUNREACH: return "EHOSTUNREACH";
375  case EIDRM: return "EIDRM";
376  case EILSEQ: return "EILSEQ";
377  case EINPROGRESS: return "EINPROGRESS";
378  case EINTR: return "EINTR";
379  case EINVAL: return "EINVAL";
380  case EIO: return "EIO";
381  case EISCONN: return "EISCONN";
382  case EISDIR: return "EISDIR";
383  case ELIBACC: return "ELIBACC";
384  case ELOOP: return "ELOOP";
385  case EMFILE: return "EMFILE";
386  case EMLINK: return "EMLINK";
387  case EMSGSIZE: return "EMSGSIZE";
388 #ifdef EMULTIHOP // Not available on OpenBSD
389  case EMULTIHOP: return "EMULTIHOP";
390 #endif
391  case ENAMETOOLONG: return "ENAMETOOLONG";
392  case ENETDOWN: return "ENETDOWN";
393  case ENETRESET: return "ENETRESET";
394  case ENETUNREACH: return "ENETUNREACH";
395  case ENFILE: return "ENFILE";
396  case ENOBUFS: return "ENOBUFS";
397  case ENODATA: return "ENODATA";
398  case ENODEV: return "ENODEV";
399  case ENOENT: return "ENOENT";
400  case ENOEXEC: return "ENOEXEC";
401  case ENOKEY: return "ENOKEY";
402  case ENOLCK: return "ENOLCK";
403 #ifdef ENOLINK // Not available on OpenBSD
404  case ENOLINK: return "ENOLINK";
405 #endif
406  case ENOMEM: return "ENOMEM";
407  case ENOMSG: return "ENOMSG";
408  case ENOPROTOOPT: return "ENOPROTOOPT";
409  case ENOSPC: return "ENOSPC";
410 #ifdef ENOSR
411  case ENOSR: return "ENOSR";
412 #endif
413 #ifdef ENOSTR
414  case ENOSTR: return "ENOSTR";
415 #endif
416  case ENOSYS: return "ENOSYS";
417  case ENOTBLK: return "ENOTBLK";
418  case ENOTCONN: return "ENOTCONN";
419  case ENOTDIR: return "ENOTDIR";
420  case ENOTEMPTY: return "ENOTEMPTY";
421  case ENOTSOCK: return "ENOTSOCK";
422 #if ENOTSUP != EOPNOTSUPP
423  case ENOTSUP: return "ENOTSUP";
424 #endif
425  case ENOTTY: return "ENOTTY";
426  case ENOTUNIQ: return "ENOTUNIQ";
427  case ENXIO: return "ENXIO";
428  case EOPNOTSUPP: return "EOPNOTSUPP";
429  case EOVERFLOW: return "EOVERFLOW";
430  case EPERM: return "EPERM";
431  case EPFNOSUPPORT: return "EPFNOSUPPORT";
432  case EPIPE: return "EPIPE";
433  case EPROTO: return "EPROTO";
434  case EPROTONOSUPPORT: return "EPROTONOSUPPORT";
435  case EPROTOTYPE: return "EPROTOTYPE";
436  case ERANGE: return "ERANGE";
437  case EREMOTE: return "EREMOTE";
438  case EREMOTEIO: return "EREMOTEIO";
439  case EROFS: return "EROFS";
440  case ESHUTDOWN: return "ESHUTDOWN";
441  case ESPIPE: return "ESPIPE";
442  case ESOCKTNOSUPPORT: return "ESOCKTNOSUPPORT";
443  case ESRCH: return "ESRCH";
444  case ESTALE: return "ESTALE";
445  case ETIME: return "ETIME";
446  case ETIMEDOUT: return "ETIMEDOUT";
447  case ETXTBSY: return "ETXTBSY";
448 #ifdef EUNATCH
449  case EUNATCH: return "EUNATCH";
450 #endif
451  case EUSERS: return "EUSERS";
452  /* case EWOULDBLOCK: return "EWOULDBLOCK"; */
453  case EXDEV: return "EXDEV";
454 
455 #ifdef EBADE // Not available on OS X
456  case EBADE: return "EBADE";
457  case EBADFD: return "EBADFD";
458  case EBADSLT: return "EBADSLT";
459  case EDEADLOCK: return "EDEADLOCK";
460  case EBADR: return "EBADR";
461  case EBADRQC: return "EBADRQC";
462  case ECHRNG: return "ECHRNG";
463 #ifdef EISNAM // Not available on OS X, Illumos, Solaris
464  case EISNAM: return "EISNAM";
465  case EKEYEXPIRED: return "EKEYEXPIRED";
466  case EKEYREVOKED: return "EKEYREVOKED";
467 #endif
468  case EKEYREJECTED: return "EKEYREJECTED";
469  case EL2HLT: return "EL2HLT";
470  case EL2NSYNC: return "EL2NSYNC";
471  case EL3HLT: return "EL3HLT";
472  case EL3RST: return "EL3RST";
473  case ELIBBAD: return "ELIBBAD";
474  case ELIBMAX: return "ELIBMAX";
475  case ELIBSCN: return "ELIBSCN";
476  case ELIBEXEC: return "ELIBEXEC";
477 #ifdef ENOMEDIUM // Not available on OS X, Illumos, Solaris
478  case ENOMEDIUM: return "ENOMEDIUM";
479  case EMEDIUMTYPE: return "EMEDIUMTYPE";
480 #endif
481  case ENONET: return "ENONET";
482  case ENOPKG: return "ENOPKG";
483  case EREMCHG: return "EREMCHG";
484  case ERESTART: return "ERESTART";
485  case ESTRPIPE: return "ESTRPIPE";
486 #ifdef EUCLEAN // Not available on OS X, Illumos, Solaris
487  case EUCLEAN: return "EUCLEAN";
488 #endif
489  case EXFULL: return "EXFULL";
490 #endif // EBADE
491  default: return "Unknown";
492  }
493 }
494 
502 const char *
503 pcmk_rc_str(int rc)
504 {
505  if (rc == pcmk_rc_ok) {
506  return "OK";
507  }
508  if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
509  return pcmk__rcs[pcmk_rc_error - rc].desc;
510  }
511  if (rc < 0) {
512  return "Error";
513  }
514 
515  // Handle values that could be defined by system or by portability.h
516  switch (rc) {
517 #ifdef PCMK__ENOTUNIQ
518  case ENOTUNIQ: return "Name not unique on network";
519 #endif
520 #ifdef PCMK__ECOMM
521  case ECOMM: return "Communication error on send";
522 #endif
523 #ifdef PCMK__ELIBACC
524  case ELIBACC: return "Can not access a needed shared library";
525 #endif
526 #ifdef PCMK__EREMOTEIO
527  case EREMOTEIO: return "Remote I/O error";
528 #endif
529 #ifdef PCMK__ENOKEY
530  case ENOKEY: return "Required key not available";
531 #endif
532 #ifdef PCMK__ENODATA
533  case ENODATA: return "No data available";
534 #endif
535 #ifdef PCMK__ETIME
536  case ETIME: return "Timer expired";
537 #endif
538 #ifdef PCMK__EKEYREJECTED
539  case EKEYREJECTED: return "Key was rejected by service";
540 #endif
541  default: return strerror(rc);
542  }
543 }
544 
545 // This returns negative values for errors
547 int
549 {
550  if (rc >= 0) {
551  return -rc; // OK or system errno
552  }
553  if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
554  return pcmk__rcs[pcmk_rc_error - rc].legacy_rc;
555  }
556  return -pcmk_err_generic;
557 }
558 
560 int
561 pcmk_legacy2rc(int legacy_rc)
562 {
563  legacy_rc = abs(legacy_rc);
564  switch (legacy_rc) {
569  case pcmk_err_old_data: return pcmk_rc_old_data;
574  case pcmk_err_cib_save: return pcmk_rc_cib_save;
576  case pcmk_err_multiple: return pcmk_rc_multiple;
578  case pcmk_err_already: return pcmk_rc_already;
581  case pcmk_err_generic: return pcmk_rc_error;
582  case pcmk_ok: return pcmk_rc_ok;
583  default: return legacy_rc; // system errno
584  }
585 }
586 
587 // Exit status codes
588 
589 const char *
591 {
592  switch (exit_code) {
593  case CRM_EX_OK: return "CRM_EX_OK";
594  case CRM_EX_ERROR: return "CRM_EX_ERROR";
595  case CRM_EX_INVALID_PARAM: return "CRM_EX_INVALID_PARAM";
596  case CRM_EX_UNIMPLEMENT_FEATURE: return "CRM_EX_UNIMPLEMENT_FEATURE";
597  case CRM_EX_INSUFFICIENT_PRIV: return "CRM_EX_INSUFFICIENT_PRIV";
598  case CRM_EX_NOT_INSTALLED: return "CRM_EX_NOT_INSTALLED";
599  case CRM_EX_NOT_CONFIGURED: return "CRM_EX_NOT_CONFIGURED";
600  case CRM_EX_NOT_RUNNING: return "CRM_EX_NOT_RUNNING";
601  case CRM_EX_PROMOTED: return "CRM_EX_PROMOTED";
602  case CRM_EX_FAILED_PROMOTED: return "CRM_EX_FAILED_PROMOTED";
603  case CRM_EX_USAGE: return "CRM_EX_USAGE";
604  case CRM_EX_DATAERR: return "CRM_EX_DATAERR";
605  case CRM_EX_NOINPUT: return "CRM_EX_NOINPUT";
606  case CRM_EX_NOUSER: return "CRM_EX_NOUSER";
607  case CRM_EX_NOHOST: return "CRM_EX_NOHOST";
608  case CRM_EX_UNAVAILABLE: return "CRM_EX_UNAVAILABLE";
609  case CRM_EX_SOFTWARE: return "CRM_EX_SOFTWARE";
610  case CRM_EX_OSERR: return "CRM_EX_OSERR";
611  case CRM_EX_OSFILE: return "CRM_EX_OSFILE";
612  case CRM_EX_CANTCREAT: return "CRM_EX_CANTCREAT";
613  case CRM_EX_IOERR: return "CRM_EX_IOERR";
614  case CRM_EX_TEMPFAIL: return "CRM_EX_TEMPFAIL";
615  case CRM_EX_PROTOCOL: return "CRM_EX_PROTOCOL";
616  case CRM_EX_NOPERM: return "CRM_EX_NOPERM";
617  case CRM_EX_CONFIG: return "CRM_EX_CONFIG";
618  case CRM_EX_FATAL: return "CRM_EX_FATAL";
619  case CRM_EX_PANIC: return "CRM_EX_PANIC";
620  case CRM_EX_DISCONNECT: return "CRM_EX_DISCONNECT";
621  case CRM_EX_DIGEST: return "CRM_EX_DIGEST";
622  case CRM_EX_NOSUCH: return "CRM_EX_NOSUCH";
623  case CRM_EX_QUORUM: return "CRM_EX_QUORUM";
624  case CRM_EX_UNSAFE: return "CRM_EX_UNSAFE";
625  case CRM_EX_EXISTS: return "CRM_EX_EXISTS";
626  case CRM_EX_MULTIPLE: return "CRM_EX_MULTIPLE";
627  case CRM_EX_EXPIRED: return "CRM_EX_EXPIRED";
628  case CRM_EX_NOT_YET_IN_EFFECT: return "CRM_EX_NOT_YET_IN_EFFECT";
629  case CRM_EX_INDETERMINATE: return "CRM_EX_INDETERMINATE";
630  case CRM_EX_UNSATISFIED: return "CRM_EX_UNSATISFIED";
631  case CRM_EX_OLD: return "CRM_EX_OLD";
632  case CRM_EX_TIMEOUT: return "CRM_EX_TIMEOUT";
633  case CRM_EX_DEGRADED: return "CRM_EX_DEGRADED";
634  case CRM_EX_DEGRADED_PROMOTED: return "CRM_EX_DEGRADED_PROMOTED";
635  case CRM_EX_NONE: return "CRM_EX_NONE";
636  case CRM_EX_MAX: return "CRM_EX_UNKNOWN";
637  }
638  return "CRM_EX_UNKNOWN";
639 }
640 
641 const char *
643 {
644  switch (exit_code) {
645  case CRM_EX_OK: return "OK";
646  case CRM_EX_ERROR: return "Error occurred";
647  case CRM_EX_INVALID_PARAM: return "Invalid parameter";
648  case CRM_EX_UNIMPLEMENT_FEATURE: return "Unimplemented";
649  case CRM_EX_INSUFFICIENT_PRIV: return "Insufficient privileges";
650  case CRM_EX_NOT_INSTALLED: return "Not installed";
651  case CRM_EX_NOT_CONFIGURED: return "Not configured";
652  case CRM_EX_NOT_RUNNING: return "Not running";
653  case CRM_EX_PROMOTED: return "Promoted";
654  case CRM_EX_FAILED_PROMOTED: return "Failed in promoted role";
655  case CRM_EX_USAGE: return "Incorrect usage";
656  case CRM_EX_DATAERR: return "Invalid data given";
657  case CRM_EX_NOINPUT: return "Input file not available";
658  case CRM_EX_NOUSER: return "User does not exist";
659  case CRM_EX_NOHOST: return "Host does not exist";
660  case CRM_EX_UNAVAILABLE: return "Necessary service unavailable";
661  case CRM_EX_SOFTWARE: return "Internal software bug";
662  case CRM_EX_OSERR: return "Operating system error occurred";
663  case CRM_EX_OSFILE: return "System file not available";
664  case CRM_EX_CANTCREAT: return "Cannot create output file";
665  case CRM_EX_IOERR: return "I/O error occurred";
666  case CRM_EX_TEMPFAIL: return "Temporary failure, try again";
667  case CRM_EX_PROTOCOL: return "Protocol violated";
668  case CRM_EX_NOPERM: return "Insufficient privileges";
669  case CRM_EX_CONFIG: return "Invalid configuration";
670  case CRM_EX_FATAL: return "Fatal error occurred, will not respawn";
671  case CRM_EX_PANIC: return "System panic required";
672  case CRM_EX_DISCONNECT: return "Not connected";
673  case CRM_EX_DIGEST: return "Digest mismatch";
674  case CRM_EX_NOSUCH: return "No such object";
675  case CRM_EX_QUORUM: return "Quorum required";
676  case CRM_EX_UNSAFE: return "Operation not safe";
677  case CRM_EX_EXISTS: return "Requested item already exists";
678  case CRM_EX_MULTIPLE: return "Multiple items match request";
679  case CRM_EX_EXPIRED: return "Requested item has expired";
680  case CRM_EX_NOT_YET_IN_EFFECT: return "Requested item is not yet in effect";
681  case CRM_EX_INDETERMINATE: return "Could not determine status";
682  case CRM_EX_UNSATISFIED: return "Not applicable under current conditions";
683  case CRM_EX_OLD: return "Update was older than existing configuration";
684  case CRM_EX_TIMEOUT: return "Timeout occurred";
685  case CRM_EX_DEGRADED: return "Service is active but might fail soon";
686  case CRM_EX_DEGRADED_PROMOTED: return "Service is promoted but might fail soon";
687  case CRM_EX_NONE: return "No exit status available";
688  case CRM_EX_MAX: return "Error occurred";
689  }
690  if ((exit_code > 128) && (exit_code < CRM_EX_MAX)) {
691  return "Interrupted by signal";
692  }
693  return "Unknown exit status";
694 }
695 
705 {
706  switch (rc) {
707  case pcmk_rc_ok:
708  case pcmk_rc_no_output: // quiet mode, or nothing to output
709  return CRM_EX_OK;
710 
711  case pcmk_rc_no_quorum:
712  return CRM_EX_QUORUM;
713 
714  case pcmk_rc_old_data:
715  return CRM_EX_OLD;
716 
720  return CRM_EX_CONFIG;
721 
722  case pcmk_rc_bad_nvpair:
723  return CRM_EX_INVALID_PARAM;
724 
725  case EACCES:
727 
728  case EBADF:
729  case EINVAL:
730  case EFAULT:
731  case ENOSYS:
732  case EOVERFLOW:
733  case pcmk_rc_underflow:
734  case pcmk_rc_compression:
735  return CRM_EX_SOFTWARE;
736 
737  case EBADMSG:
738  case EMSGSIZE:
739  case ENOMSG:
740  case ENOPROTOOPT:
741  case EPROTO:
742  case EPROTONOSUPPORT:
743  case EPROTOTYPE:
744  return CRM_EX_PROTOCOL;
745 
746  case ECOMM:
747  case ENOMEM:
748  return CRM_EX_OSERR;
749 
750  case ECONNABORTED:
751  case ECONNREFUSED:
752  case ECONNRESET:
753  case ENOTCONN:
754  return CRM_EX_DISCONNECT;
755 
756  case EEXIST:
757  case pcmk_rc_already:
758  return CRM_EX_EXISTS;
759 
760  case EIO:
761  case pcmk_rc_dot_error:
762  case pcmk_rc_graph_error:
763  return CRM_EX_IOERR;
764 
765  case ENOTSUP:
766 #if EOPNOTSUPP != ENOTSUP
767  case EOPNOTSUPP:
768 #endif
770 
771  case ENOTUNIQ:
772  case pcmk_rc_multiple:
773  return CRM_EX_MULTIPLE;
774 
775  case ENODEV:
776  case ENOENT:
777  case ENXIO:
780  return CRM_EX_NOSUCH;
781 
784  return CRM_EX_NOHOST;
785 
786  case ETIME:
787  case ETIMEDOUT:
788  return CRM_EX_TIMEOUT;
789 
790  case EAGAIN:
791  case EBUSY:
792  return CRM_EX_UNSATISFIED;
793 
796 
797  case pcmk_rc_after_range:
798  return CRM_EX_EXPIRED;
799 
801  return CRM_EX_INDETERMINATE;
802 
804  return CRM_EX_UNSATISFIED;
805 
807  return CRM_EX_OK;
808 
809  case pcmk_rc_no_input:
810  return CRM_EX_NOINPUT;
811 
813  return CRM_EX_MULTIPLE;
814 
815  case pcmk_rc_bad_input:
817  return CRM_EX_DATAERR;
818 
819  default:
820  return CRM_EX_ERROR;
821  }
822 }
823 
831 enum ocf_exitcode
832 pcmk_rc2ocf(int rc)
833 {
834  switch (rc) {
835  case pcmk_rc_ok:
836  return PCMK_OCF_OK;
837 
838  case pcmk_rc_bad_nvpair:
839  return PCMK_OCF_INVALID_PARAM;
840 
841  case EACCES:
843 
844  case ENOTSUP:
845 #if EOPNOTSUPP != ENOTSUP
846  case EOPNOTSUPP:
847 #endif
849 
850  default:
851  return PCMK_OCF_UNKNOWN_ERROR;
852  }
853 }
854 
855 
856 // Other functions
857 
866 int
868 {
869  switch (gai) {
870  case 0:
871  return pcmk_rc_ok;
872 
873  case EAI_AGAIN:
874  return EAGAIN;
875 
876  case EAI_BADFLAGS:
877  case EAI_SERVICE:
878  return EINVAL;
879 
880  case EAI_FAMILY:
881  return EAFNOSUPPORT;
882 
883  case EAI_MEMORY:
884  return ENOMEM;
885 
886  case EAI_NONAME:
887  return pcmk_rc_node_unknown;
888 
889  case EAI_SOCKTYPE:
890  return ESOCKTNOSUPPORT;
891 
892  case EAI_SYSTEM:
893  return errno;
894 
895  default:
896  return pcmk_rc_ns_resolution;
897  }
898 }
899 
907 int
909 {
910  switch (bz2) {
911  case BZ_OK:
912  case BZ_RUN_OK:
913  case BZ_FLUSH_OK:
914  case BZ_FINISH_OK:
915  case BZ_STREAM_END:
916  return pcmk_rc_ok;
917 
918  case BZ_MEM_ERROR:
919  return ENOMEM;
920 
921  case BZ_DATA_ERROR:
922  case BZ_DATA_ERROR_MAGIC:
923  case BZ_UNEXPECTED_EOF:
924  return pcmk_rc_bad_input;
925 
926  case BZ_IO_ERROR:
927  return EIO;
928 
929  case BZ_OUTBUFF_FULL:
930  return EFBIG;
931 
932  default:
933  return pcmk_rc_compression;
934  }
935 }
936 
939 {
940  /* A compiler could theoretically use any type for crm_exit_t, but an int
941  * should always hold it, so cast to int to keep static analysis happy.
942  */
943  if ((((int) rc) < 0) || (((int) rc) > CRM_EX_MAX)) {
944  rc = CRM_EX_ERROR;
945  }
946 
948  crm_xml_cleanup();
949 
950  free(pcmk__our_nodename);
951 
952  if (crm_system_name) {
953  crm_info("Exiting %s " CRM_XS " with status %d", crm_system_name, rc);
954  free(crm_system_name);
955  } else {
956  crm_trace("Exiting with status %d", rc);
957  }
959  qb_log_fini(); // Don't log anything after this point
960 
961  exit(rc);
962 }
963 
964 /*
965  * External action results
966  */
967 
977 void
979  enum pcmk_exec_status exec_status, const char *exit_reason)
980 {
981  if (result == NULL) {
982  return;
983  }
984 
985  result->exit_status = exit_status;
986  result->execution_status = exec_status;
987 
988  if (!pcmk__str_eq(result->exit_reason, exit_reason, pcmk__str_none)) {
989  free(result->exit_reason);
990  result->exit_reason = (exit_reason == NULL)? NULL : strdup(exit_reason);
991  }
992 }
993 
994 
1006 G_GNUC_PRINTF(4, 5)
1007 void
1009  enum pcmk_exec_status exec_status,
1010  const char *format, ...)
1011 {
1012  va_list ap;
1013  int len = 0;
1014  char *reason = NULL;
1015 
1016  if (result == NULL) {
1017  return;
1018  }
1019 
1020  result->exit_status = exit_status;
1021  result->execution_status = exec_status;
1022 
1023  if (format != NULL) {
1024  va_start(ap, format);
1025  len = vasprintf(&reason, format, ap);
1026  pcmk__assert(len > 0);
1027  va_end(ap);
1028  }
1029  free(result->exit_reason);
1030  result->exit_reason = reason;
1031 }
1032 
1046 void
1048 {
1049  if (result == NULL) {
1050  return;
1051  }
1052 
1053  free(result->action_stdout);
1054  result->action_stdout = out;
1055 
1056  free(result->action_stderr);
1057  result->action_stderr = err;
1058 }
1059 
1066 void
1068 {
1069  if (result == NULL) {
1070  return;
1071  }
1072 
1073  free(result->exit_reason);
1074  result->exit_reason = NULL;
1075 
1076  free(result->action_stdout);
1077  result->action_stdout = NULL;
1078 
1079  free(result->action_stderr);
1080  result->action_stderr = NULL;
1081 }
1082 
1090 void
1092 {
1093  CRM_CHECK((src != NULL) && (dst != NULL), return);
1094  dst->exit_status = src->exit_status;
1095  dst->execution_status = src->execution_status;
1096  dst->exit_reason = pcmk__str_copy(src->exit_reason);
1099 }
1100 
1110 static void
1111 log_assertion_as(const char *file, const char *function, int line,
1112  const char *assert_condition)
1113 {
1114  if (!pcmk__is_daemon) {
1115  crm_enable_stderr(TRUE); // Make sure command-line user sees message
1116  }
1117  crm_err("%s: Triggered fatal assertion at %s:%d : %s",
1118  function, file, line, assert_condition);
1119 }
1120 
1121 /* coverity[+kill] */
1133 _Noreturn void
1134 pcmk__abort_as(const char *file, const char *function, int line,
1135  const char *assert_condition)
1136 {
1137  log_assertion_as(file, function, line, assert_condition);
1138  abort();
1139 }
1140 
1141 /* coverity[+kill] */
1154 static void
1155 fail_assert_as(const char *file, const char *function, int line,
1156  const char *assert_condition)
1157 {
1158  int status = 0;
1159  pid_t pid = 0;
1160 
1161  if (!pcmk__is_daemon) {
1162  pcmk__abort_as(file, function, line, assert_condition); // No return
1163  }
1164 
1165  pid = fork();
1166  switch (pid) {
1167  case -1: // Fork failed
1168  crm_warn("%s: Cannot dump core for non-fatal assertion at %s:%d "
1169  ": %s", function, file, line, assert_condition);
1170  break;
1171 
1172  case 0: // Child process: just abort to dump core
1173  abort();
1174  break;
1175 
1176  default: // Parent process: wait for child
1177  crm_err("%s: Forked child [%d] to record non-fatal assertion at "
1178  "%s:%d : %s", function, pid, file, line, assert_condition);
1179  crm_write_blackbox(SIGTRAP, NULL);
1180  do {
1181  if (waitpid(pid, &status, 0) == pid) {
1182  return; // Child finished dumping core
1183  }
1184  } while (errno == EINTR);
1185  if (errno == ECHILD) {
1186  // crm_mon ignores SIGCHLD
1187  crm_trace("Cannot wait on forked child [%d] "
1188  "(SIGCHLD is probably ignored)", pid);
1189  } else {
1190  crm_err("Cannot wait on forked child [%d]: %s",
1191  pid, pcmk_rc_str(errno));
1192  }
1193  break;
1194  }
1195 }
1196 
1197 /* coverity[+kill] */
1198 void
1199 crm_abort(const char *file, const char *function, int line,
1200  const char *assert_condition, gboolean do_core, gboolean do_fork)
1201 {
1202  if (!do_fork) {
1203  pcmk__abort_as(file, function, line, assert_condition); // No return
1204  } else if (do_core) {
1205  fail_assert_as(file, function, line, assert_condition);
1206  } else {
1207  log_assertion_as(file, function, line, assert_condition);
1208  }
1209 }
1210 
1211 // Deprecated functions kept only for backward API compatibility
1212 // LCOV_EXCL_START
1213 
1214 #include <crm/common/results_compat.h>
1215 
1216 const char *
1218 {
1219  // See ftp://sources.redhat.com/pub/bzip2/docs/manual_3.html#SEC17
1220  switch (rc) {
1221  case BZ_OK:
1222  case BZ_RUN_OK:
1223  case BZ_FLUSH_OK:
1224  case BZ_FINISH_OK:
1225  case BZ_STREAM_END:
1226  return "Ok";
1227  case BZ_CONFIG_ERROR:
1228  return "libbz2 has been improperly compiled on your platform";
1229  case BZ_SEQUENCE_ERROR:
1230  return "library functions called in the wrong order";
1231  case BZ_PARAM_ERROR:
1232  return "parameter is out of range or otherwise incorrect";
1233  case BZ_MEM_ERROR:
1234  return "memory allocation failed";
1235  case BZ_DATA_ERROR:
1236  return "data integrity error is detected during decompression";
1237  case BZ_DATA_ERROR_MAGIC:
1238  return "the compressed stream does not start with the correct magic bytes";
1239  case BZ_IO_ERROR:
1240  return "error reading or writing in the compressed file";
1241  case BZ_UNEXPECTED_EOF:
1242  return "compressed file finishes before the logical end of stream is detected";
1243  case BZ_OUTBUFF_FULL:
1244  return "output data will not fit into the buffer provided";
1245  }
1246  return "Data compression error";
1247 }
1248 
1249 crm_exit_t
1251 {
1252  return pcmk_rc2exitc(pcmk_legacy2rc(rc));
1253 }
1254 
1255 // LCOV_EXCL_STOP
1256 // End deprecated API
#define pcmk_err_old_data
Definition: results.h:73
const char * bz2_strerror(int rc)
Definition: results.c:1217
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:245
User does not exist.
Definition: results.h:268
#define pcmk_err_schema_validation
Definition: results.h:71
ocf_exitcode
Exit status codes for resource agents.
Definition: results.h:173
#define pcmk_err_already
Definition: results.h:88
Internal software bug.
Definition: results.h:271
#define ETIME
Definition: portability.h:111
crm_exit_t pcmk_rc2exitc(int rc)
Map a function return code to the most similar exit code.
Definition: results.c:704
void crm_enable_stderr(int enable)
Definition: logging.c:1042
#define pcmk_err_no_quorum
Definition: results.h:70
#define pcmk_err_schema_unchanged
Definition: results.h:84
Requested item does not exist.
Definition: results.h:287
crm_exit_t crm_errno2exit(int rc)
Definition: results.c:1250
Dependencies not available locally.
Definition: results.h:258
int pcmk__result_bounds(enum pcmk_result_type type, int *lower, int *upper)
Definition: results.c:96
const char * name
Definition: cib.c:26
const char * crm_exit_name(crm_exit_t exit_code)
Definition: results.c:590
int pcmk_rc2legacy(int rc)
Definition: results.c:548
Update older than existing config.
Definition: results.h:285
Could not determine status.
Definition: results.h:294
Service active and promoted.
Definition: results.h:261
void crm_xml_cleanup(void)
Definition: xml.c:2161
#define EKEYREJECTED
Definition: portability.h:116
Service promoted but more likely to fail soon.
Definition: results.h:307
#define pcmk_err_transform_failed
Definition: results.h:72
#define EREMOTEIO
Definition: portability.h:96
enum pcmk_exec_status execution_status
Unspecified error.
Definition: results.h:252
#define pcmk_err_node_unknown
Definition: results.h:87
Panic the local host.
Definition: results.h:283
#define pcmk_err_generic
Definition: results.h:69
void mainloop_cleanup(void)
Definition: mainloop.c:420
char * crm_system_name
Definition: utils.c:48
Requested item does not satisfy constraints.
Definition: results.h:295
enum crm_exit_e crm_exit_t
Command line usage error.
Definition: results.h:265
enum crm_ais_msg_types type
Definition: cpg.c:51
int pcmk__gaierror2rc(int gai)
Map a getaddrinfo() return code to the most similar Pacemaker return code.
Definition: results.c:867
Ensure crm_exit_t can hold this.
Definition: results.h:316
#define _Noreturn
Definition: config.h:667
#define pcmk_err_cib_backup
Definition: results.h:82
void pcmk__free_common_logger(void)
Definition: logging.c:1251
Non-file permission issue.
Definition: results.h:278
Wrappers for and extensions to glib mainloop.
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition: results.c:503
enum ocf_exitcode pcmk_rc2ocf(int rc)
Map a function return code to the most similar OCF exit code.
Definition: results.c:832
File I/O error.
Definition: results.h:275
Try again.
Definition: results.h:276
void pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
Definition: results.c:1047
#define crm_warn(fmt, args...)
Definition: logging.h:394
#define pcmk_err_cib_save
Definition: results.h:83
#define pcmk_err_diff_failed
Definition: results.h:76
Protocol violated.
Definition: results.h:277
User-supplied data incorrect.
Definition: results.h:266
Host unknown.
Definition: results.h:269
uint32_t pid
Definition: cpg.c:49
Requested item has multiple matches.
Definition: results.h:291
int pcmk_legacy2rc(int legacy_rc)
Definition: results.c:561
void pcmk__copy_result(const pcmk__action_result_t *src, pcmk__action_result_t *dst)
Definition: results.c:1091
#define pcmk_err_multiple
Definition: results.h:86
Requested action not implemented.
Definition: results.h:256
const size_t pcmk__n_rc
Definition: results.c:333
Parameter invalid (in local context)
Definition: results.h:179
const char * crm_exit_str(crm_exit_t exit_code)
Definition: results.c:642
Input file not available.
Definition: results.h:267
crm_exit_t crm_exit(crm_exit_t rc)
Definition: results.c:938
External (OS/environmental) problem.
Definition: results.h:272
#define crm_trace(fmt, args...)
Definition: logging.h:404
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:46
Insufficient privileges.
Definition: results.h:181
bool pcmk__is_daemon
Definition: logging.c:47
Wrappers for and extensions to libxml2.
#define PCMK__NELEM(a)
Definition: internal.h:48
Service failed and possibly promoted.
Definition: results.h:262
#define ECOMM
Definition: portability.h:86
Success.
Definition: results.h:251
#define pcmk_err_cib_modified
Definition: results.h:81
System file not usable.
Definition: results.h:273
void crm_abort(const char *file, const char *function, int line, const char *assert_condition, gboolean do_core, gboolean do_fork)
Definition: results.c:1199
Service active but more likely to fail soon.
Definition: results.h:306
#define pcmk__str_copy(str)
Service safely stopped.
Definition: results.h:260
void crm_write_blackbox(int nsig, const struct qb_log_callsite *callsite)
Definition: logging.c:505
Requested item has expired.
Definition: results.h:292
#define ENOKEY
Definition: portability.h:101
Unspecified error.
Definition: results.h:177
#define pcmk__assert(expr)
void pcmk__reset_result(pcmk__action_result_t *result)
Definition: results.c:1067
#define CRM_XS
Definition: logging.h:56
#define ELIBACC
Definition: portability.h:91
Misconfiguration.
Definition: results.h:279
Requested action not implemented.
Definition: results.h:180
Legacy API function return code.
Definition: results.h:361
void pcmk__format_result(pcmk__action_result_t *result, int exit_status, enum pcmk_exec_status exec_status, const char *format,...)
Definition: results.c:1008
Exit status code.
Definition: results.h:363
Requires –force or new conditions.
Definition: results.h:289
#define ENODATA
Definition: portability.h:106
_Noreturn void pcmk__abort_as(const char *file, const char *function, int line, const char *assert_condition)
Definition: results.c:1134
#define pcmk_err_diff_resync
Definition: results.h:79
pcmk__action_result_t result
Definition: pcmk_fence.c:35
Insufficient privileges.
Definition: results.h:257
#define crm_err(fmt, args...)
Definition: logging.h:391
char * pcmk__our_nodename
Node name of the local node.
Definition: logging.c:48
#define pcmk_err_unknown_format
Definition: results.h:95
Success.
Definition: results.h:174
#define ENOTUNIQ
Definition: portability.h:81
Needed service unavailable.
Definition: results.h:270
File couldn&#39;t be created.
Definition: results.h:274
const char * pcmk_rc_name(int rc)
Get a return code constant name as a string.
Definition: results.c:343
Local partition does not have quorum.
Definition: results.h:288
Lost connection to something.
Definition: results.h:284
Requested item is not in effect.
Definition: results.h:293
Standard Pacemaker return code.
Definition: results.h:362
No exit status available.
Definition: results.h:314
#define pcmk_ok
Definition: results.h:65
Deprecated Pacemaker results API.
Digest comparison failed.
Definition: results.h:286
pcmk_exec_status
Execution status.
Definition: results.h:326
Parameter invalid (in local context)
Definition: results.h:255
int pcmk__bzlib2rc(int bz2)
Map a bz2 return code to the most similar Pacemaker return code.
Definition: results.c:908
Convention from timeout(1)
Definition: results.h:298
const char * pcmk_strerror(int rc)
Definition: results.c:151
#define pcmk_err_bad_nvpair
Definition: results.h:94
#define pcmk_err_cib_corrupt
Definition: results.h:85
Requested item already exists.
Definition: results.h:290
#define crm_info(fmt, args...)
Definition: logging.h:399
Do not respawn.
Definition: results.h:282
Parameter invalid (inherently)
Definition: results.h:259
const char * pcmk_errorname(int rc)
Definition: results.c:125
pcmk_result_type
Types of Pacemaker result codes.
Definition: results.h:360
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:978