1 /* 2 * Copyright 2012-2021 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 #ifndef CRM_RESULTS__H 10 # define CRM_RESULTS__H 11 12 #ifdef __cplusplus 13 extern "C" { 14 #endif 15 16 /*! 17 * \file 18 * \brief Function and executable result codes 19 * \ingroup core 20 */ 21 22 // Lifted from config.h 23 /* The _Noreturn keyword of C11. */ 24 #ifndef _Noreturn 25 # if (defined __cplusplus \ 26 && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ 27 || (defined _MSC_VER && 1900 <= _MSC_VER))) 28 # define _Noreturn [[noreturn]] 29 # elif ((!defined __cplusplus || defined __clang__) \ 30 && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ 31 || 4 < __GNUC__ + (7 <= __GNUC_MINOR__))) 32 /* _Noreturn works as-is. */ 33 # elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C 34 # define _Noreturn __attribute__ ((__noreturn__)) 35 # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) 36 # define _Noreturn __declspec (noreturn) 37 # else 38 # define _Noreturn 39 # endif 40 #endif 41 42 # define CRM_ASSERT(expr) do { \ 43 if (!(expr)) { \ 44 crm_abort(__FILE__, __func__, __LINE__, #expr, TRUE, FALSE); \ 45 abort(); /* crm_abort() doesn't always abort! */ \ 46 } \ 47 } while(0) 48 49 /* 50 * Function return codes 51 * 52 * Most Pacemaker API functions return an integer return code. There are two 53 * alternative interpretations. The legacy interpration is that the absolute 54 * value of the return code is either a system error number or a custom 55 * pcmk_err_* number. This is less than ideal because system error numbers are 56 * constrained only to the positive int range, so there's the possibility 57 * (though not noticed in the wild) that system errors and custom errors could 58 * collide. The new intepretation is that negative values are from the pcmk_rc_e 59 * enum, and positive values are system error numbers. Both use 0 for success. 60 * 61 * For system error codes, see: 62 * - /usr/include/asm-generic/errno.h 63 * - /usr/include/asm-generic/errno-base.h 64 */ 65 66 // Legacy custom return codes for Pacemaker API functions (deprecated) 67 # define pcmk_ok 0 68 # define PCMK_ERROR_OFFSET 190 /* Replacements on non-linux systems, see include/portability.h */ 69 # define PCMK_CUSTOM_OFFSET 200 /* Purely custom codes */ 70 # define pcmk_err_generic 201 71 # define pcmk_err_no_quorum 202 72 # define pcmk_err_schema_validation 203 73 # define pcmk_err_transform_failed 204 74 # define pcmk_err_old_data 205 75 # define pcmk_err_diff_failed 206 76 # define pcmk_err_diff_resync 207 77 # define pcmk_err_cib_modified 208 78 # define pcmk_err_cib_backup 209 79 # define pcmk_err_cib_save 210 80 # define pcmk_err_schema_unchanged 211 81 # define pcmk_err_cib_corrupt 212 82 # define pcmk_err_multiple 213 83 # define pcmk_err_node_unknown 214 84 # define pcmk_err_already 215 85 /* On HPPA 215 is ENOSYM (Unknown error 215), which hopefully never happens. */ 86 #ifdef __hppa__ 87 # define pcmk_err_bad_nvpair 250 /* 216 is ENOTSOCK */ 88 # define pcmk_err_unknown_format 252 /* 217 is EDESTADDRREQ */ 89 #else 90 # define pcmk_err_bad_nvpair 216 91 # define pcmk_err_unknown_format 217 92 #endif 93 94 /*! 95 * \enum pcmk_rc_e 96 * \brief Return codes for Pacemaker API functions 97 * 98 * Any Pacemaker API function documented as returning a "standard Pacemaker 99 * return code" will return pcmk_rc_ok (0) on success, and one of this 100 * enumeration's other (negative) values or a (positive) system error number 101 * otherwise. The custom codes are at -1001 and lower, so that the caller may 102 * use -1 through -1000 for their own custom values if desired. While generally 103 * referred to as "errors", nonzero values simply indicate a result, which might 104 * or might not be an error depending on the calling context. 105 */ 106 enum pcmk_rc_e { 107 /* When adding new values, use consecutively lower numbers, update the array 108 * in lib/common/results.c, and test with crm_error. 109 */ 110 pcmk_rc_underflow = -1028, 111 pcmk_rc_no_input = -1027, 112 pcmk_rc_no_output = -1026, 113 pcmk_rc_after_range = -1025, 114 pcmk_rc_within_range = -1024, 115 pcmk_rc_before_range = -1023, 116 pcmk_rc_undetermined = -1022, 117 pcmk_rc_op_unsatisfied = -1021, 118 pcmk_rc_ipc_pid_only = -1020, 119 pcmk_rc_ipc_unresponsive = -1019, 120 pcmk_rc_ipc_unauthorized = -1018, 121 pcmk_rc_no_quorum = -1017, 122 pcmk_rc_schema_validation = -1016, 123 pcmk_rc_schema_unchanged = -1015, 124 pcmk_rc_transform_failed = -1014, 125 pcmk_rc_old_data = -1013, 126 pcmk_rc_diff_failed = -1012, 127 pcmk_rc_diff_resync = -1011, 128 pcmk_rc_cib_modified = -1010, 129 pcmk_rc_cib_backup = -1009, 130 pcmk_rc_cib_save = -1008, 131 pcmk_rc_cib_corrupt = -1007, 132 pcmk_rc_multiple = -1006, 133 pcmk_rc_node_unknown = -1005, 134 pcmk_rc_already = -1004, 135 pcmk_rc_bad_nvpair = -1003, 136 pcmk_rc_unknown_format = -1002, 137 // Developers: Use a more specific code than pcmk_rc_error whenever possible 138 pcmk_rc_error = -1001, 139 140 // Values -1 through -1000 reserved for caller use 141 142 pcmk_rc_ok = 0 143 144 // Positive values reserved for system error numbers 145 }; 146 147 /* Uniform exit codes 148 * Everything is mapped to its OCF equivalent so that Pacemaker only deals with one set of codes 149 */ 150 enum ocf_exitcode { 151 PCMK_OCF_OK = 0, 152 PCMK_OCF_UNKNOWN_ERROR = 1, 153 PCMK_OCF_INVALID_PARAM = 2, 154 PCMK_OCF_UNIMPLEMENT_FEATURE = 3, 155 PCMK_OCF_INSUFFICIENT_PRIV = 4, 156 PCMK_OCF_NOT_INSTALLED = 5, 157 PCMK_OCF_NOT_CONFIGURED = 6, 158 PCMK_OCF_NOT_RUNNING = 7, /* End of overlap with LSB */ 159 PCMK_OCF_RUNNING_PROMOTED = 8, 160 PCMK_OCF_FAILED_PROMOTED = 9, 161 162 163 /* 150-199 reserved for application use */ 164 PCMK_OCF_CONNECTION_DIED = 189, // Deprecated (see PCMK_LRM_OP_NOT_CONNECTED) 165 166 PCMK_OCF_DEGRADED = 190, // Resource active but more likely to fail soon 167 PCMK_OCF_DEGRADED_PROMOTED = 191, // Resource promoted but more likely to fail soon 168 169 PCMK_OCF_EXEC_ERROR = 192, /* Generic problem invoking the agent */ 170 PCMK_OCF_UNKNOWN = 193, /* State of the service is unknown - used for recording in-flight operations */ 171 PCMK_OCF_SIGNAL = 194, 172 PCMK_OCF_NOT_SUPPORTED = 195, 173 PCMK_OCF_PENDING = 196, 174 PCMK_OCF_CANCELLED = 197, 175 PCMK_OCF_TIMEOUT = 198, 176 PCMK_OCF_OTHER_ERROR = 199, /* Keep the same codes as PCMK_LSB */ 177 178 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1) 179 //! \deprecated Use PCMK_OCF_RUNNING_PROMOTED instead 180 PCMK_OCF_RUNNING_MASTER = PCMK_OCF_RUNNING_PROMOTED, 181 182 //! \deprecated Use PCMK_OCF_FAILED_PROMOTED instead 183 PCMK_OCF_FAILED_MASTER = PCMK_OCF_FAILED_PROMOTED, 184 185 //! \deprecated Use PCMK_OCF_DEGRADED_PROMOTED instead 186 PCMK_OCF_DEGRADED_MASTER = PCMK_OCF_DEGRADED_PROMOTED, 187 #endif 188 }; 189 190 /* 191 * Exit status codes 192 * 193 * We want well-specified (i.e. OS-invariant) exit status codes for our daemons 194 * and applications so they can be relied on by callers. (Function return codes 195 * and errno's do not make good exit statuses.) 196 * 197 * The only hard rule is that exit statuses must be between 0 and 255; all else 198 * is convention. Universally, 0 is success, and 1 is generic error (excluding 199 * OSes we don't support -- for example, OpenVMS considers 1 success!). 200 * 201 * For init scripts, the LSB gives meaning to 0-7, and sets aside 150-199 for 202 * application use. OCF adds 8-9 and 189-199. 203 * 204 * sysexits.h was an attempt to give additional meanings, but never really 205 * caught on. It uses 0 and 64-78. 206 * 207 * Bash reserves 2 ("incorrect builtin usage") and 126-255 (126 is "command 208 * found but not executable", 127 is "command not found", 128 + n is 209 * "interrupted by signal n"). 210 * 211 * tldp.org recommends 64-113 for application use. 212 * 213 * We try to overlap with the above conventions when practical. 214 */ 215 typedef enum crm_exit_e { 216 // Common convention 217 CRM_EX_OK = 0, 218 CRM_EX_ERROR = 1, 219 220 // LSB + OCF 221 CRM_EX_INVALID_PARAM = 2, 222 CRM_EX_UNIMPLEMENT_FEATURE = 3, 223 CRM_EX_INSUFFICIENT_PRIV = 4, 224 CRM_EX_NOT_INSTALLED = 5, 225 CRM_EX_NOT_CONFIGURED = 6, 226 CRM_EX_NOT_RUNNING = 7, 227 228 // sysexits.h 229 CRM_EX_USAGE = 64, // command line usage error 230 CRM_EX_DATAERR = 65, // user-supplied data incorrect 231 CRM_EX_NOINPUT = 66, // input file not available 232 CRM_EX_NOUSER = 67, // user does not exist 233 CRM_EX_NOHOST = 68, // host unknown 234 CRM_EX_UNAVAILABLE = 69, // needed service unavailable 235 CRM_EX_SOFTWARE = 70, // internal software bug 236 CRM_EX_OSERR = 71, // external (OS/environmental) problem 237 CRM_EX_OSFILE = 72, // system file not usable 238 CRM_EX_CANTCREAT = 73, // file couldn't be created 239 CRM_EX_IOERR = 74, // file I/O error 240 CRM_EX_TEMPFAIL = 75, // try again 241 CRM_EX_PROTOCOL = 76, // protocol violated 242 CRM_EX_NOPERM = 77, // non-file permission issue 243 CRM_EX_CONFIG = 78, // misconfiguration 244 245 // Custom 246 CRM_EX_FATAL = 100, // do not respawn 247 CRM_EX_PANIC = 101, // panic the local host 248 CRM_EX_DISCONNECT = 102, // lost connection to something 249 CRM_EX_OLD = 103, // update older than existing config 250 CRM_EX_DIGEST = 104, // digest comparison failed 251 CRM_EX_NOSUCH = 105, // requested item does not exist 252 CRM_EX_QUORUM = 106, // local partition does not have quorum 253 CRM_EX_UNSAFE = 107, // requires --force or new conditions 254 CRM_EX_EXISTS = 108, // requested item already exists 255 CRM_EX_MULTIPLE = 109, // requested item has multiple matches 256 CRM_EX_EXPIRED = 110, // requested item has expired 257 CRM_EX_NOT_YET_IN_EFFECT = 111, // requested item is not in effect 258 CRM_EX_INDETERMINATE = 112, // could not determine status 259 CRM_EX_UNSATISFIED = 113, // requested item does not satisfy constraints 260 261 // Other 262 CRM_EX_TIMEOUT = 124, // convention from timeout(1) 263 CRM_EX_MAX = 255, // ensure crm_exit_t can hold this 264 } crm_exit_t; 265 266 const char *pcmk_rc_name(int rc); 267 const char *pcmk_rc_str(int rc); 268 crm_exit_t pcmk_rc2exitc(int rc); 269 int pcmk_rc2legacy(int rc); 270 int pcmk_legacy2rc(int legacy_rc); 271 const char *pcmk_strerror(int rc); 272 const char *pcmk_errorname(int rc); 273 const char *bz2_strerror(int rc); 274 crm_exit_t crm_errno2exit(int rc); 275 const char *crm_exit_name(crm_exit_t exit_code); 276 const char *crm_exit_str(crm_exit_t exit_code); 277 _Noreturn crm_exit_t crm_exit(crm_exit_t rc); 278 279 #ifdef __cplusplus 280 } 281 #endif 282 283 #endif 284