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 <stdint.h>
14
15 #include <crm/cib/internal.h>
16 #include <crm/common/output.h>
17 #include <crm/common/results.h>
18 #include <crm/fencing/internal.h>
19 #include <crm/pengine/internal.h>
20 #include <crm/stonith-ng.h>
21 #include <pacemaker.h>
22 #include <pacemaker-internal.h>
23
24 static stonith_t *
25 fencing_connect(void)
26 {
27 stonith_t *st = stonith__api_new();
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 {
38 stonith__api_free(st);
39 return NULL;
40 }
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 int
68 pcmk__output_cluster_status(pcmk_scheduler_t *scheduler, stonith_t *stonith,
69 cib_t *cib, xmlNode *current_cib,
70 enum pcmk_pacemakerd_state pcmkd_state,
71 enum pcmk__fence_history fence_history,
72 uint32_t show, uint32_t show_opts,
73 const char *only_node, const char *only_rsc,
74 const char *neg_location_prefix)
75 {
76 xmlNode *cib_copy = pcmk__xml_copy(NULL, current_cib);
77 stonith_history_t *stonith_history = NULL;
78 int history_rc = 0;
79 GList *unames = NULL;
80 GList *resources = NULL;
81 pcmk__output_t *out = NULL;
82
83 int rc = pcmk_rc_ok;
84
85 if ((scheduler == NULL) || (scheduler->priv->out == NULL)) {
86 return EINVAL;
87 }
88 out = scheduler->priv->out;
89
90 rc = pcmk__update_configured_schema(&cib_copy, false);
91 if (rc != pcmk_rc_ok) {
92 cib__clean_up_connection(&cib);
93 pcmk__xml_free(cib_copy);
94 out->err(out, "Upgrade failed: %s", pcmk_rc_str(rc));
95 return rc;
96 }
97
98
99 if (fence_history != pcmk__fence_history_none) {
100 history_rc = pcmk__get_fencing_history(stonith, &stonith_history,
101 fence_history);
102 }
103
104 pcmk_reset_scheduler(scheduler);
105 scheduler->input = cib_copy;
106 cluster_status(scheduler);
107
108
109
110
111 if (pcmk_is_set(show, pcmk_section_bans)
112 || pcmk_is_set(show, pcmk_section_tickets)) {
113 pcmk__unpack_constraints(scheduler);
114 }
115
116 unames = pe__build_node_name_list(scheduler, only_node);
117 resources = pe__build_rsc_list(scheduler, only_rsc);
118
119
120 if (scheduler->dc_node == NULL) {
121 show |= pcmk_section_dc;
122 }
123
124 out->message(out, "cluster-status",
125 scheduler, pcmkd_state, pcmk_rc2exitc(history_rc),
126 stonith_history, fence_history, show, show_opts,
127 neg_location_prefix, unames, resources);
128
129 g_list_free_full(unames, free);
130 g_list_free_full(resources, free);
131
132 stonith__history_free(stonith_history);
133 stonith_history = NULL;
134 return rc;
135 }
136
137 int
138 pcmk_status(xmlNodePtr *xml)
139 {
140 cib_t *cib = NULL;
141 pcmk__output_t *out = NULL;
142 int rc = pcmk_rc_ok;
143
144 uint32_t show_opts = pcmk_show_pending
145 |pcmk_show_inactive_rscs
146 |pcmk_show_timing;
147
148 cib = cib_new();
149
150 if (cib == NULL) {
151 return pcmk_rc_cib_corrupt;
152 }
153
154 rc = pcmk__xml_output_new(&out, xml);
155 if (rc != pcmk_rc_ok) {
156 cib_delete(cib);
157 return rc;
158 }
159
160 pcmk__register_lib_messages(out);
161 pe__register_messages(out);
162 stonith__register_messages(out);
163
164 rc = pcmk__status(out, cib, pcmk__fence_history_full, pcmk_section_all,
165 show_opts, NULL, NULL, NULL, 0);
166 pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
167
168 cib_delete(cib);
169 return rc;
170 }
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 int
205 pcmk__status(pcmk__output_t *out, cib_t *cib,
206 enum pcmk__fence_history fence_history, uint32_t show,
207 uint32_t show_opts, const char *only_node, const char *only_rsc,
208 const char *neg_location_prefix, unsigned int timeout_ms)
209 {
210 xmlNode *current_cib = NULL;
211 int rc = pcmk_rc_ok;
212 stonith_t *stonith = NULL;
213 enum pcmk_pacemakerd_state pcmkd_state = pcmk_pacemakerd_state_invalid;
214 time_t last_updated = 0;
215 pcmk_scheduler_t *scheduler = NULL;
216
217 if (cib == NULL) {
218 return ENOTCONN;
219 }
220
221 if (cib->variant == cib_native) {
222 rc = pcmk__pacemakerd_status(out, crm_system_name, timeout_ms, false,
223 &pcmkd_state);
224 if (rc != pcmk_rc_ok) {
225 return rc;
226 }
227
228 last_updated = time(NULL);
229
230 switch (pcmkd_state) {
231 case pcmk_pacemakerd_state_running:
232 case pcmk_pacemakerd_state_shutting_down:
233 case pcmk_pacemakerd_state_remote:
234
235
236
237 break;
238 default:
239
240 out->message(out, "pacemakerd-health",
241 NULL, pcmkd_state, NULL, last_updated);
242 return rc;
243 }
244
245 if (fence_history != pcmk__fence_history_none) {
246 stonith = fencing_connect();
247 }
248 }
249
250 rc = cib__signon_query(out, &cib, ¤t_cib);
251 if (rc != pcmk_rc_ok) {
252 if (pcmkd_state != pcmk_pacemakerd_state_invalid) {
253
254 out->message(out, "pacemakerd-health",
255 NULL, pcmkd_state, NULL, last_updated);
256 }
257 goto done;
258 }
259
260 scheduler = pcmk_new_scheduler();
261 pcmk__mem_assert(scheduler);
262 scheduler->priv->out = out;
263
264 if ((cib->variant == cib_native) && pcmk_is_set(show, pcmk_section_times)) {
265
266 pcmk__query_node_name(out, 0, &(scheduler->priv->local_node_name), 0);
267 }
268
269 rc = pcmk__output_cluster_status(scheduler, stonith, cib, current_cib,
270 pcmkd_state, fence_history, show,
271 show_opts, only_node, only_rsc,
272 neg_location_prefix);
273 if (rc != pcmk_rc_ok) {
274 out->err(out, "Error outputting status info from the fencer or CIB");
275 }
276
277 done:
278 pcmk_free_scheduler(scheduler);
279 stonith__api_free(stonith);
280 pcmk__xml_free(current_cib);
281 return pcmk_rc_ok;
282 }