This source file includes following definitions.
- fencing_connect
- pcmk__output_cluster_status
- pcmk_status
- pcmk__status
1
2
3
4
5
6
7
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>
22 #include <pacemaker.h>
23 #include <pacemaker-internal.h>
24
25 static stonith_t *
26 fencing_connect(void)
27 {
28 stonith_t *st = stonith_api_new();
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 {
39 stonith_api_delete(st);
40 return NULL;
41 }
42 }
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 int
69 pcmk__output_cluster_status(pcmk_scheduler_t *scheduler, stonith_t *stonith,
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) {
93 cib__clean_up_connection(&cib);
94 pcmk__xml_free(cib_copy);
95 out->err(out, "Upgrade failed: %s", pcmk_rc_str(rc));
96 return rc;
97 }
98
99
100 if (fence_history != pcmk__fence_history_none) {
101 history_rc = pcmk__get_fencing_history(stonith, &stonith_history,
102 fence_history);
103 }
104
105 pe_reset_working_set(scheduler);
106 scheduler->input = cib_copy;
107 cluster_status(scheduler);
108
109
110
111
112 if (pcmk_is_set(show, pcmk_section_bans)
113 || pcmk_is_set(show, pcmk_section_tickets)) {
114 pcmk__unpack_constraints(scheduler);
115 }
116
117 unames = pe__build_node_name_list(scheduler, only_node);
118 resources = pe__build_rsc_list(scheduler, only_rsc);
119
120
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
146 |pcmk_show_inactive_rscs
147 |pcmk_show_timing;
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
161 pcmk__register_lib_messages(out);
162 pe__register_messages(out);
163 stonith__register_messages(out);
164
165 rc = pcmk__status(out, cib, pcmk__fence_history_full, pcmk_section_all,
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 int
206 pcmk__status(pcmk__output_t *out, cib_t *cib,
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;
214 enum pcmk_pacemakerd_state pcmkd_state = pcmk_pacemakerd_state_invalid;
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) {
232 case pcmk_pacemakerd_state_running:
233 case pcmk_pacemakerd_state_shutting_down:
234 case pcmk_pacemakerd_state_remote:
235
236
237
238 break;
239 default:
240
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, ¤t_cib);
252 if (rc != pcmk_rc_ok) {
253 if (pcmkd_state != pcmk_pacemakerd_state_invalid) {
254
255 out->message(out, "pacemakerd-health",
256 NULL, pcmkd_state, NULL, last_updated);
257 }
258 goto done;
259 }
260
261 scheduler = pe_new_working_set();
262 pcmk__mem_assert(scheduler);
263 scheduler->priv->out = out;
264
265 if ((cib->variant == cib_native) && pcmk_is_set(show, pcmk_section_times)) {
266
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:
279 pe_free_working_set(scheduler);
280 stonith_api_delete(stonith);
281 pcmk__xml_free(current_cib);
282 return pcmk_rc_ok;
283 }