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