pacemaker  3.0.0-d8340737c4
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 #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 // General (all result code types)
28 
29 
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;
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 
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; // 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;
112  return pcmk_rc_undetermined;
113  }
114  return pcmk_rc_ok;
115 }
116 
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); // 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
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 /* coverity[+kill] */
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); // 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] */
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); // 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 
230 const 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 
256 const 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  */
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",
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 };
430 
439 const size_t pcmk__n_rc = PCMK__NELEM(pcmk__rcs);
440 
448 const char *
450 {
451  if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
452  return pcmk__rcs[pcmk_rc_error - rc].name;
453  }
454  switch (rc) {
455  case pcmk_rc_ok: return "pcmk_rc_ok";
456  case E2BIG: return "E2BIG";
457  case EACCES: return "EACCES";
458  case EADDRINUSE: return "EADDRINUSE";
459  case EADDRNOTAVAIL: return "EADDRNOTAVAIL";
460  case EAFNOSUPPORT: return "EAFNOSUPPORT";
461  case EAGAIN: return "EAGAIN";
462  case EALREADY: return "EALREADY";
463  case EBADF: return "EBADF";
464  case EBADMSG: return "EBADMSG";
465  case EBUSY: return "EBUSY";
466  case ECANCELED: return "ECANCELED";
467  case ECHILD: return "ECHILD";
468  case ECOMM: return "ECOMM";
469  case ECONNABORTED: return "ECONNABORTED";
470  case ECONNREFUSED: return "ECONNREFUSED";
471  case ECONNRESET: return "ECONNRESET";
472  /* case EDEADLK: return "EDEADLK"; */
473  case EDESTADDRREQ: return "EDESTADDRREQ";
474  case EDOM: return "EDOM";
475  case EDQUOT: return "EDQUOT";
476  case EEXIST: return "EEXIST";
477  case EFAULT: return "EFAULT";
478  case EFBIG: return "EFBIG";
479  case EHOSTDOWN: return "EHOSTDOWN";
480  case EHOSTUNREACH: return "EHOSTUNREACH";
481  case EIDRM: return "EIDRM";
482  case EILSEQ: return "EILSEQ";
483  case EINPROGRESS: return "EINPROGRESS";
484  case EINTR: return "EINTR";
485  case EINVAL: return "EINVAL";
486  case EIO: return "EIO";
487  case EISCONN: return "EISCONN";
488  case EISDIR: return "EISDIR";
489  case ELIBACC: return "ELIBACC";
490  case ELOOP: return "ELOOP";
491  case EMFILE: return "EMFILE";
492  case EMLINK: return "EMLINK";
493  case EMSGSIZE: return "EMSGSIZE";
494 #ifdef EMULTIHOP // Not available on OpenBSD
495  case EMULTIHOP: return "EMULTIHOP";
496 #endif
497  case ENAMETOOLONG: return "ENAMETOOLONG";
498  case ENETDOWN: return "ENETDOWN";
499  case ENETRESET: return "ENETRESET";
500  case ENETUNREACH: return "ENETUNREACH";
501  case ENFILE: return "ENFILE";
502  case ENOBUFS: return "ENOBUFS";
503  case ENODATA: return "ENODATA";
504  case ENODEV: return "ENODEV";
505  case ENOENT: return "ENOENT";
506  case ENOEXEC: return "ENOEXEC";
507  case ENOKEY: return "ENOKEY";
508  case ENOLCK: return "ENOLCK";
509 #ifdef ENOLINK // Not available on OpenBSD
510  case ENOLINK: return "ENOLINK";
511 #endif
512  case ENOMEM: return "ENOMEM";
513  case ENOMSG: return "ENOMSG";
514  case ENOPROTOOPT: return "ENOPROTOOPT";
515  case ENOSPC: return "ENOSPC";
516 #ifdef ENOSR
517  case ENOSR: return "ENOSR";
518 #endif
519 #ifdef ENOSTR
520  case ENOSTR: return "ENOSTR";
521 #endif
522  case ENOSYS: return "ENOSYS";
523  case ENOTBLK: return "ENOTBLK";
524  case ENOTCONN: return "ENOTCONN";
525  case ENOTDIR: return "ENOTDIR";
526  case ENOTEMPTY: return "ENOTEMPTY";
527  case ENOTSOCK: return "ENOTSOCK";
528 #if ENOTSUP != EOPNOTSUPP
529  case ENOTSUP: return "ENOTSUP";
530 #endif
531  case ENOTTY: return "ENOTTY";
532  case ENOTUNIQ: return "ENOTUNIQ";
533  case ENXIO: return "ENXIO";
534  case EOPNOTSUPP: return "EOPNOTSUPP";
535  case EOVERFLOW: return "EOVERFLOW";
536  case EPERM: return "EPERM";
537  case EPFNOSUPPORT: return "EPFNOSUPPORT";
538  case EPIPE: return "EPIPE";
539  case EPROTO: return "EPROTO";
540  case EPROTONOSUPPORT: return "EPROTONOSUPPORT";
541  case EPROTOTYPE: return "EPROTOTYPE";
542  case ERANGE: return "ERANGE";
543  case EREMOTE: return "EREMOTE";
544  case EREMOTEIO: return "EREMOTEIO";
545  case EROFS: return "EROFS";
546  case ESHUTDOWN: return "ESHUTDOWN";
547  case ESPIPE: return "ESPIPE";
548  case ESOCKTNOSUPPORT: return "ESOCKTNOSUPPORT";
549  case ESRCH: return "ESRCH";
550  case ESTALE: return "ESTALE";
551  case ETIME: return "ETIME";
552  case ETIMEDOUT: return "ETIMEDOUT";
553  case ETXTBSY: return "ETXTBSY";
554 #ifdef EUNATCH
555  case EUNATCH: return "EUNATCH";
556 #endif
557  case EUSERS: return "EUSERS";
558  /* case EWOULDBLOCK: return "EWOULDBLOCK"; */
559  case EXDEV: return "EXDEV";
560 
561 #ifdef EBADE // Not available on OS X
562  case EBADE: return "EBADE";
563  case EBADFD: return "EBADFD";
564  case EBADSLT: return "EBADSLT";
565  case EDEADLOCK: return "EDEADLOCK";
566  case EBADR: return "EBADR";
567  case EBADRQC: return "EBADRQC";
568  case ECHRNG: return "ECHRNG";
569 #ifdef EISNAM // Not available on OS X, Illumos, Solaris
570  case EISNAM: return "EISNAM";
571  case EKEYEXPIRED: return "EKEYEXPIRED";
572  case EKEYREVOKED: return "EKEYREVOKED";
573 #endif
574  case EKEYREJECTED: return "EKEYREJECTED";
575  case EL2HLT: return "EL2HLT";
576  case EL2NSYNC: return "EL2NSYNC";
577  case EL3HLT: return "EL3HLT";
578  case EL3RST: return "EL3RST";
579  case ELIBBAD: return "ELIBBAD";
580  case ELIBMAX: return "ELIBMAX";
581  case ELIBSCN: return "ELIBSCN";
582  case ELIBEXEC: return "ELIBEXEC";
583 #ifdef ENOMEDIUM // Not available on OS X, Illumos, Solaris
584  case ENOMEDIUM: return "ENOMEDIUM";
585  case EMEDIUMTYPE: return "EMEDIUMTYPE";
586 #endif
587  case ENONET: return "ENONET";
588  case ENOPKG: return "ENOPKG";
589  case EREMCHG: return "EREMCHG";
590  case ERESTART: return "ERESTART";
591  case ESTRPIPE: return "ESTRPIPE";
592 #ifdef EUCLEAN // Not available on OS X, Illumos, Solaris
593  case EUCLEAN: return "EUCLEAN";
594 #endif
595  case EXFULL: return "EXFULL";
596 #endif // EBADE
597  default: return "Unknown";
598  }
599 }
600 
608 const char *
609 pcmk_rc_str(int rc)
610 {
611  if (rc == pcmk_rc_ok) {
612  return "OK";
613  }
614  if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
615  return pcmk__rcs[pcmk_rc_error - rc].desc;
616  }
617  if (rc < 0) {
618  return "Error";
619  }
620 
621  // Handle values that could be defined by system or by portability.h
622  switch (rc) {
623 #ifdef PCMK__ENOTUNIQ
624  case ENOTUNIQ: return "Name not unique on network";
625 #endif
626 #ifdef PCMK__ECOMM
627  case ECOMM: return "Communication error on send";
628 #endif
629 #ifdef PCMK__ELIBACC
630  case ELIBACC: return "Can not access a needed shared library";
631 #endif
632 #ifdef PCMK__EREMOTEIO
633  case EREMOTEIO: return "Remote I/O error";
634 #endif
635 #ifdef PCMK__ENOKEY
636  case ENOKEY: return "Required key not available";
637 #endif
638 #ifdef PCMK__ENODATA
639  case ENODATA: return "No data available";
640 #endif
641 #ifdef PCMK__ETIME
642  case ETIME: return "Timer expired";
643 #endif
644 #ifdef PCMK__EKEYREJECTED
645  case EKEYREJECTED: return "Key was rejected by service";
646 #endif
647  default: return strerror(rc);
648  }
649 }
650 
651 // This returns negative values for errors
653 int
655 {
656  if (rc >= 0) {
657  return -rc; // OK or system errno
658  }
659  if ((rc <= pcmk_rc_error) && ((pcmk_rc_error - rc) < pcmk__n_rc)) {
660  return pcmk__rcs[pcmk_rc_error - rc].legacy_rc;
661  }
662  return -pcmk_err_generic;
663 }
664 
666 int
667 pcmk_legacy2rc(int legacy_rc)
668 {
669  legacy_rc = abs(legacy_rc);
670  switch (legacy_rc) {
675  case pcmk_err_old_data: return pcmk_rc_old_data;
680  case pcmk_err_cib_save: return pcmk_rc_cib_save;
682  case pcmk_err_multiple: return pcmk_rc_multiple;
684  case pcmk_err_already: return pcmk_rc_already;
687  case pcmk_err_generic: return pcmk_rc_error;
688  case pcmk_ok: return pcmk_rc_ok;
689  default: return legacy_rc; // system errno
690  }
691 }
692 
693 // Exit status codes
694 
695 const char *
697 {
698  switch (exit_code) {
699  case CRM_EX_OK: return "CRM_EX_OK";
700  case CRM_EX_ERROR: return "CRM_EX_ERROR";
701  case CRM_EX_INVALID_PARAM: return "CRM_EX_INVALID_PARAM";
702  case CRM_EX_UNIMPLEMENT_FEATURE: return "CRM_EX_UNIMPLEMENT_FEATURE";
703  case CRM_EX_INSUFFICIENT_PRIV: return "CRM_EX_INSUFFICIENT_PRIV";
704  case CRM_EX_NOT_INSTALLED: return "CRM_EX_NOT_INSTALLED";
705  case CRM_EX_NOT_CONFIGURED: return "CRM_EX_NOT_CONFIGURED";
706  case CRM_EX_NOT_RUNNING: return "CRM_EX_NOT_RUNNING";
707  case CRM_EX_PROMOTED: return "CRM_EX_PROMOTED";
708  case CRM_EX_FAILED_PROMOTED: return "CRM_EX_FAILED_PROMOTED";
709  case CRM_EX_USAGE: return "CRM_EX_USAGE";
710  case CRM_EX_DATAERR: return "CRM_EX_DATAERR";
711  case CRM_EX_NOINPUT: return "CRM_EX_NOINPUT";
712  case CRM_EX_NOUSER: return "CRM_EX_NOUSER";
713  case CRM_EX_NOHOST: return "CRM_EX_NOHOST";
714  case CRM_EX_UNAVAILABLE: return "CRM_EX_UNAVAILABLE";
715  case CRM_EX_SOFTWARE: return "CRM_EX_SOFTWARE";
716  case CRM_EX_OSERR: return "CRM_EX_OSERR";
717  case CRM_EX_OSFILE: return "CRM_EX_OSFILE";
718  case CRM_EX_CANTCREAT: return "CRM_EX_CANTCREAT";
719  case CRM_EX_IOERR: return "CRM_EX_IOERR";
720  case CRM_EX_TEMPFAIL: return "CRM_EX_TEMPFAIL";
721  case CRM_EX_PROTOCOL: return "CRM_EX_PROTOCOL";
722  case CRM_EX_NOPERM: return "CRM_EX_NOPERM";
723  case CRM_EX_CONFIG: return "CRM_EX_CONFIG";
724  case CRM_EX_FATAL: return "CRM_EX_FATAL";
725  case CRM_EX_PANIC: return "CRM_EX_PANIC";
726  case CRM_EX_DISCONNECT: return "CRM_EX_DISCONNECT";
727  case CRM_EX_DIGEST: return "CRM_EX_DIGEST";
728  case CRM_EX_NOSUCH: return "CRM_EX_NOSUCH";
729  case CRM_EX_QUORUM: return "CRM_EX_QUORUM";
730  case CRM_EX_UNSAFE: return "CRM_EX_UNSAFE";
731  case CRM_EX_EXISTS: return "CRM_EX_EXISTS";
732  case CRM_EX_MULTIPLE: return "CRM_EX_MULTIPLE";
733  case CRM_EX_EXPIRED: return "CRM_EX_EXPIRED";
734  case CRM_EX_NOT_YET_IN_EFFECT: return "CRM_EX_NOT_YET_IN_EFFECT";
735  case CRM_EX_INDETERMINATE: return "CRM_EX_INDETERMINATE";
736  case CRM_EX_UNSATISFIED: return "CRM_EX_UNSATISFIED";
737  case CRM_EX_OLD: return "CRM_EX_OLD";
738  case CRM_EX_TIMEOUT: return "CRM_EX_TIMEOUT";
739  case CRM_EX_DEGRADED: return "CRM_EX_DEGRADED";
740  case CRM_EX_DEGRADED_PROMOTED: return "CRM_EX_DEGRADED_PROMOTED";
741  case CRM_EX_NONE: return "CRM_EX_NONE";
742  case CRM_EX_MAX: return "CRM_EX_UNKNOWN";
743  }
744  return "CRM_EX_UNKNOWN";
745 }
746 
747 const char *
749 {
750  switch (exit_code) {
751  case CRM_EX_OK: return "OK";
752  case CRM_EX_ERROR: return "Error occurred";
753  case CRM_EX_INVALID_PARAM: return "Invalid parameter";
754  case CRM_EX_UNIMPLEMENT_FEATURE: return "Unimplemented";
755  case CRM_EX_INSUFFICIENT_PRIV: return "Insufficient privileges";
756  case CRM_EX_NOT_INSTALLED: return "Not installed";
757  case CRM_EX_NOT_CONFIGURED: return "Not configured";
758  case CRM_EX_NOT_RUNNING: return "Not running";
759  case CRM_EX_PROMOTED: return "Promoted";
760  case CRM_EX_FAILED_PROMOTED: return "Failed in promoted role";
761  case CRM_EX_USAGE: return "Incorrect usage";
762  case CRM_EX_DATAERR: return "Invalid data given";
763  case CRM_EX_NOINPUT: return "Input file not available";
764  case CRM_EX_NOUSER: return "User does not exist";
765  case CRM_EX_NOHOST: return "Host does not exist";
766  case CRM_EX_UNAVAILABLE: return "Necessary service unavailable";
767  case CRM_EX_SOFTWARE: return "Internal software bug";
768  case CRM_EX_OSERR: return "Operating system error occurred";
769  case CRM_EX_OSFILE: return "System file not available";
770  case CRM_EX_CANTCREAT: return "Cannot create output file";
771  case CRM_EX_IOERR: return "I/O error occurred";
772  case CRM_EX_TEMPFAIL: return "Temporary failure, try again";
773  case CRM_EX_PROTOCOL: return "Protocol violated";
774  case CRM_EX_NOPERM: return "Insufficient privileges";
775  case CRM_EX_CONFIG: return "Invalid configuration";
776  case CRM_EX_FATAL: return "Fatal error occurred, will not respawn";
777  case CRM_EX_PANIC: return "System panic required";
778  case CRM_EX_DISCONNECT: return "Not connected";
779  case CRM_EX_DIGEST: return "Digest mismatch";
780  case CRM_EX_NOSUCH: return "No such object";
781  case CRM_EX_QUORUM: return "Quorum required";
782  case CRM_EX_UNSAFE: return "Operation not safe";
783  case CRM_EX_EXISTS: return "Requested item already exists";
784  case CRM_EX_MULTIPLE: return "Multiple items match request";
785  case CRM_EX_EXPIRED: return "Requested item has expired";
786  case CRM_EX_NOT_YET_IN_EFFECT: return "Requested item is not yet in effect";
787  case CRM_EX_INDETERMINATE: return "Could not determine status";
788  case CRM_EX_UNSATISFIED: return "Not applicable under current conditions";
789  case CRM_EX_OLD: return "Update was older than existing configuration";
790  case CRM_EX_TIMEOUT: return "Timeout occurred";
791  case CRM_EX_DEGRADED: return "Service is active but might fail soon";
792  case CRM_EX_DEGRADED_PROMOTED: return "Service is promoted but might fail soon";
793  case CRM_EX_NONE: return "No exit status available";
794  case CRM_EX_MAX: return "Error occurred";
795  }
796  if ((exit_code > 128) && (exit_code < CRM_EX_MAX)) {
797  return "Interrupted by signal";
798  }
799  return "Unknown exit status";
800 }
801 
811 {
812  switch (rc) {
813  case pcmk_rc_ok:
814  case pcmk_rc_no_output: // quiet mode, or nothing to output
815  return CRM_EX_OK;
816 
817  case pcmk_rc_no_quorum:
818  return CRM_EX_QUORUM;
819 
820  case pcmk_rc_old_data:
821  return CRM_EX_OLD;
822 
826  return CRM_EX_CONFIG;
827 
828  case pcmk_rc_bad_nvpair:
829  return CRM_EX_INVALID_PARAM;
830 
831  case EACCES:
833 
834  case EBADF:
835  case EINVAL:
836  case EFAULT:
837  case ENOSYS:
838  case EOVERFLOW:
839  case pcmk_rc_underflow:
840  case pcmk_rc_compression:
841  return CRM_EX_SOFTWARE;
842 
843  case EBADMSG:
844  case EMSGSIZE:
845  case ENOMSG:
846  case ENOPROTOOPT:
847  case EPROTO:
848  case EPROTONOSUPPORT:
849  case EPROTOTYPE:
850  return CRM_EX_PROTOCOL;
851 
852  case ECOMM:
853  case ENOMEM:
854  return CRM_EX_OSERR;
855 
856  case ECONNABORTED:
857  case ECONNREFUSED:
858  case ECONNRESET:
859  case ENOTCONN:
860  return CRM_EX_DISCONNECT;
861 
862  case EEXIST:
863  case pcmk_rc_already:
864  return CRM_EX_EXISTS;
865 
866  case EIO:
867  case pcmk_rc_dot_error:
868  case pcmk_rc_graph_error:
869  return CRM_EX_IOERR;
870 
871  case ENOTSUP:
872 #if EOPNOTSUPP != ENOTSUP
873  case EOPNOTSUPP:
874 #endif
876 
877  case ENOTUNIQ:
878  case pcmk_rc_multiple:
879  return CRM_EX_MULTIPLE;
880 
881  case ENODEV:
882  case ENOENT:
883  case ENXIO:
886  return CRM_EX_NOSUCH;
887 
890  return CRM_EX_NOHOST;
891 
892  case ETIME:
893  case ETIMEDOUT:
894  return CRM_EX_TIMEOUT;
895 
896  case EAGAIN:
897  case EBUSY:
898  return CRM_EX_UNSATISFIED;
899 
902 
903  case pcmk_rc_after_range:
904  return CRM_EX_EXPIRED;
905 
907  return CRM_EX_INDETERMINATE;
908 
910  return CRM_EX_UNSATISFIED;
911 
913  return CRM_EX_OK;
914 
915  case pcmk_rc_no_input:
916  return CRM_EX_NOINPUT;
917 
919  return CRM_EX_MULTIPLE;
920 
921  case pcmk_rc_bad_input:
923  return CRM_EX_DATAERR;
924 
925  default:
926  return CRM_EX_ERROR;
927  }
928 }
929 
937 enum ocf_exitcode
938 pcmk_rc2ocf(int rc)
939 {
940  switch (rc) {
941  case pcmk_rc_ok:
942  return PCMK_OCF_OK;
943 
944  case pcmk_rc_bad_nvpair:
945  return PCMK_OCF_INVALID_PARAM;
946 
947  case EACCES:
949 
950  case ENOTSUP:
951 #if EOPNOTSUPP != ENOTSUP
952  case EOPNOTSUPP:
953 #endif
955 
956  default:
957  return PCMK_OCF_UNKNOWN_ERROR;
958  }
959 }
960 
961 
962 // Other functions
963 
972 int
974 {
975  switch (gai) {
976  case 0:
977  return pcmk_rc_ok;
978 
979  case EAI_AGAIN:
980  return EAGAIN;
981 
982  case EAI_BADFLAGS:
983  case EAI_SERVICE:
984  return EINVAL;
985 
986  case EAI_FAMILY:
987  return EAFNOSUPPORT;
988 
989  case EAI_MEMORY:
990  return ENOMEM;
991 
992  case EAI_NONAME:
993  return pcmk_rc_node_unknown;
994 
995  case EAI_SOCKTYPE:
996  return ESOCKTNOSUPPORT;
997 
998  case EAI_SYSTEM:
999  return errno;
1000 
1001  default:
1002  return pcmk_rc_ns_resolution;
1003  }
1004 }
1005 
1013 int
1015 {
1016  switch (bz2) {
1017  case BZ_OK:
1018  case BZ_RUN_OK:
1019  case BZ_FLUSH_OK:
1020  case BZ_FINISH_OK:
1021  case BZ_STREAM_END:
1022  return pcmk_rc_ok;
1023 
1024  case BZ_MEM_ERROR:
1025  return ENOMEM;
1026 
1027  case BZ_DATA_ERROR:
1028  case BZ_DATA_ERROR_MAGIC:
1029  case BZ_UNEXPECTED_EOF:
1030  return pcmk_rc_bad_input;
1031 
1032  case BZ_IO_ERROR:
1033  return EIO;
1034 
1035  case BZ_OUTBUFF_FULL:
1036  return EFBIG;
1037 
1038  default:
1039  return pcmk_rc_compression;
1040  }
1041 }
1042 
1043 crm_exit_t
1044 crm_exit(crm_exit_t exit_status)
1045 {
1046  /* A compiler could theoretically use any type for crm_exit_t, but an int
1047  * should always hold it, so cast to int to keep static analysis happy.
1048  */
1049  if ((((int) exit_status) < 0) || (((int) exit_status) > CRM_EX_MAX)) {
1050  exit_status = CRM_EX_ERROR;
1051  }
1052 
1053  crm_info("Exiting %s " QB_XS " with status %d (%s: %s)",
1054  pcmk__s(crm_system_name, "process"), exit_status,
1055  crm_exit_name(exit_status), crm_exit_str(exit_status));
1057  exit(exit_status);
1058 }
1059 
1060 /*
1061  * External action results
1062  */
1063 
1073 void
1075  enum pcmk_exec_status exec_status, const char *exit_reason)
1076 {
1077  if (result == NULL) {
1078  return;
1079  }
1080 
1081  result->exit_status = exit_status;
1082  result->execution_status = exec_status;
1083 
1084  if (!pcmk__str_eq(result->exit_reason, exit_reason, pcmk__str_none)) {
1085  free(result->exit_reason);
1086  result->exit_reason = (exit_reason == NULL)? NULL : strdup(exit_reason);
1087  }
1088 }
1089 
1090 
1102 G_GNUC_PRINTF(4, 5)
1103 void
1105  enum pcmk_exec_status exec_status,
1106  const char *format, ...)
1107 {
1108  va_list ap;
1109  int len = 0;
1110  char *reason = NULL;
1111 
1112  if (result == NULL) {
1113  return;
1114  }
1115 
1116  result->exit_status = exit_status;
1117  result->execution_status = exec_status;
1118 
1119  if (format != NULL) {
1120  va_start(ap, format);
1121  len = vasprintf(&reason, format, ap);
1122  pcmk__assert(len > 0);
1123  va_end(ap);
1124  }
1125  free(result->exit_reason);
1126  result->exit_reason = reason;
1127 }
1128 
1142 void
1144 {
1145  if (result == NULL) {
1146  return;
1147  }
1148 
1149  free(result->action_stdout);
1150  result->action_stdout = out;
1151 
1152  free(result->action_stderr);
1153  result->action_stderr = err;
1154 }
1155 
1162 void
1164 {
1165  if (result == NULL) {
1166  return;
1167  }
1168 
1169  free(result->exit_reason);
1170  result->exit_reason = NULL;
1171 
1172  free(result->action_stdout);
1173  result->action_stdout = NULL;
1174 
1175  free(result->action_stderr);
1176  result->action_stderr = NULL;
1177 }
1178 
1186 void
1188 {
1189  CRM_CHECK((src != NULL) && (dst != NULL), return);
1190  dst->exit_status = src->exit_status;
1191  dst->execution_status = src->execution_status;
1192  dst->exit_reason = pcmk__str_copy(src->exit_reason);
1195 }
#define pcmk_err_old_data
Definition: results.h:73
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:213
User does not exist.
Definition: results.h:248
#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:251
#define ETIME
Definition: portability.h:66
crm_exit_t pcmk_rc2exitc(int rc)
Map a function return code to the most similar exit code.
Definition: results.c:810
void crm_enable_stderr(int enable)
Definition: logging.c:1067
#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:267
Dependencies not available locally.
Definition: results.h:238
int pcmk__result_bounds(enum pcmk_result_type type, int *lower, int *upper)
Definition: results.c:92
const char * name
Definition: cib.c:26
enum pcmk_ipc_server type
Definition: cpg.c:51
const char * crm_exit_name(crm_exit_t exit_code)
Definition: results.c:696
int pcmk_rc2legacy(int rc)
Definition: results.c:654
Update older than existing config.
Definition: results.h:265
Could not determine status.
Definition: results.h:274
Service active and promoted.
Definition: results.h:241
#define EKEYREJECTED
Definition: portability.h:71
Service promoted but more likely to fail soon.
Definition: results.h:287
#define pcmk_err_transform_failed
Definition: results.h:72
#define EREMOTEIO
Definition: portability.h:51
enum pcmk_exec_status execution_status
Unspecified error.
Definition: results.h:232
#define pcmk_err_node_unknown
Definition: results.h:87
Panic the local host.
Definition: results.h:263
#define pcmk_err_generic
Definition: results.h:69
char * crm_system_name
Definition: utils.c:44
Requested item does not satisfy constraints.
Definition: results.h:275
enum crm_exit_e crm_exit_t
void pcmk_common_cleanup(void)
Free all memory used by libcrmcommon.
Definition: utils.c:54
Command line usage error.
Definition: results.h:245
int pcmk__gaierror2rc(int gai)
Map a getaddrinfo() return code to the most similar Pacemaker return code.
Definition: results.c:973
Ensure crm_exit_t can hold this.
Definition: results.h:296
#define pcmk_err_cib_backup
Definition: results.h:82
Non-file permission issue.
Definition: results.h:258
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:609
enum ocf_exitcode pcmk_rc2ocf(int rc)
Map a function return code to the most similar OCF exit code.
Definition: results.c:938
File I/O error.
Definition: results.h:255
Try again.
Definition: results.h:256
void pcmk__set_result_output(pcmk__action_result_t *result, char *out, char *err)
Definition: results.c:1143
#define crm_warn(fmt, args...)
Definition: logging.h:362
#define pcmk_err_cib_save
Definition: results.h:83
#define pcmk_err_diff_failed
Definition: results.h:76
Protocol violated.
Definition: results.h:257
User-supplied data incorrect.
Definition: results.h:246
Host unknown.
Definition: results.h:249
uint32_t pid
Definition: cpg.c:49
Requested item has multiple matches.
Definition: results.h:271
int pcmk_legacy2rc(int legacy_rc)
Definition: results.c:667
void pcmk__copy_result(const pcmk__action_result_t *src, pcmk__action_result_t *dst)
Definition: results.c:1187
#define pcmk_err_multiple
Definition: results.h:86
Requested action not implemented.
Definition: results.h:236
const size_t pcmk__n_rc
Definition: results.c:439
Parameter invalid (in local context)
Definition: results.h:179
const char * crm_exit_str(crm_exit_t exit_code)
Definition: results.c:748
Input file not available.
Definition: results.h:247
External (OS/environmental) problem.
Definition: results.h:252
#define crm_trace(fmt, args...)
Definition: logging.h:372
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
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:49
Service failed and possibly promoted.
Definition: results.h:242
#define ECOMM
Definition: portability.h:41
Success.
Definition: results.h:231
#define pcmk_err_cib_modified
Definition: results.h:81
System file not usable.
Definition: results.h:253
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
Service active but more likely to fail soon.
Definition: results.h:286
#define pcmk__str_copy(str)
Service safely stopped.
Definition: results.h:240
void crm_write_blackbox(int nsig, const struct qb_log_callsite *callsite)
Definition: logging.c:519
Requested item has expired.
Definition: results.h:272
#define ENOKEY
Definition: portability.h:56
Unspecified error.
Definition: results.h:177
#define pcmk__assert(expr)
void pcmk__reset_result(pcmk__action_result_t *result)
Definition: results.c:1163
#define ELIBACC
Definition: portability.h:46
Misconfiguration.
Definition: results.h:259
Requested action not implemented.
Definition: results.h:180
Legacy API function return code.
Definition: results.h:341
void pcmk__format_result(pcmk__action_result_t *result, int exit_status, enum pcmk_exec_status exec_status, const char *format,...)
Definition: results.c:1104
Exit status code.
Definition: results.h:343
Requires –force or new conditions.
Definition: results.h:269
#define ENODATA
Definition: portability.h:61
_Noreturn void pcmk__abort_as(const char *file, const char *function, int line, const char *assert_condition)
Definition: results.c:150
#define pcmk_err_diff_resync
Definition: results.h:79
pcmk__action_result_t result
Definition: pcmk_fence.c:37
Insufficient privileges.
Definition: results.h:237
#define _Noreturn
Definition: results.h:40
#define crm_err(fmt, args...)
Definition: logging.h:359
#define pcmk_err_unknown_format
Definition: results.h:95
Success.
Definition: results.h:174
#define ENOTUNIQ
Definition: portability.h:36
Needed service unavailable.
Definition: results.h:250
File couldn&#39;t be created.
Definition: results.h:254
const char * pcmk_rc_name(int rc)
Get a return code constant name as a string.
Definition: results.c:449
Local partition does not have quorum.
Definition: results.h:268
Lost connection to something.
Definition: results.h:264
Requested item is not in effect.
Definition: results.h:273
Standard Pacemaker return code.
Definition: results.h:342
No exit status available.
Definition: results.h:294
#define pcmk_ok
Definition: results.h:65
Digest comparison failed.
Definition: results.h:266
pcmk_exec_status
Execution status.
Definition: results.h:306
Parameter invalid (in local context)
Definition: results.h:235
int pcmk__bzlib2rc(int bz2)
Map a bz2 return code to the most similar Pacemaker return code.
Definition: results.c:1014
Convention from timeout(1)
Definition: results.h:278
const char * pcmk_strerror(int rc)
Definition: results.c:257
crm_exit_t crm_exit(crm_exit_t exit_status)
Definition: results.c:1044
#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:270
#define crm_info(fmt, args...)
Definition: logging.h:367
Do not respawn.
Definition: results.h:262
Parameter invalid (inherently)
Definition: results.h:239
const char * pcmk_errorname(int rc)
Definition: results.c:231
pcmk_result_type
Types of Pacemaker result codes.
Definition: results.h:340
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:1074