pacemaker  3.0.0-d8340737c4
Scalable High-Availability cluster resource manager
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>
19 #include <crm/fencing/internal.h>
20 #include <crm/pengine/internal.h>
21 #include <crm/stonith-ng.h> // stonith__register_messages()
22 #include <pacemaker.h>
23 #include <pacemaker-internal.h>
24 
25 static stonith_t *
26 fencing_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 
68 int
70  cib_t *cib, xmlNode *current_cib,
71  enum pcmk_pacemakerd_state pcmkd_state,
72  enum pcmk__fence_history fence_history,
73  uint32_t show, uint32_t show_opts,
74  const char *only_node, const char *only_rsc,
75  const char *neg_location_prefix)
76 {
77  xmlNode *cib_copy = pcmk__xml_copy(NULL, current_cib);
78  stonith_history_t *stonith_history = NULL;
79  int history_rc = 0;
80  GList *unames = NULL;
81  GList *resources = NULL;
82  pcmk__output_t *out = NULL;
83 
84  int rc = pcmk_rc_ok;
85 
86  if ((scheduler == NULL) || (scheduler->priv->out == NULL)) {
87  return EINVAL;
88  }
89  out = scheduler->priv->out;
90 
91  rc = pcmk__update_configured_schema(&cib_copy, false);
92  if (rc != pcmk_rc_ok) {
94  pcmk__xml_free(cib_copy);
95  out->err(out, "Upgrade failed: %s", pcmk_rc_str(rc));
96  return rc;
97  }
98 
99  /* get the stonith-history if there is evidence we need it */
100  if (fence_history != pcmk__fence_history_none) {
101  history_rc = pcmk__get_fencing_history(stonith, &stonith_history,
102  fence_history);
103  }
104 
106  scheduler->input = cib_copy;
108 
109  /* Unpack constraints if any section will need them
110  * (tickets may be referenced in constraints but not granted yet,
111  * and bans need negative location constraints) */
112  if (pcmk_is_set(show, pcmk_section_bans)
113  || pcmk_is_set(show, pcmk_section_tickets)) {
115  }
116 
117  unames = pe__build_node_name_list(scheduler, only_node);
118  resources = pe__build_rsc_list(scheduler, only_rsc);
119 
120  /* Always print DC if NULL. */
121  if (scheduler->dc_node == NULL) {
122  show |= pcmk_section_dc;
123  }
124 
125  out->message(out, "cluster-status",
126  scheduler, pcmkd_state, pcmk_rc2exitc(history_rc),
127  stonith_history, fence_history, show, show_opts,
128  neg_location_prefix, unames, resources);
129 
130  g_list_free_full(unames, free);
131  g_list_free_full(resources, free);
132 
133  stonith_history_free(stonith_history);
134  stonith_history = NULL;
135  return rc;
136 }
137 
138 int
139 pcmk_status(xmlNodePtr *xml)
140 {
141  cib_t *cib = NULL;
142  pcmk__output_t *out = NULL;
143  int rc = pcmk_rc_ok;
144 
145  uint32_t show_opts = pcmk_show_pending
148 
149  cib = cib_new();
150 
151  if (cib == NULL) {
152  return pcmk_rc_cib_corrupt;
153  }
154 
155  rc = pcmk__xml_output_new(&out, xml);
156  if (rc != pcmk_rc_ok) {
157  cib_delete(cib);
158  return rc;
159  }
160 
164 
166  show_opts, NULL, NULL, NULL, 0);
167  pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
168 
169  cib_delete(cib);
170  return rc;
171 }
172 
205 int
207  enum pcmk__fence_history fence_history, uint32_t show,
208  uint32_t show_opts, const char *only_node, const char *only_rsc,
209  const char *neg_location_prefix, unsigned int timeout_ms)
210 {
211  xmlNode *current_cib = NULL;
212  int rc = pcmk_rc_ok;
213  stonith_t *stonith = NULL;
215  time_t last_updated = 0;
216  pcmk_scheduler_t *scheduler = NULL;
217 
218  if (cib == NULL) {
219  return ENOTCONN;
220  }
221 
222  if (cib->variant == cib_native) {
223  rc = pcmk__pacemakerd_status(out, crm_system_name, timeout_ms, false,
224  &pcmkd_state);
225  if (rc != pcmk_rc_ok) {
226  return rc;
227  }
228 
229  last_updated = time(NULL);
230 
231  switch (pcmkd_state) {
235  /* Fencer and CIB may still be available while shutting down or
236  * running on a Pacemaker Remote node
237  */
238  break;
239  default:
240  // Fencer and CIB are definitely unavailable
241  out->message(out, "pacemakerd-health",
242  NULL, pcmkd_state, NULL, last_updated);
243  return rc;
244  }
245 
246  if (fence_history != pcmk__fence_history_none) {
247  stonith = fencing_connect();
248  }
249  }
250 
251  rc = cib__signon_query(out, &cib, &current_cib);
252  if (rc != pcmk_rc_ok) {
253  if (pcmkd_state != pcmk_pacemakerd_state_invalid) {
254  // Invalid at this point means we didn't query the pcmkd state
255  out->message(out, "pacemakerd-health",
256  NULL, pcmkd_state, NULL, last_updated);
257  }
258  goto done;
259  }
260 
263  scheduler->priv->out = out;
264 
265  if ((cib->variant == cib_native) && pcmk_is_set(show, pcmk_section_times)) {
266  // Currently used only in the times section
267  pcmk__query_node_name(out, 0, &(scheduler->priv->local_node_name), 0);
268  }
269 
270  rc = pcmk__output_cluster_status(scheduler, stonith, cib, current_cib,
271  pcmkd_state, fence_history, show,
272  show_opts, only_node, only_rsc,
273  neg_location_prefix);
274  if (rc != pcmk_rc_ok) {
275  out->err(out, "Error outputting status info from the fencer or CIB");
276  }
277 
278 done:
280  stonith_api_delete(stonith);
281  pcmk__xml_free(current_cib);
282  return pcmk_rc_ok;
283 }
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
Definition: xml.c:805
Control output from tools.
void stonith__register_messages(pcmk__output_t *out)
Definition: st_output.c:604
cib_t * cib_new(void)
Create a new CIB connection object.
Definition: cib_client.c:562
int cib__signon_query(pcmk__output_t *out, cib_t **cib, xmlNode **cib_object)
Definition: cib_utils.c:841
int(* message)(pcmk__output_t *out, const char *message_id,...)
pcmk__fence_history
Control how much of the fencing history is output.
Definition: pcmki_fence.h:22
void pe_reset_working_set(pcmk_scheduler_t *scheduler)
Reset scheduler data to default state without freeing it.
Definition: status.c:393
crm_exit_t pcmk_rc2exitc(int rc)
Map a function return code to the most similar exit code.
Definition: results.c:810
int pcmk__output_cluster_status(pcmk_scheduler_t *scheduler, 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)
Definition: pcmk_status.c:69
int pcmk__update_configured_schema(xmlNode **xml, bool to_logs)
Update XML from its configured schema to the latest major series.
Definition: schemas.c:1159
pcmk__scheduler_private_t * priv
Definition: scheduler.h:99
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)
High Level API.
char * crm_system_name
Definition: utils.c:44
void pcmk__xml_output_finish(pcmk__output_t *out, crm_exit_t exit_status, xmlNodePtr *xml)
Definition: output.c:271
GList * pe__build_rsc_list(pcmk_scheduler_t *scheduler, const char *s)
Definition: utils.c:847
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition: results.c:609
gboolean cluster_status(pcmk_scheduler_t *scheduler)
Definition: status.c:103
pcmk_node_t * dc_node
Definition: scheduler.h:85
void cib_delete(cib_t *cib)
Free all memory used by CIB connection.
Definition: cib_client.c:721
stonith_t * stonith_api_new(void)
Definition: st_client.c:1858
void pcmk__xml_free(xmlNode *xml)
Definition: xml.c:789
stonith_t * st
Definition: pcmk_fence.c:30
void pcmk__unpack_constraints(pcmk_scheduler_t *scheduler)
#define pcmk_section_all
Definition: output.h:49
int pcmk__xml_output_new(pcmk__output_t **out, xmlNodePtr *xml)
Definition: output.c:244
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:80
int(*) int(*) void(* err)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
void pcmk__register_lib_messages(pcmk__output_t *out)
Definition: pcmk_output.c:2709
GList * pe__build_node_name_list(pcmk_scheduler_t *scheduler, const char *s)
Definition: utils.c:814
void pe__register_messages(pcmk__output_t *out)
Definition: pe_output.c:3470
int(* connect)(stonith_t *st, const char *name, int *stonith_fd)
Connect to the local fencer.
Definition: stonith-ng.h:190
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, unsigned int timeout_ms)
Definition: pcmk_status.c:206
int cib__clean_up_connection(cib_t **cib)
Definition: cib_utils.c:920
pcmk_scheduler_t * pe_new_working_set(void)
Create a new object to hold scheduler data.
Definition: status.c:34
Function and executable result codes.
pcmk_pacemakerd_state
void pe_free_working_set(pcmk_scheduler_t *scheduler)
Free scheduler data.
Definition: status.c:56
void stonith_api_delete(stonith_t *st)
Definition: st_client.c:1725
pcmk_scheduler_t * scheduler
stonith_api_operations_t * cmds
Definition: stonith-ng.h:573
xmlNode * input
Definition: scheduler.h:81
void stonith_history_free(stonith_history_t *history)
Definition: st_client.c:761
Fencing aka. STONITH.
#define pcmk__mem_assert(ptr)
This structure contains everything that makes up a single output formatter.
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:654
enum cib_variant variant
Definition: cib_types.h:315
int pcmk_status(xmlNodePtr *xml)
Output cluster status formatted like crm_mon --output-as=xml
Definition: pcmk_status.c:139