1 /*
2 * Copyright 2012-2020 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(__unlikely((expr) == FALSE)) { \
44 crm_abort(__FILE__, __func__, __LINE__, #expr, TRUE, FALSE); \
45 abort(); /* Redundant but it makes static analyzers happy */ \
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_MASTER = 8,
160 PCMK_OCF_FAILED_MASTER = 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, /* Active resource that is no longer 100% functional */
167 PCMK_OCF_DEGRADED_MASTER = 191, /* Promoted resource that is no longer 100% functional */
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
179 /*
180 * Exit status codes
181 *
182 * We want well-specified (i.e. OS-invariant) exit status codes for our daemons
183 * and applications so they can be relied on by callers. (Function return codes
184 * and errno's do not make good exit statuses.)
185 *
186 * The only hard rule is that exit statuses must be between 0 and 255; all else
187 * is convention. Universally, 0 is success, and 1 is generic error (excluding
188 * OSes we don't support -- for example, OpenVMS considers 1 success!).
189 *
190 * For init scripts, the LSB gives meaning to 0-7, and sets aside 150-199 for
191 * application use. OCF adds 8-9 and 189-199.
192 *
193 * sysexits.h was an attempt to give additional meanings, but never really
194 * caught on. It uses 0 and 64-78.
195 *
196 * Bash reserves 2 ("incorrect builtin usage") and 126-255 (126 is "command
197 * found but not executable", 127 is "command not found", 128 + n is
198 * "interrupted by signal n").
199 *
200 * tldp.org recommends 64-113 for application use.
201 *
202 * We try to overlap with the above conventions when practical.
203 */
204 typedef enum crm_exit_e {
205 // Common convention
206 CRM_EX_OK = 0,
207 CRM_EX_ERROR = 1,
208
209 // LSB + OCF
210 CRM_EX_INVALID_PARAM = 2,
211 CRM_EX_UNIMPLEMENT_FEATURE = 3,
212 CRM_EX_INSUFFICIENT_PRIV = 4,
213 CRM_EX_NOT_INSTALLED = 5,
214 CRM_EX_NOT_CONFIGURED = 6,
215 CRM_EX_NOT_RUNNING = 7,
216
217 // sysexits.h
218 CRM_EX_USAGE = 64, // command line usage error
219 CRM_EX_DATAERR = 65, // user-supplied data incorrect
220 CRM_EX_NOINPUT = 66, // input file not available
221 CRM_EX_NOUSER = 67, // user does not exist
222 CRM_EX_NOHOST = 68, // host unknown
223 CRM_EX_UNAVAILABLE = 69, // needed service unavailable
224 CRM_EX_SOFTWARE = 70, // internal software bug
225 CRM_EX_OSERR = 71, // external (OS/environmental) problem
226 CRM_EX_OSFILE = 72, // system file not usable
227 CRM_EX_CANTCREAT = 73, // file couldn't be created
228 CRM_EX_IOERR = 74, // file I/O error
229 CRM_EX_TEMPFAIL = 75, // try again
230 CRM_EX_PROTOCOL = 76, // protocol violated
231 CRM_EX_NOPERM = 77, // non-file permission issue
232 CRM_EX_CONFIG = 78, // misconfiguration
233
234 // Custom
235 CRM_EX_FATAL = 100, // do not respawn
236 CRM_EX_PANIC = 101, // panic the local host
237 CRM_EX_DISCONNECT = 102, // lost connection to something
238 CRM_EX_OLD = 103, // update older than existing config
239 CRM_EX_DIGEST = 104, // digest comparison failed
240 CRM_EX_NOSUCH = 105, // requested item does not exist
241 CRM_EX_QUORUM = 106, // local partition does not have quorum
242 CRM_EX_UNSAFE = 107, // requires --force or new conditions
243 CRM_EX_EXISTS = 108, // requested item already exists
244 CRM_EX_MULTIPLE = 109, // requested item has multiple matches
245 CRM_EX_EXPIRED = 110, // requested item has expired
246 CRM_EX_NOT_YET_IN_EFFECT = 111, // requested item is not in effect
247 CRM_EX_INDETERMINATE = 112, // could not determine status
248 CRM_EX_UNSATISFIED = 113, // requested item does not satisfy constraints
249
250 // Other
251 CRM_EX_TIMEOUT = 124, // convention from timeout(1)
252 CRM_EX_MAX = 255, // ensure crm_exit_t can hold this
253 } crm_exit_t;
254
255 const char *pcmk_rc_name(int rc);
256 const char *pcmk_rc_str(int rc);
257 crm_exit_t pcmk_rc2exitc(int rc);
258 int pcmk_rc2legacy(int rc);
259 int pcmk_legacy2rc(int legacy_rc);
260 const char *pcmk_strerror(int rc);
261 const char *pcmk_errorname(int rc);
262 const char *bz2_strerror(int rc);
263 crm_exit_t crm_errno2exit(int rc);
264 const char *crm_exit_name(crm_exit_t exit_code);
265 const char *crm_exit_str(crm_exit_t exit_code);
266 _Noreturn crm_exit_t crm_exit(crm_exit_t rc);
267
268 #ifdef __cplusplus
269 }
270 #endif
271
272 #endif