1 /*
2 * Copyright 2019-2022 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 #ifndef PCMK__PACEMAKER__H
11 # define PCMK__PACEMAKER__H
12
13 # include <glib.h>
14 # include <libxml/tree.h>
15 # include <crm/cib/cib_types.h>
16 # include <crm/pengine/pe_types.h>
17
18 # include <crm/stonith-ng.h>
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 /**
25 * \file
26 * \brief High Level API
27 * \ingroup pacemaker
28 */
29
30
31 /*!
32 * \brief Modify operation of running a cluster simulation.
33 */
34 enum pcmk_sim_flags {
35 pcmk_sim_none = 0,
36 pcmk_sim_all_actions = 1 << 0,
37 pcmk_sim_show_pending = 1 << 1,
38 pcmk_sim_process = 1 << 2,
39 pcmk_sim_show_scores = 1 << 3,
40 pcmk_sim_show_utilization = 1 << 4,
41 pcmk_sim_simulate = 1 << 5,
42 pcmk_sim_sanitized = 1 << 6,
43 pcmk_sim_verbose = 1 << 7,
44 };
45
46 /*!
47 * \brief Synthetic cluster events that can be injected into the cluster
48 * for running simulations.
49 */
50 typedef struct {
51 /*! A list of node names (gchar *) to simulate bringing online */
52 GList *node_up;
53 /*! A list of node names (gchar *) to simulate bringing offline */
54 GList *node_down;
55 /*! A list of node names (gchar *) to simulate failing */
56 GList *node_fail;
57 /*! A list of operations (gchar *) to inject. The format of these strings
58 * is described in the "Operation Specification" section of crm_simulate
59 * help output.
60 */
61 GList *op_inject;
62 /*! A list of operations (gchar *) that should return a given error code
63 * if they fail. The format of these strings is described in the
64 * "Operation Specification" section of crm_simulate help output.
65 */
66 GList *op_fail;
67 /*! A list of tickets (gchar *) to simulate granting */
68 GList *ticket_grant;
69 /*! A list of tickets (gchar *) to simulate revoking */
70 GList *ticket_revoke;
71 /*! A list of tickets (gchar *) to simulate putting on standby */
72 GList *ticket_standby;
73 /*! A list of tickets (gchar *) to simulate activating */
74 GList *ticket_activate;
75 /*! Does the cluster have an active watchdog device? */
76 char *watchdog;
77 /*! Does the cluster have quorum? */
78 char *quorum;
79 } pcmk_injections_t;
80
81 /*!
82 * \brief Get controller status
83 *
84 * \param[in,out] xml The destination for the result, as an XML tree.
85 * \param[in] dest_node Destination node for request
86 * \param[in] message_timeout_ms Message timeout
87 *
88 * \return Standard Pacemaker return code
89 */
90 int pcmk_controller_status(xmlNodePtr *xml, char *dest_node, unsigned int message_timeout_ms);
91
92 /*!
93 * \brief Get designated controller
94 *
95 * \param[in,out] xml The destination for the result, as an XML tree.
96 * \param[in] message_timeout_ms Message timeout
97 *
98 * \return Standard Pacemaker return code
99 */
100 int pcmk_designated_controller(xmlNodePtr *xml, unsigned int message_timeout_ms);
101
102 /*!
103 * \brief Free a :pcmk_injections_t structure
104 *
105 * \param[in,out] injections The structure to be freed
106 */
107 void pcmk_free_injections(pcmk_injections_t *injections);
108
109 /*!
110 * \brief Get and output \p pacemakerd status
111 *
112 * \param[in,out] xml Destination for the result, as an XML tree
113 * \param[in] ipc_name IPC name for request
114 * \param[in] message_timeout_ms How long to wait for a reply from the
115 * \p pacemakerd API. If 0,
116 * \p pcmk_ipc_dispatch_sync will be used.
117 * If positive, \p pcmk_ipc_dispatch_main
118 * will be used, and a new mainloop will be
119 * created for this purpose (freed before
120 * return).
121 *
122 * \return Standard Pacemaker return code
123 */
124 int pcmk_pacemakerd_status(xmlNodePtr *xml, const char *ipc_name,
125 unsigned int message_timeout_ms);
126
127 /*!
128 * \brief Calculate and output resource operation digests
129 *
130 * \param[out] xml Where to store XML with result
131 * \param[in] rsc Resource to calculate digests for
132 * \param[in] node Node whose operation history should be used
133 * \param[in] overrides Hash table of configuration parameters to override
134 * \param[in] data_set Cluster working set (with status)
135 *
136 * \return Standard Pacemaker return code
137 */
138 int pcmk_resource_digests(xmlNodePtr *xml, pe_resource_t *rsc,
139 pe_node_t *node, GHashTable *overrides,
140 pe_working_set_t *data_set);
141
142 /**
143 * \brief Simulate a cluster's response to events.
144 *
145 * This high-level function essentially implements crm_simulate(8). It operates
146 * on an input CIB file and various lists of events that can be simulated. It
147 * optionally writes out a variety of artifacts to show the results of the
148 * simulation. Output can be modified with various flags.
149 *
150 * \param[in,out] xml The destination for the result, as an XML tree.
151 * \param[in,out] data_set Working set for the cluster.
152 * \param[in] events A structure containing cluster events
153 * (node up/down, tickets, injected operations)
154 * \param[in] flags A bitfield of :pcmk_sim_flags to modify
155 * operation of the simulation.
156 * \param[in] section_opts Which portions of the cluster status output
157 * should be displayed?
158 * \param[in] use_date The date to set the cluster's time to
159 * (may be NULL).
160 * \param[in] input_file The source CIB file, which may be overwritten by
161 * this function (may be NULL).
162 * \param[in] graph_file Where to write the XML-formatted transition graph
163 * (may be NULL, in which case no file will be
164 * written).
165 * \param[in] dot_file Where to write the dot(1) formatted transition
166 * graph (may be NULL, in which case no file will
167 * be written). See \p pcmk__write_sim_dotfile().
168 *
169 * \return Standard Pacemaker return code
170 */
171 int pcmk_simulate(xmlNodePtr *xml, pe_working_set_t *data_set,
172 pcmk_injections_t *injections, unsigned int flags,
173 unsigned int section_opts, char *use_date, char *input_file,
174 char *graph_file, char *dot_file);
175
176 /*!
177 * \brief Get nodes list
178 *
179 * \param[in,out] xml The destination for the result, as an XML tree.
180 * \param[in] node_types Node type(s) to return (default: all)
181 *
182 * \return Standard Pacemaker return code
183 */
184 int pcmk_list_nodes(xmlNodePtr *xml, char *node_types);
185
186 /*!
187 * \brief Output the current status of the cluster, formatted in the same way
188 * that `crm_mon --output-as=xml` would.
189 *
190 * \param[in,out] xml The destination for the result, as an XML tree.
191 *
192 * \return Standard Pacemaker return code
193 */
194 int pcmk_status(xmlNodePtr *xml);
195
196 /*!
197 * \brief Check whether each rule in a list is in effect
198 *
199 * \param[in,out] xml The destination for the result, as an XML tree
200 * \param[in] input The CIB XML to check (if \c NULL, use current CIB)
201 * \param[in] date Check whether the rule is in effect at this date and
202 * time (if \c NULL, use current date and time)
203 * \param[in] rule_ids The IDs of the rules to check, as a <tt>NULL</tt>-
204 * terminated list.
205 *
206 * \return Standard Pacemaker return code
207 */
208 int pcmk_check_rules(xmlNodePtr *xml, xmlNodePtr input, const crm_time_t *date,
209 const char **rule_ids);
210
211 /*!
212 * \brief Check whether a given rule is in effect
213 *
214 * \param[in,out] xml The destination for the result, as an XML tree
215 * \param[in] input The CIB XML to check (if \c NULL, use current CIB)
216 * \param[in] date Check whether the rule is in effect at this date and
217 * time (if \c NULL, use current date and time)
218 * \param[in] rule_ids The ID of the rule to check
219 *
220 * \return Standard Pacemaker return code
221 */
222 static inline int
223 pcmk_check_rule(xmlNodePtr *xml, xmlNodePtr input, const crm_time_t *date,
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
224 const char *rule_id)
225 {
226 const char *rule_ids[] = {rule_id, NULL};
227 return pcmk_check_rules(xml, input, date, rule_ids);
228 }
229
230 /*
231 * \enum pcmk_rc_disp_flags
232 * \brief Bit flags to control which fields of result code info are displayed
233 */
234 enum pcmk_rc_disp_flags {
235 pcmk_rc_disp_none = 0, //!< (Does nothing)
236 pcmk_rc_disp_code = (1 << 0), //!< Display result code number
237 pcmk_rc_disp_name = (1 << 1), //!< Display result code name
238 pcmk_rc_disp_desc = (1 << 2), //!< Display result code description
239 };
240
241 /*
242 * \brief Display the name and/or description of a result code
243 *
244 * \param[in,out] xml The destination for the result, as an XML tree
245 * \param[in] code The result code
246 * \param[in] type Interpret \c code as this type of result code.
247 * Supported values: \c pcmk_result_legacy,
248 * \c pcmk_result_rc, \c pcmk_result_exitcode.
249 * \param[in] flags Group of \c pcmk_rc_disp_flags
250 *
251 * \return Standard Pacemaker return code
252 */
253 int pcmk_show_result_code(xmlNodePtr *xml, int code, enum pcmk_result_type type,
254 uint32_t flags);
255
256 /*!
257 * \brief List all valid result codes in a particular family
258 *
259 * \param[in,out] xml The destination for the result, as an XML tree
260 * \param[in] type The family of result codes to list. Supported
261 * values: \c pcmk_result_legacy, \c pcmk_result_rc,
262 * \c pcmk_result_exitcode.
263 * \param[in] flags Group of \c pcmk_rc_disp_flags
264 *
265 * \return Standard Pacemaker return code
266 */
267 int pcmk_list_result_codes(xmlNodePtr *xml, enum pcmk_result_type type,
268 uint32_t flags);
269
270 #ifdef BUILD_PUBLIC_LIBPACEMAKER
271
272 /*!
273 * \brief Ask the cluster to perform fencing
274 *
275 * \param[in] st A connection to the fencer API
276 * \param[in] target The node that should be fenced
277 * \param[in] action The fencing action (on, off, reboot) to perform
278 * \param[in] name Who requested the fence action?
279 * \param[in] timeout How long to wait for the operation to complete (in ms)
280 * \param[in] tolerance If a successful action for \p target happened within
281 * this many ms, return 0 without performing the action
282 * again
283 * \param[in] delay Apply this delay (in milliseconds) before initiating the
284 * fencing action (a value of -1 applies no delay and also
285 * disables any fencing delay from pcmk_delay_base and
286 * pcmk_delay_max)
287 * \param[out] reason If not NULL, where to put descriptive failure reason
288 *
289 * \return Standard Pacemaker return code
290 * \note If \p reason is not NULL, the caller is responsible for freeing its
291 * returned value.
292 */
293 int pcmk_request_fencing(stonith_t *st, const char *target, const char *action,
294 const char *name, unsigned int timeout,
295 unsigned int tolerance, int delay, char **reason);
296
297 /*!
298 * \brief List the fencing operations that have occurred for a specific node.
299 *
300 * \note If \p xml is not NULL, it will be freed first and the previous
301 * contents lost.
302 *
303 * \param[in,out] xml The destination for the result, as an XML tree.
304 * \param[in] st A connection to the STONITH API.
305 * \param[in] target The node to get history for.
306 * \param[in] timeout How long to wait for the operation to complete (in ms).
307 * \param[in] quiet Suppress most output.
308 * \param[in] verbose Include additional output.
309 * \param[in] broadcast Gather fencing history from all nodes.
310 * \param[in] cleanup Clean up fencing history after listing.
311 *
312 * \return Standard Pacemaker return code
313 */
314 int pcmk_fence_history(xmlNodePtr *xml, stonith_t *st, char *target,
315 unsigned int timeout, bool quiet, int verbose,
316 bool broadcast, bool cleanup);
317
318 /*!
319 * \brief List all installed STONITH agents.
320 *
321 * \note If \p xml is not NULL, it will be freed first and the previous
322 * contents lost.
323 *
324 * \param[in,out] xml The destination for the result, as an XML tree.
325 * \param[in] st A connection to the STONITH API.
326 * \param[in] timeout How long to wait for the operation to complete (in ms).
327 *
328 * \return Standard Pacemaker return code
329 */
330 int pcmk_fence_installed(xmlNodePtr *xml, stonith_t *st, unsigned int timeout);
331
332 /*!
333 * \brief When was a device last fenced?
334 *
335 * \note If \p xml is not NULL, it will be freed first and the previous
336 * contents lost.
337 *
338 * \param[in,out] xml The destination for the result, as an XML tree.
339 * \param[in] target The node that was fenced.
340 * \param[in] as_nodeid
341 *
342 * \return Standard Pacemaker return code
343 */
344 int pcmk_fence_last(xmlNodePtr *xml, const char *target, bool as_nodeid);
345
346 /*!
347 * \brief List nodes that can be fenced.
348 *
349 * \note If \p xml is not NULL, it will be freed first and the previous
350 * contents lost.
351 *
352 * \param[in,out] xml The destination for the result, as an XML tree
353 * \param[in] st A connection to the STONITH API
354 * \param[in] device_id Resource ID of fence device to check
355 * \param[in] timeout How long to wait for the operation to complete (in ms)
356 *
357 * \return Standard Pacemaker return code
358 */
359 int pcmk_fence_list_targets(xmlNodePtr *xml, stonith_t *st,
360 const char *device_id, unsigned int timeout);
361
362 /*!
363 * \brief Get metadata for a resource.
364 *
365 * \note If \p xml is not NULL, it will be freed first and the previous
366 * contents lost.
367 *
368 * \param[in,out] xml The destination for the result, as an XML tree.
369 * \param[in] st A connection to the STONITH API.
370 * \param[in] agent The fence agent to get metadata for.
371 * \param[in] timeout How long to wait for the operation to complete (in ms).
372 *
373 * \return Standard Pacemaker return code
374 */
375 int pcmk_fence_metadata(xmlNodePtr *xml, stonith_t *st, char *agent,
376 unsigned int timeout);
377
378 /*!
379 * \brief List registered fence devices.
380 *
381 * \note If \p xml is not NULL, it will be freed first and the previous
382 * contents lost.
383 *
384 * \param[in,out] xml The destination for the result, as an XML tree.
385 * \param[in] st A connection to the STONITH API.
386 * \param[in] target If not NULL, only return devices that can fence
387 * this node.
388 * \param[in] timeout How long to wait for the operation to complete (in ms).
389 *
390 * \return Standard Pacemaker return code
391 */
392 int pcmk_fence_registered(xmlNodePtr *xml, stonith_t *st, char *target,
393 unsigned int timeout);
394
395 /*!
396 * \brief Register a fencing level for a specific node, node regex, or attribute.
397 *
398 * \p target can take three different forms:
399 * - name=value, in which case \p target is an attribute.
400 * - @pattern, in which case \p target is a node regex.
401 * - Otherwise, \p target is a node name.
402 *
403 * \param[in] st A connection to the STONITH API.
404 * \param[in] target The object to register a fencing level for.
405 * \param[in] fence_level Index number of level to add.
406 * \param[in] devices Devices to use in level.
407 *
408 * \return Standard Pacemaker return code
409 */
410 int pcmk_fence_register_level(stonith_t *st, char *target, int fence_level,
411 stonith_key_value_t *devices);
412
413 /*!
414 * \brief Unregister a fencing level for a specific node, node regex, or attribute.
415 *
416 * \p target can take three different forms:
417 * - name=value, in which case \p target is an attribute.
418 * - @pattern, in which case \p target is a node regex.
419 * - Otherwise, \p target is a node name.
420 *
421 * \param[in] st A connection to the STONITH API.
422 * \param[in] target The object to unregister a fencing level for.
423 * \param[in] fence_level Index number of level to remove.
424 *
425 * \return Standard Pacemaker return code
426 */
427 int pcmk_fence_unregister_level(stonith_t *st, char *target, int fence_level);
428
429 /*!
430 * \brief Validate a STONITH device configuration.
431 *
432 * \note If \p xml is not NULL, it will be freed first and the previous
433 * contents lost.
434 *
435 * \param[in,out] xml The destination for the result, as an XML tree.
436 * \param[in] st A connection to the STONITH API.
437 * \param[in] agent The agent to validate (for example, "fence_xvm").
438 * \param[in] id STONITH device ID (may be NULL).
439 * \param[in] params STONITH device configuration parameters.
440 * \param[in] timeout How long to wait for the operation to complete (in ms).
441 *
442 * \return Standard Pacemaker return code
443 */
444 int pcmk_fence_validate(xmlNodePtr *xml, stonith_t *st, const char *agent,
445 const char *id, stonith_key_value_t *params,
446 unsigned int timeout);
447 #endif
448
449 #ifdef __cplusplus
450 }
451 #endif
452
453 #endif