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