1 /* 2 * Copyright 2012-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 #ifndef PCMK__CRM_COMMON_RESULTS__H 10 #define PCMK__CRM_COMMON_RESULTS__H 11 12 #include <glib.h> // gboolean 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 /*! 19 * \file 20 * \brief Function and executable result codes 21 * \ingroup core 22 */ 23 24 // Lifted from config.h 25 /* The _Noreturn keyword of C11. */ 26 #ifndef _Noreturn 27 # if (defined __cplusplus \ 28 && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ 29 || (defined _MSC_VER && 1900 <= _MSC_VER))) 30 # define _Noreturn [[noreturn]] 31 # elif ((!defined __cplusplus || defined __clang__) \ 32 && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \ 33 || 4 < __GNUC__ + (7 <= __GNUC_MINOR__))) 34 /* _Noreturn works as-is. */ 35 # elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C 36 # define _Noreturn __attribute__ ((__noreturn__)) 37 # elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0) 38 # define _Noreturn __declspec (noreturn) 39 # else 40 # define _Noreturn 41 # endif 42 #endif 43 44 /* 45 * Function return codes 46 * 47 * Most Pacemaker API functions return an integer return code. There are two 48 * alternative interpretations. The legacy interpration is that the absolute 49 * value of the return code is either a system error number or a custom 50 * pcmk_err_* number. This is less than ideal because system error numbers are 51 * constrained only to the positive int range, so there's the possibility that 52 * system errors and custom errors could collide (which did in fact happen 53 * already on one architecture). The new intepretation is that negative values 54 * are from the pcmk_rc_e enum, and positive values are system error numbers. 55 * Both use 0 for success. 56 * 57 * For system error codes, see: 58 * - /usr/include/asm-generic/errno.h 59 * - /usr/include/asm-generic/errno-base.h 60 */ 61 62 // Legacy custom return codes for Pacemaker API functions (deprecated) 63 64 // NOTE: sbd (as of at least 1.5.2) uses this 65 #define pcmk_ok 0 66 67 #define PCMK_ERROR_OFFSET 190 /* Replacements on non-linux systems, see include/portability.h */ 68 #define PCMK_CUSTOM_OFFSET 200 /* Purely custom codes */ 69 #define pcmk_err_generic 201 70 #define pcmk_err_no_quorum 202 71 #define pcmk_err_schema_validation 203 72 #define pcmk_err_transform_failed 204 73 #define pcmk_err_old_data 205 74 75 // NOTE: sbd (as of at least 1.5.2) uses this 76 #define pcmk_err_diff_failed 206 77 78 // NOTE: sbd (as of at least 1.5.2) uses this 79 #define pcmk_err_diff_resync 207 80 81 #define pcmk_err_cib_modified 208 82 #define pcmk_err_cib_backup 209 83 #define pcmk_err_cib_save 210 84 #define pcmk_err_schema_unchanged 211 85 #define pcmk_err_cib_corrupt 212 86 #define pcmk_err_multiple 213 87 #define pcmk_err_node_unknown 214 88 #define pcmk_err_already 215 89 /* On HPPA 215 is ENOSYM (Unknown error 215), which hopefully never happens. */ 90 #ifdef __hppa__ 91 #define pcmk_err_bad_nvpair 250 /* 216 is ENOTSOCK */ 92 #define pcmk_err_unknown_format 252 /* 217 is EDESTADDRREQ */ 93 #else 94 #define pcmk_err_bad_nvpair 216 95 #define pcmk_err_unknown_format 217 96 #endif 97 98 /*! 99 * \enum pcmk_rc_e 100 * \brief Return codes for Pacemaker API functions 101 * 102 * Any Pacemaker API function documented as returning a "standard Pacemaker 103 * return code" will return pcmk_rc_ok (0) on success, and one of this 104 * enumeration's other (negative) values or a (positive) system error number 105 * otherwise. The custom codes are at -1001 and lower, so that the caller may 106 * use -1 through -1000 for their own custom values if desired. While generally 107 * referred to as "errors", nonzero values simply indicate a result, which might 108 * or might not be an error depending on the calling context. 109 */ 110 enum pcmk_rc_e { 111 /* When adding new values, use consecutively lower numbers, update the array 112 * in lib/common/results.c, and test with crm_error. 113 */ 114 pcmk_rc_compression = -1039, 115 pcmk_rc_ns_resolution = -1038, 116 pcmk_rc_no_transaction = -1037, 117 pcmk_rc_bad_xml_patch = -1036, 118 pcmk_rc_bad_input = -1035, 119 pcmk_rc_disabled = -1034, 120 pcmk_rc_duplicate_id = -1033, 121 pcmk_rc_unpack_error = -1032, 122 pcmk_rc_invalid_transition = -1031, 123 pcmk_rc_graph_error = -1030, 124 pcmk_rc_dot_error = -1029, 125 pcmk_rc_underflow = -1028, 126 pcmk_rc_no_input = -1027, 127 pcmk_rc_no_output = -1026, 128 pcmk_rc_after_range = -1025, 129 pcmk_rc_within_range = -1024, 130 pcmk_rc_before_range = -1023, 131 pcmk_rc_undetermined = -1022, 132 pcmk_rc_op_unsatisfied = -1021, 133 pcmk_rc_ipc_pid_only = -1020, 134 pcmk_rc_ipc_unresponsive = -1019, 135 pcmk_rc_ipc_unauthorized = -1018, 136 pcmk_rc_no_quorum = -1017, 137 pcmk_rc_schema_validation = -1016, 138 pcmk_rc_schema_unchanged = -1015, 139 pcmk_rc_transform_failed = -1014, 140 pcmk_rc_old_data = -1013, 141 pcmk_rc_diff_failed = -1012, 142 pcmk_rc_diff_resync = -1011, 143 pcmk_rc_cib_modified = -1010, 144 pcmk_rc_cib_backup = -1009, 145 pcmk_rc_cib_save = -1008, 146 pcmk_rc_cib_corrupt = -1007, 147 pcmk_rc_multiple = -1006, 148 pcmk_rc_node_unknown = -1005, 149 pcmk_rc_already = -1004, 150 pcmk_rc_bad_nvpair = -1003, 151 pcmk_rc_unknown_format = -1002, 152 // Developers: Use a more specific code than pcmk_rc_error whenever possible 153 pcmk_rc_error = -1001, 154 155 // Values -1 through -1000 reserved for caller use 156 157 // NOTE: sbd (as of at least 1.5.2) uses this 158 pcmk_rc_ok = 0 159 160 // Positive values reserved for system error numbers 161 }; 162 163 164 /*! 165 * \enum ocf_exitcode 166 * \brief Exit status codes for resource agents 167 * 168 * The OCF Resource Agent API standard enumerates the possible exit status codes 169 * that agents should return. Besides being used with OCF agents, these values 170 * are also used by the executor as a universal status for all agent standards; 171 * actual results are mapped to these before returning them to clients. 172 */ 173 enum ocf_exitcode { 174 PCMK_OCF_OK = 0, //!< Success 175 176 // NOTE: booth (as of at least 1.1) uses this value 177 PCMK_OCF_UNKNOWN_ERROR = 1, //!< Unspecified error 178 179 PCMK_OCF_INVALID_PARAM = 2, //!< Parameter invalid (in local context) 180 PCMK_OCF_UNIMPLEMENT_FEATURE = 3, //!< Requested action not implemented 181 PCMK_OCF_INSUFFICIENT_PRIV = 4, //!< Insufficient privileges 182 PCMK_OCF_NOT_INSTALLED = 5, //!< Dependencies not available locally 183 PCMK_OCF_NOT_CONFIGURED = 6, //!< Parameter invalid (inherently) 184 185 // NOTE: booth (as of at least 1.1) uses this value 186 PCMK_OCF_NOT_RUNNING = 7, //!< Service safely stopped 187 188 PCMK_OCF_RUNNING_PROMOTED = 8, //!< Service active and promoted 189 PCMK_OCF_FAILED_PROMOTED = 9, //!< Service failed and possibly in promoted role 190 PCMK_OCF_DEGRADED = 190, //!< Service active but more likely to fail soon 191 PCMK_OCF_DEGRADED_PROMOTED = 191, //!< Service promoted but more likely to fail soon 192 193 /* These two are Pacemaker extensions, not in the OCF standard. The 194 * controller records PCMK_OCF_UNKNOWN for pending actions. 195 * PCMK_OCF_CONNECTION_DIED is used only with older DCs that don't support 196 * PCMK_EXEC_NOT_CONNECTED. 197 */ 198 PCMK_OCF_CONNECTION_DIED = 189, //!< \deprecated See PCMK_EXEC_NOT_CONNECTED 199 PCMK_OCF_UNKNOWN = 193, //!< Action is pending 200 201 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1) 202 // Former Pacemaker extensions 203 PCMK_OCF_EXEC_ERROR = 192, //!< \deprecated (Unused) 204 PCMK_OCF_SIGNAL = 194, //!< \deprecated (Unused) 205 PCMK_OCF_NOT_SUPPORTED = 195, //!< \deprecated (Unused) 206 PCMK_OCF_PENDING = 196, //!< \deprecated (Unused) 207 PCMK_OCF_CANCELLED = 197, //!< \deprecated (Unused) 208 PCMK_OCF_TIMEOUT = 198, //!< \deprecated (Unused) 209 PCMK_OCF_OTHER_ERROR = 199, //!< \deprecated (Unused) 210 211 //! \deprecated Use PCMK_OCF_RUNNING_PROMOTED instead 212 PCMK_OCF_RUNNING_MASTER = PCMK_OCF_RUNNING_PROMOTED, 213 214 //! \deprecated Use PCMK_OCF_FAILED_PROMOTED instead 215 PCMK_OCF_FAILED_MASTER = PCMK_OCF_FAILED_PROMOTED, 216 217 //! \deprecated Use PCMK_OCF_DEGRADED_PROMOTED instead 218 PCMK_OCF_DEGRADED_MASTER = PCMK_OCF_DEGRADED_PROMOTED, 219 #endif 220 }; 221 222 // NOTE: sbd (as of at least 1.5.2) uses this 223 /*! 224 * \enum crm_exit_e 225 * \brief Exit status codes for tools and daemons 226 * 227 * We want well-specified (i.e. OS-invariant) exit status codes for our daemons 228 * and applications so they can be relied on by callers. (Function return codes 229 * and errno's do not make good exit statuses.) 230 * 231 * The only hard rule is that exit statuses must be between 0 and 255; all else 232 * is convention. Universally, 0 is success, and 1 is generic error (excluding 233 * OSes we don't support -- for example, OpenVMS considers 1 success!). 234 * 235 * For init scripts, the LSB gives meaning to 0-7, and sets aside 150-199 for 236 * application use. OCF adds 8-9 and 190-191. 237 * 238 * sysexits.h was an attempt to give additional meanings, but never really 239 * caught on. It uses 0 and 64-78. 240 * 241 * Bash reserves 2 ("incorrect builtin usage") and 126-255 (126 is "command 242 * found but not executable", 127 is "command not found", 128 + n is 243 * "interrupted by signal n"). 244 * 245 * tldp.org recommends 64-113 for application use. 246 * 247 * We try to overlap with the above conventions when practical. 248 */ 249 typedef enum crm_exit_e { 250 // Common convention 251 CRM_EX_OK = 0, //!< Success 252 CRM_EX_ERROR = 1, //!< Unspecified error 253 254 // LSB + OCF 255 CRM_EX_INVALID_PARAM = 2, //!< Parameter invalid (in local context) 256 CRM_EX_UNIMPLEMENT_FEATURE = 3, //!< Requested action not implemented 257 CRM_EX_INSUFFICIENT_PRIV = 4, //!< Insufficient privileges 258 CRM_EX_NOT_INSTALLED = 5, //!< Dependencies not available locally 259 CRM_EX_NOT_CONFIGURED = 6, //!< Parameter invalid (inherently) 260 CRM_EX_NOT_RUNNING = 7, //!< Service safely stopped 261 CRM_EX_PROMOTED = 8, //!< Service active and promoted 262 CRM_EX_FAILED_PROMOTED = 9, //!< Service failed and possibly promoted 263 264 // sysexits.h 265 CRM_EX_USAGE = 64, //!< Command line usage error 266 CRM_EX_DATAERR = 65, //!< User-supplied data incorrect 267 CRM_EX_NOINPUT = 66, //!< Input file not available 268 CRM_EX_NOUSER = 67, //!< User does not exist 269 CRM_EX_NOHOST = 68, //!< Host unknown 270 CRM_EX_UNAVAILABLE = 69, //!< Needed service unavailable 271 CRM_EX_SOFTWARE = 70, //!< Internal software bug 272 CRM_EX_OSERR = 71, //!< External (OS/environmental) problem 273 CRM_EX_OSFILE = 72, //!< System file not usable 274 CRM_EX_CANTCREAT = 73, //!< File couldn't be created 275 CRM_EX_IOERR = 74, //!< File I/O error 276 CRM_EX_TEMPFAIL = 75, //!< Try again 277 CRM_EX_PROTOCOL = 76, //!< Protocol violated 278 CRM_EX_NOPERM = 77, //!< Non-file permission issue 279 CRM_EX_CONFIG = 78, //!< Misconfiguration 280 281 // Custom 282 CRM_EX_FATAL = 100, //!< Do not respawn 283 CRM_EX_PANIC = 101, //!< Panic the local host 284 CRM_EX_DISCONNECT = 102, //!< Lost connection to something 285 CRM_EX_OLD = 103, //!< Update older than existing config 286 CRM_EX_DIGEST = 104, //!< Digest comparison failed 287 CRM_EX_NOSUCH = 105, //!< Requested item does not exist 288 CRM_EX_QUORUM = 106, //!< Local partition does not have quorum 289 CRM_EX_UNSAFE = 107, //!< Requires --force or new conditions 290 CRM_EX_EXISTS = 108, //!< Requested item already exists 291 CRM_EX_MULTIPLE = 109, //!< Requested item has multiple matches 292 CRM_EX_EXPIRED = 110, //!< Requested item has expired 293 CRM_EX_NOT_YET_IN_EFFECT = 111, //!< Requested item is not in effect 294 CRM_EX_INDETERMINATE = 112, //!< Could not determine status 295 CRM_EX_UNSATISFIED = 113, //!< Requested item does not satisfy constraints 296 297 // Other 298 CRM_EX_TIMEOUT = 124, //!< Convention from timeout(1) 299 300 /* Anything above 128 overlaps with some shells' use of these values for 301 * "interrupted by signal N", and so may be unreliable when detected by 302 * shell scripts. 303 */ 304 305 // OCF Resource Agent API 1.1 306 CRM_EX_DEGRADED = 190, //!< Service active but more likely to fail soon 307 CRM_EX_DEGRADED_PROMOTED = 191, //!< Service promoted but more likely to fail soon 308 309 /* Custom 310 * 311 * This can be used to initialize exit status variables or to indicate that 312 * a command is pending (which is what the controller uses it for). 313 */ 314 CRM_EX_NONE = 193, //!< No exit status available 315 316 CRM_EX_MAX = 255, //!< Ensure crm_exit_t can hold this 317 } crm_exit_t; 318 319 /*! 320 * \enum pcmk_exec_status 321 * \brief Execution status 322 * 323 * These codes are used to specify the result of the attempt to execute an 324 * agent, rather than the agent's result itself. 325 */ 326 enum pcmk_exec_status { 327 PCMK_EXEC_UNKNOWN = -2, //!< Used only to initialize variables 328 PCMK_EXEC_PENDING = -1, //!< Action is in progress 329 PCMK_EXEC_DONE, //!< Action completed, result is known 330 PCMK_EXEC_CANCELLED, //!< Action was cancelled 331 PCMK_EXEC_TIMEOUT, //!< Action did not complete in time 332 PCMK_EXEC_NOT_SUPPORTED, //!< Agent does not implement requested action 333 PCMK_EXEC_ERROR, //!< Execution failed, may be retried 334 PCMK_EXEC_ERROR_HARD, //!< Execution failed, do not retry on node 335 PCMK_EXEC_ERROR_FATAL, //!< Execution failed, do not retry anywhere 336 PCMK_EXEC_NOT_INSTALLED, //!< Agent or dependency not available locally 337 PCMK_EXEC_NOT_CONNECTED, //!< No connection to executor 338 PCMK_EXEC_INVALID, //!< Action cannot be attempted (e.g. shutdown) 339 PCMK_EXEC_NO_FENCE_DEVICE, //!< No fence device is configured for target 340 PCMK_EXEC_NO_SECRETS, //!< Necessary CIB secrets are unavailable 341 342 // Add new values above here then update this one below 343 PCMK_EXEC_MAX = PCMK_EXEC_NO_SECRETS, //!< Maximum value for this enum 344 }; 345 346 /*! 347 * \enum pcmk_result_type 348 * \brief Types of Pacemaker result codes 349 * 350 * A particular integer can have different meanings within different Pacemaker 351 * result code families. It may be interpretable within zero, one, or multiple 352 * families. 353 * 354 * These values are useful for specifying how an integer result code should be 355 * interpreted in situations involving a generic integer value. For example, a 356 * function that can process multiple types of result codes might accept an 357 * arbitrary integer argument along with a \p pcmk_result_type argument that 358 * specifies how to interpret the integer. 359 */ 360 enum pcmk_result_type { 361 pcmk_result_legacy = 0, //!< Legacy API function return code 362 pcmk_result_rc = 1, //!< Standard Pacemaker return code 363 pcmk_result_exitcode = 2, //!< Exit status code 364 pcmk_result_exec_status = 3, //!< Execution status 365 }; 366 367 int pcmk_result_get_strings(int code, enum pcmk_result_type type, 368 const char **name, const char **desc); 369 const char *pcmk_rc_name(int rc); 370 371 // NOTE: sbd (as of at least 1.5.2) uses this 372 const char *pcmk_rc_str(int rc); 373 374 crm_exit_t pcmk_rc2exitc(int rc); 375 enum ocf_exitcode pcmk_rc2ocf(int rc); 376 int pcmk_rc2legacy(int rc); 377 int pcmk_legacy2rc(int legacy_rc); 378 379 // NOTE: sbd (as of at least 1.5.2) uses this 380 const char *pcmk_strerror(int rc); 381 382 const char *pcmk_errorname(int rc); 383 const char *crm_exit_name(crm_exit_t exit_code); 384 385 // NOTE: sbd (as of at least 1.5.2) uses this 386 const char *crm_exit_str(crm_exit_t exit_code); 387 388 _Noreturn crm_exit_t crm_exit(crm_exit_t rc); 389 390 /* coverity[+kill] */ 391 void crm_abort(const char *file, const char *function, int line, 392 const char *condition, gboolean do_core, gboolean do_fork); 393 394 static inline const char * 395 pcmk_exec_status_str(enum pcmk_exec_status status) /* */ 396 { 397 switch (status) { 398 case PCMK_EXEC_PENDING: return "pending"; 399 case PCMK_EXEC_DONE: return "complete"; 400 case PCMK_EXEC_CANCELLED: return "Cancelled"; 401 case PCMK_EXEC_TIMEOUT: return "Timed Out"; 402 case PCMK_EXEC_NOT_SUPPORTED: return "NOT SUPPORTED"; 403 case PCMK_EXEC_ERROR: return "Error"; 404 case PCMK_EXEC_ERROR_HARD: return "Hard error"; 405 case PCMK_EXEC_ERROR_FATAL: return "Fatal error"; 406 case PCMK_EXEC_NOT_INSTALLED: return "Not installed"; 407 case PCMK_EXEC_NOT_CONNECTED: return "Internal communication failure"; 408 case PCMK_EXEC_INVALID: return "Cannot execute now"; 409 case PCMK_EXEC_NO_FENCE_DEVICE: return "No fence device"; 410 case PCMK_EXEC_NO_SECRETS: return "CIB secrets unavailable"; 411 default: return "UNKNOWN!"; 412 } 413 } 414 415 #ifdef __cplusplus 416 } 417 #endif 418 419 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1) 420 #include <crm/common/results_compat.h> 421 #endif 422 423 #endif