pacemaker 2.1.8-2.1.8
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pcmk_status.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-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 General Public License version 2
7 * or later (GPLv2+) WITHOUT ANY WARRANTY.
8 */
9
10#include <crm_internal.h>
11
12#include <stdbool.h>
13#include <stddef.h>
14#include <stdint.h>
15
16#include <crm/cib/internal.h>
17#include <crm/common/output.h>
18#include <crm/common/results.h>
21#include <crm/stonith-ng.h> // stonith__register_messages()
22#include <pacemaker.h>
23#include <pacemaker-internal.h>
24
25static stonith_t *
26fencing_connect(void)
27{
29 int rc = pcmk_rc_ok;
30
31 if (st == NULL) {
32 return NULL;
33 }
34
35 rc = st->cmds->connect(st, crm_system_name, NULL);
36 if (rc == pcmk_rc_ok) {
37 return st;
38 } else {
40 return NULL;
41 }
42}
43
71int
73 xmlNode *current_cib,
74 enum pcmk_pacemakerd_state pcmkd_state,
75 enum pcmk__fence_history fence_history,
76 uint32_t show, uint32_t show_opts,
77 const char *only_node, const char *only_rsc,
78 const char *neg_location_prefix, bool simple_output)
79{
80 xmlNode *cib_copy = pcmk__xml_copy(NULL, current_cib);
81 stonith_history_t *stonith_history = NULL;
82 int history_rc = 0;
84 GList *unames = NULL;
85 GList *resources = NULL;
86
87 int rc = pcmk_rc_ok;
88
89 rc = pcmk__update_configured_schema(&cib_copy, false);
90 if (rc != pcmk_rc_ok) {
92 free_xml(cib_copy);
93 out->err(out, "Upgrade failed: %s", pcmk_rc_str(rc));
94 return rc;
95 }
96
97 /* get the stonith-history if there is evidence we need it */
98 if (fence_history != pcmk__fence_history_none) {
99 history_rc = pcmk__get_fencing_history(stonith, &stonith_history,
100 fence_history);
101 }
102
106
107 scheduler->input = cib_copy;
108 scheduler->priv = out;
110
111 if ((cib->variant == cib_native) && pcmk_is_set(show, pcmk_section_times)) {
112 if (pcmk__our_nodename == NULL) {
113 // Currently used only in the times section
114 pcmk__query_node_name(out, 0, &pcmk__our_nodename, 0);
115 }
117 }
118
119 /* Unpack constraints if any section will need them
120 * (tickets may be referenced in constraints but not granted yet,
121 * and bans need negative location constraints) */
125 }
126
127 unames = pe__build_node_name_list(scheduler, only_node);
128 resources = pe__build_rsc_list(scheduler, only_rsc);
129
130 /* Always print DC if NULL. */
131 if (scheduler->dc_node == NULL) {
132 show |= pcmk_section_dc;
133 }
134
135 if (simple_output) {
137 } else {
138 out->message(out, "cluster-status",
139 scheduler, pcmkd_state, pcmk_rc2exitc(history_rc),
140 stonith_history, fence_history, show, show_opts,
141 neg_location_prefix, unames, resources);
142 }
143
144 g_list_free_full(unames, free);
145 g_list_free_full(resources, free);
146
147 stonith_history_free(stonith_history);
148 stonith_history = NULL;
150 return rc;
151}
152
153int
154pcmk_status(xmlNodePtr *xml)
155{
156 cib_t *cib = NULL;
157 pcmk__output_t *out = NULL;
158 int rc = pcmk_rc_ok;
159
160 uint32_t show_opts = pcmk_show_pending
163
164 cib = cib_new();
165
166 if (cib == NULL) {
167 return pcmk_rc_cib_corrupt;
168 }
169
170 rc = pcmk__xml_output_new(&out, xml);
171 if (rc != pcmk_rc_ok) {
172 cib_delete(cib);
173 return rc;
174 }
175
179
181 show_opts, NULL, NULL, NULL, false, 0);
183
184 cib_delete(cib);
185 return rc;
186}
187
223int
225 enum pcmk__fence_history fence_history, uint32_t show,
226 uint32_t show_opts, const char *only_node, const char *only_rsc,
227 const char *neg_location_prefix, bool simple_output,
228 unsigned int timeout_ms)
229{
230 xmlNode *current_cib = NULL;
231 int rc = pcmk_rc_ok;
232 stonith_t *stonith = NULL;
234 time_t last_updated = 0;
235
236 if (cib == NULL) {
237 return ENOTCONN;
238 }
239
240 if (cib->variant == cib_native) {
241 rc = pcmk__pacemakerd_status(out, crm_system_name, timeout_ms, false,
242 &pcmkd_state);
243 if (rc != pcmk_rc_ok) {
244 return rc;
245 }
246
247 last_updated = time(NULL);
248
249 switch (pcmkd_state) {
253 /* Fencer and CIB may still be available while shutting down or
254 * running on a Pacemaker Remote node
255 */
256 break;
257 default:
258 // Fencer and CIB are definitely unavailable
259 out->message(out, "pacemakerd-health",
260 NULL, pcmkd_state, NULL, last_updated);
261 return rc;
262 }
263
264 if (fence_history != pcmk__fence_history_none) {
265 stonith = fencing_connect();
266 }
267 }
268
269 rc = cib__signon_query(out, &cib, &current_cib);
270 if (rc != pcmk_rc_ok) {
271 if (pcmkd_state != pcmk_pacemakerd_state_invalid) {
272 // Invalid at this point means we didn't query the pcmkd state
273 out->message(out, "pacemakerd-health",
274 NULL, pcmkd_state, NULL, last_updated);
275 }
276 goto done;
277 }
278
279 rc = pcmk__output_cluster_status(out, stonith, cib, current_cib,
280 pcmkd_state, fence_history, show,
281 show_opts, only_node, only_rsc,
282 neg_location_prefix, simple_output);
283 if (rc != pcmk_rc_ok) {
284 out->err(out, "Error outputting status info from the fencer or CIB");
285 }
286
287done:
288 stonith_api_delete(stonith);
289 free_xml(current_cib);
290 return pcmk_rc_ok;
291}
292
304int
307{
308 int nodes_online = 0;
309 int nodes_standby = 0;
310 int nodes_maint = 0;
311 GString *offline_nodes = NULL;
312 bool no_dc = false;
313 bool offline = false;
314 bool has_warnings = false;
315
316 if (scheduler->dc_node == NULL) {
317 has_warnings = true;
318 no_dc = true;
319 }
320
321 for (GList *iter = scheduler->nodes; iter != NULL; iter = iter->next) {
322 pcmk_node_t *node = (pcmk_node_t *) iter->data;
323
324 if (node->details->standby && node->details->online) {
325 nodes_standby++;
326 } else if (node->details->maintenance && node->details->online) {
327 nodes_maint++;
328 } else if (node->details->online) {
329 nodes_online++;
330 } else {
331 pcmk__add_word(&offline_nodes, 1024, "offline node:");
332 pcmk__add_word(&offline_nodes, 0, pcmk__node_name(node));
333 has_warnings = true;
334 offline = true;
335 }
336 }
337
338 if (has_warnings) {
339 out->info(out, "CLUSTER WARN: %s%s%s",
340 no_dc ? "No DC" : "",
341 no_dc && offline ? ", " : "",
342 (offline? (const char *) offline_nodes->str : ""));
343
344 if (offline_nodes != NULL) {
345 g_string_free(offline_nodes, TRUE);
346 }
347
348 } else {
349 char *nodes_standby_s = NULL;
350 char *nodes_maint_s = NULL;
351
352 if (nodes_standby > 0) {
353 nodes_standby_s = crm_strdup_printf(", %d standby node%s",
354 nodes_standby,
355 pcmk__plural_s(nodes_standby));
356 }
357
358 if (nodes_maint > 0) {
359 nodes_maint_s = crm_strdup_printf(", %d maintenance node%s",
360 nodes_maint,
361 pcmk__plural_s(nodes_maint));
362 }
363
364 out->info(out, "CLUSTER OK: %d node%s online%s%s, "
365 "%d resource instance%s configured",
366 nodes_online, pcmk__plural_s(nodes_online),
367 nodes_standby_s != NULL ? nodes_standby_s : "",
368 nodes_maint_s != NULL ? nodes_maint_s : "",
370
371 free(nodes_standby_s);
372 free(nodes_maint_s);
373 }
374
375 if (has_warnings) {
376 return pcmk_rc_error;
377 } else {
378 return pcmk_rc_ok;
379 }
380 /* coverity[leaked_storage] False positive */
381}
int cib__clean_up_connection(cib_t **cib)
Definition cib_utils.c:1046
int cib__signon_query(pcmk__output_t *out, cib_t **cib, xmlNode **cib_object)
Definition cib_utils.c:965
void cib_delete(cib_t *cib)
Free all memory used by CIB connection.
Definition cib_client.c:791
cib_t * cib_new(void)
Create a new CIB connection object.
Definition cib_client.c:616
@ cib_native
Definition cib_types.h:30
char * pcmk__our_nodename
Node name of the local node.
Definition logging.c:48
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:98
char * crm_system_name
Definition utils.c:50
void stonith__register_messages(pcmk__output_t *out)
Definition st_output.c:604
pcmk_pacemakerd_state
@ pcmk_pacemakerd_state_invalid
@ pcmk_pacemakerd_state_running
@ pcmk_pacemakerd_state_shutting_down
@ pcmk_pacemakerd_state_remote
pcmk_scheduler_t * scheduler
Control output from tools.
@ pcmk_show_timing
Definition output.h:62
@ pcmk_show_pending
Definition output.h:65
@ pcmk_show_inactive_rscs
Definition output.h:63
#define pcmk_section_all
Definition output.h:49
@ pcmk_section_times
Definition output.h:29
@ pcmk_section_bans
Definition output.h:41
@ pcmk_section_tickets
Definition output.h:40
@ pcmk_section_dc
Definition output.h:28
void pcmk__xml_output_finish(pcmk__output_t *out, crm_exit_t exit_status, xmlNodePtr *xml)
Definition output.c:271
int pcmk__xml_output_new(pcmk__output_t **out, xmlNodePtr *xml)
Definition output.c:244
High Level API.
stonith_t * st
Definition pcmk_fence.c:28
int pcmk__status(pcmk__output_t *out, cib_t *cib, enum pcmk__fence_history fence_history, uint32_t show, uint32_t show_opts, const char *only_node, const char *only_rsc, const char *neg_location_prefix, bool simple_output, unsigned int timeout_ms)
int pcmk__output_cluster_status(pcmk__output_t *out, stonith_t *stonith, cib_t *cib, xmlNode *current_cib, enum pcmk_pacemakerd_state pcmkd_state, enum pcmk__fence_history fence_history, uint32_t show, uint32_t show_opts, const char *only_node, const char *only_rsc, const char *neg_location_prefix, bool simple_output)
Definition pcmk_status.c:72
int pcmk_status(xmlNodePtr *xml)
Output cluster status formatted like crm_mon --output-as=xml
int pcmk__output_simple_status(pcmk__output_t *out, const pcmk_scheduler_t *scheduler)
int pcmk__pacemakerd_status(pcmk__output_t *out, const char *ipc_name, unsigned int message_timeout_ms, bool show_output, enum pcmk_pacemakerd_state *state)
int pcmk__get_fencing_history(stonith_t *st, stonith_history_t **stonith_history, enum pcmk__fence_history fence_history)
Fetch fencing history, optionally reducing it.
Definition pcmk_fence.c:612
pcmk__fence_history
Control how much of the fencing history is output.
Definition pcmki_fence.h:18
@ pcmk__fence_history_none
Definition pcmki_fence.h:19
@ pcmk__fence_history_full
Definition pcmki_fence.h:21
void pcmk__register_lib_messages(pcmk__output_t *out)
void pcmk__unpack_constraints(pcmk_scheduler_t *scheduler)
GList * pe__build_rsc_list(pcmk_scheduler_t *scheduler, const char *s)
Definition utils.c:848
void pe__register_messages(pcmk__output_t *out)
Definition pe_output.c:3440
GList * pe__build_node_name_list(pcmk_scheduler_t *scheduler, const char *s)
Definition utils.c:815
Function and executable result codes.
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition results.c:501
@ pcmk_rc_ok
Definition results.h:162
@ pcmk_rc_error
Definition results.h:157
@ pcmk_rc_cib_corrupt
Definition results.h:150
crm_exit_t pcmk_rc2exitc(int rc)
Map a function return code to the most similar exit code.
Definition results.c:702
#define pcmk__mem_assert(ptr)
@ pcmk_sched_no_compat
Definition scheduler.h:170
#define pcmk__set_scheduler_flags(scheduler, flags_to_set)
int pcmk__update_configured_schema(xmlNode **xml, bool to_logs)
Update XML from its configured schema to the latest major series.
Definition schemas.c:1257
void pe_free_working_set(pcmk_scheduler_t *scheduler)
Free scheduler data.
Definition status.c:50
pcmk_scheduler_t * pe_new_working_set(void)
Create a new object to hold scheduler data.
Definition status.c:34
gboolean cluster_status(pcmk_scheduler_t *scheduler)
Definition status.c:96
Fencing aka. STONITH.
void stonith_history_free(stonith_history_t *history)
Definition st_client.c:762
void stonith_api_delete(stonith_t *st)
Definition st_client.c:1726
stonith_t * stonith_api_new(void)
Definition st_client.c:1833
#define pcmk__plural_s(i)
enum cib_variant variant
Definition cib_types.h:385
This structure contains everything that makes up a single output formatter.
int(* message)(pcmk__output_t *out, const char *message_id,...)
int(* info)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
int(*) int(*) void(* err)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
struct pe_node_shared_s * details
Definition nodes.h:167
gboolean online
Definition nodes.h:80
gboolean standby
Definition nodes.h:82
gboolean maintenance
Definition nodes.h:104
xmlNode * input
Definition scheduler.h:196
pcmk_node_t * dc_node
Definition scheduler.h:203
const char * localhost
Definition scheduler.h:251
int(* connect)(stonith_t *st, const char *name, int *stonith_fd)
Connect to the local fencer.
Definition stonith-ng.h:164
stonith_api_operations_t * cmds
Definition stonith-ng.h:551
void free_xml(xmlNode *child)
Definition xml.c:867
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
Definition xml.c:883