pacemaker 2.1.6-6fdc9deea29
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pcmk_status.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2023 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>
20#include <crm/stonith-ng.h>
21#include <pacemaker.h>
22#include <pacemaker-internal.h>
23
24static stonith_t *
25fencing_connect(void)
26{
28 int rc = pcmk_rc_ok;
29
30 if (st == NULL) {
31 return NULL;
32 }
33
34 rc = st->cmds->connect(st, crm_system_name, NULL);
35 if (rc == pcmk_rc_ok) {
36 return st;
37 } else {
39 return NULL;
40 }
41}
42
70int
72 xmlNode *current_cib,
73 enum pcmk_pacemakerd_state pcmkd_state,
74 enum pcmk__fence_history fence_history,
75 uint32_t show, uint32_t show_opts,
76 const char *only_node, const char *only_rsc,
77 const char *neg_location_prefix, bool simple_output)
78{
79 xmlNode *cib_copy = copy_xml(current_cib);
80 stonith_history_t *stonith_history = NULL;
81 int history_rc = 0;
83 GList *unames = NULL;
84 GList *resources = NULL;
85
86 int rc = pcmk_rc_ok;
87
88 if (cli_config_update(&cib_copy, NULL, FALSE) == FALSE) {
90 free_xml(cib_copy);
92 out->err(out, "Upgrade failed: %s", pcmk_rc_str(rc));
93 return rc;
94 }
95
96 /* get the stonith-history if there is evidence we need it */
97 if (fence_history != pcmk__fence_history_none) {
98 history_rc = pcmk__get_fencing_history(stonith, &stonith_history,
99 fence_history);
100 }
101
103 CRM_ASSERT(data_set != NULL);
105
106 data_set->input = cib_copy;
107 data_set->priv = out;
109
110 if ((cib->variant == cib_native) && pcmk_is_set(show, pcmk_section_times)) {
111 if (pcmk__our_nodename == NULL) {
112 // Currently used only in the times section
113 pcmk__query_node_name(out, 0, &pcmk__our_nodename, 0);
114 }
116 }
117
118 /* Unpack constraints if any section will need them
119 * (tickets may be referenced in constraints but not granted yet,
120 * and bans need negative location constraints) */
123 }
124
125 unames = pe__build_node_name_list(data_set, only_node);
126 resources = pe__build_rsc_list(data_set, only_rsc);
127
128 /* Always print DC if NULL. */
129 if (data_set->dc_node == NULL) {
130 show |= pcmk_section_dc;
131 }
132
133 if (simple_output) {
135 } else {
136 out->message(out, "cluster-status",
137 data_set, pcmkd_state, pcmk_rc2exitc(history_rc),
138 stonith_history, fence_history, show, show_opts,
139 neg_location_prefix, unames, resources);
140 }
141
142 g_list_free_full(unames, free);
143 g_list_free_full(resources, free);
144
145 stonith_history_free(stonith_history);
146 stonith_history = NULL;
148 return rc;
149}
150
151int
152pcmk_status(xmlNodePtr *xml)
153{
154 cib_t *cib = NULL;
155 pcmk__output_t *out = NULL;
156 int rc = pcmk_rc_ok;
157
159
160 cib = cib_new();
161
162 if (cib == NULL) {
163 return pcmk_rc_cib_corrupt;
164 }
165
166 rc = pcmk__xml_output_new(&out, xml);
167 if (rc != pcmk_rc_ok) {
168 cib_delete(cib);
169 return rc;
170 }
171
175
177 show_opts, NULL, NULL, NULL, false, 0);
178 pcmk__xml_output_finish(out, xml);
179
180 cib_delete(cib);
181 return rc;
182}
183
219int
221 enum pcmk__fence_history fence_history, uint32_t show,
222 uint32_t show_opts, const char *only_node, const char *only_rsc,
223 const char *neg_location_prefix, bool simple_output,
224 unsigned int timeout_ms)
225{
226 xmlNode *current_cib = NULL;
227 int rc = pcmk_rc_ok;
228 stonith_t *stonith = NULL;
230 time_t last_updated = 0;
231
232 if (cib == NULL) {
233 return ENOTCONN;
234 }
235
236 if (cib->variant == cib_native) {
237 rc = pcmk__pacemakerd_status(out, crm_system_name, timeout_ms, false,
238 &pcmkd_state);
239 if (rc != pcmk_rc_ok) {
240 return rc;
241 }
242
243 last_updated = time(NULL);
244
245 switch (pcmkd_state) {
249 /* Fencer and CIB may still be available while shutting down or
250 * running on a Pacemaker Remote node
251 */
252 break;
253 default:
254 // Fencer and CIB are definitely unavailable
255 out->message(out, "pacemakerd-health",
256 NULL, pcmkd_state, NULL, last_updated);
257 return rc;
258 }
259
260 if (fence_history != pcmk__fence_history_none) {
261 stonith = fencing_connect();
262 }
263 }
264
265 rc = cib__signon_query(out, &cib, &current_cib);
266 if (rc != pcmk_rc_ok) {
267 if (pcmkd_state != pcmk_pacemakerd_state_invalid) {
268 // Invalid at this point means we didn't query the pcmkd state
269 out->message(out, "pacemakerd-health",
270 NULL, pcmkd_state, NULL, last_updated);
271 }
272 goto done;
273 }
274
275 rc = pcmk__output_cluster_status(out, stonith, cib, current_cib,
276 pcmkd_state, fence_history, show,
277 show_opts, only_node, only_rsc,
278 neg_location_prefix, simple_output);
279 if (rc != pcmk_rc_ok) {
280 out->err(out, "Error outputting status info from the fencer or CIB");
281 }
282
283done:
284 stonith_api_delete(stonith);
285 free_xml(current_cib);
286 return pcmk_rc_ok;
287}
288
289/* This is an internal-only function that is planned to be deprecated and removed.
290 * It should only ever be called from crm_mon.
291 */
292int
295{
296 int nodes_online = 0;
297 int nodes_standby = 0;
298 int nodes_maintenance = 0;
299 GString *offline_nodes = NULL;
300 bool no_dc = false;
301 bool offline = false;
302 bool has_warnings = false;
303
304 if (data_set->dc_node == NULL) {
305 has_warnings = true;
306 no_dc = true;
307 }
308
309 for (GList *iter = data_set->nodes; iter != NULL; iter = iter->next) {
310 pe_node_t *node = (pe_node_t *) iter->data;
311
312 if (node->details->standby && node->details->online) {
313 nodes_standby++;
314 } else if (node->details->maintenance && node->details->online) {
315 nodes_maintenance++;
316 } else if (node->details->online) {
317 nodes_online++;
318 } else {
319 pcmk__add_word(&offline_nodes, 1024, "offline node:");
320 pcmk__add_word(&offline_nodes, 0, pe__node_name(node));
321 has_warnings = true;
322 offline = true;
323 }
324 }
325
326 if (has_warnings) {
327 out->info(out, "CLUSTER WARN: %s%s%s",
328 no_dc ? "No DC" : "",
329 no_dc && offline ? ", " : "",
330 (offline? (const char *) offline_nodes->str : ""));
331
332 if (offline_nodes != NULL) {
333 g_string_free(offline_nodes, TRUE);
334 }
335
336 } else {
337 char *nodes_standby_s = NULL;
338 char *nodes_maint_s = NULL;
339
340 if (nodes_standby > 0) {
341 nodes_standby_s = crm_strdup_printf(", %d standby node%s", nodes_standby,
342 pcmk__plural_s(nodes_standby));
343 }
344
345 if (nodes_maintenance > 0) {
346 nodes_maint_s = crm_strdup_printf(", %d maintenance node%s",
347 nodes_maintenance,
348 pcmk__plural_s(nodes_maintenance));
349 }
350
351 out->info(out, "CLUSTER OK: %d node%s online%s%s, "
352 "%d resource instance%s configured",
353 nodes_online, pcmk__plural_s(nodes_online),
354 nodes_standby_s != NULL ? nodes_standby_s : "",
355 nodes_maint_s != NULL ? nodes_maint_s : "",
357
358 free(nodes_standby_s);
359 free(nodes_maint_s);
360 }
361
362 if (has_warnings) {
363 return pcmk_rc_error;
364 } else {
365 return pcmk_rc_ok;
366 }
367 /* coverity[leaked_storage] False positive */
368}
int cib__clean_up_connection(cib_t **cib)
Definition cib_utils.c:799
int cib__signon_query(pcmk__output_t *out, cib_t **cib, xmlNode **cib_object)
Definition cib_utils.c:745
void cib_delete(cib_t *cib)
Free all memory used by CIB connection.
Definition cib_client.c:700
cib_t * cib_new(void)
Create a new CIB connection object.
Definition cib_client.c:535
@ 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:121
char * crm_system_name
Definition utils.c:51
void stonith__register_messages(pcmk__output_t *out)
Definition st_output.c:598
pcmk_pacemakerd_state
@ pcmk_pacemakerd_state_invalid
@ pcmk_pacemakerd_state_running
@ pcmk_pacemakerd_state_shutting_down
@ pcmk_pacemakerd_state_remote
pe_working_set_t * data_set
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
int pcmk__xml_output_new(pcmk__output_t **out, xmlNodePtr *xml)
Definition output.c:236
void pcmk__xml_output_finish(pcmk__output_t *out, xmlNodePtr *xml)
Definition output.c:258
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_simple_status(pcmk__output_t *out, const pe_working_set_t *data_set)
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:71
int pcmk_status(xmlNodePtr *xml)
Output cluster status formatted like crm_mon --output-as=xml
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:604
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(pe_working_set_t *data_set)
#define pe_flag_no_compat
Definition pe_types.h:148
GList * pe__build_rsc_list(pe_working_set_t *data_set, const char *s)
Definition utils.c:863
GList * pe__build_node_name_list(pe_working_set_t *data_set, const char *s)
Definition utils.c:831
void pe__register_messages(pcmk__output_t *out)
Definition pe_output.c:3106
#define pe__set_working_set_flags(working_set, flags_to_set)
Definition internal.h:65
Function and executable result codes.
#define CRM_ASSERT(expr)
Definition results.h:42
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition results.c:488
@ pcmk_rc_ok
Definition results.h:151
@ pcmk_rc_schema_validation
Definition results.h:131
@ pcmk_rc_error
Definition results.h:147
@ pcmk_rc_cib_corrupt
Definition results.h:140
crm_exit_t pcmk_rc2exitc(int rc)
Map a function return code to the most similar exit code.
Definition results.c:689
gboolean cluster_status(pe_working_set_t *data_set)
Definition status.c:71
void pe_free_working_set(pe_working_set_t *data_set)
Free a working set.
Definition status.c:50
pe_working_set_t * pe_new_working_set(void)
Create a new working set.
Definition status.c:34
Fencing aka. STONITH.
void stonith_history_free(stonith_history_t *history)
Definition st_client.c:755
void stonith_api_delete(stonith_t *st)
Definition st_client.c:1709
stonith_t * stonith_api_new(void)
Definition st_client.c:1817
#define pcmk__plural_s(i)
enum cib_variant variant
Definition cib_types.h:206
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 pe_types.h:268
gboolean online
Definition pe_types.h:236
gboolean standby
Definition pe_types.h:237
gboolean maintenance
Definition pe_types.h:245
xmlNode * input
Definition pe_types.h:160
pe_node_t * dc_node
Definition pe_types.h:165
const char * localhost
Definition pe_types.h:202
int(* connect)(stonith_t *st, const char *name, int *stonith_fd)
Connect to the local fencer.
Definition stonith-ng.h:169
stonith_api_operations_t * cmds
Definition stonith-ng.h:556
gboolean cli_config_update(xmlNode **xml, int *best_version, gboolean to_logs)
Definition schemas.c:1197
void free_xml(xmlNode *child)
Definition xml.c:813
xmlNode * copy_xml(xmlNode *src_node)
Definition xml.c:819