This source file includes following definitions.
- cli_resource_print_cts_constraints
- cli_resource_print_cts
- cli_resource_print_operations
- cli_resource_print
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- add_resource_name
- PCMK__OUTPUT_ARGS
- crm_resource_register_messages
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdint.h>
13
14 #include <crm_resource.h>
15 #include <crm/common/lists_internal.h>
16 #include <crm/common/output.h>
17 #include <crm/common/results.h>
18
19 #define cons_string(x) x?x:"NA"
20 void
21 cli_resource_print_cts_constraints(pe_working_set_t * data_set)
22 {
23 pcmk__output_t *out = data_set->priv;
24 xmlNode *xml_obj = NULL;
25 xmlNode *lifetime = NULL;
26 xmlNode *cib_constraints = pcmk_find_cib_element(data_set->input,
27 XML_CIB_TAG_CONSTRAINTS);
28
29 for (xml_obj = pcmk__xe_first_child(cib_constraints); xml_obj != NULL;
30 xml_obj = pcmk__xe_next(xml_obj)) {
31 const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
32
33 if (id == NULL) {
34 continue;
35 }
36
37
38 lifetime = first_named_child(xml_obj, "lifetime");
39 if (pe_evaluate_rules(lifetime, NULL, data_set->now, NULL) == FALSE) {
40 continue;
41 }
42
43 if (!pcmk__str_eq(XML_CONS_TAG_RSC_DEPEND, crm_element_name(xml_obj), pcmk__str_casei)) {
44 continue;
45 }
46
47 out->info(out, "Constraint %s %s %s %s %s %s %s",
48 crm_element_name(xml_obj),
49 cons_string(crm_element_value(xml_obj, XML_ATTR_ID)),
50 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE)),
51 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET)),
52 cons_string(crm_element_value(xml_obj, XML_RULE_ATTR_SCORE)),
53 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE)),
54 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET_ROLE)));
55 }
56 }
57
58 void
59 cli_resource_print_cts(pe_resource_t * rsc, pcmk__output_t *out)
60 {
61 const char *host = NULL;
62 bool needs_quorum = TRUE;
63 const char *rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE);
64 const char *rprov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
65 const char *rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
66 pe_node_t *node = pe__current_node(rsc);
67
68 if (pcmk__str_eq(rclass, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_casei)) {
69 needs_quorum = FALSE;
70 } else {
71
72 }
73
74 if (node != NULL) {
75 host = node->details->uname;
76 }
77
78 out->info(out, "Resource: %s %s %s %s %s %s %s %s %d %lld %#.16llx",
79 crm_element_name(rsc->xml), rsc->id,
80 rsc->clone_name ? rsc->clone_name : rsc->id, rsc->parent ? rsc->parent->id : "NA",
81 rprov ? rprov : "NA", rclass, rtype, host ? host : "NA", needs_quorum, rsc->flags,
82 rsc->flags);
83
84 g_list_foreach(rsc->children, (GFunc) cli_resource_print_cts, out);
85 }
86
87
88 int
89 cli_resource_print_operations(const char *rsc_id, const char *host_uname,
90 bool active, pe_working_set_t * data_set)
91 {
92 pcmk__output_t *out = data_set->priv;
93 int rc = pcmk_rc_no_output;
94 GList *ops = find_operations(rsc_id, host_uname, active, data_set);
95
96 if (!ops) {
97 return rc;
98 }
99
100 out->begin_list(out, NULL, NULL, "Resource Operations");
101 rc = pcmk_rc_ok;
102
103 for (GList *lpc = ops; lpc != NULL; lpc = lpc->next) {
104 xmlNode *xml_op = (xmlNode *) lpc->data;
105 out->message(out, "node-and-op", data_set, xml_op);
106 }
107
108 out->end_list(out);
109 return rc;
110 }
111
112
113 int
114 cli_resource_print(pe_resource_t *rsc, pe_working_set_t *data_set, bool expanded)
115 {
116 pcmk__output_t *out = data_set->priv;
117 uint32_t show_opts = pcmk_show_pending;
118 GList *all = NULL;
119
120 all = g_list_prepend(all, (gpointer) "*");
121
122 out->begin_list(out, NULL, NULL, "Resource Config");
123 out->message(out, crm_map_element_name(rsc->xml), show_opts, rsc, all, all);
124 out->message(out, "resource-config", rsc, !expanded);
125 out->end_list(out);
126
127 g_list_free(all);
128 return pcmk_rc_ok;
129 }
130
131 PCMK__OUTPUT_ARGS("attribute-list", "pe_resource_t *", "char *", "GHashTable *")
132 static int
133 attribute_list_default(pcmk__output_t *out, va_list args) {
134 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
135 char *attr = va_arg(args, char *);
136 GHashTable *params = va_arg(args, GHashTable *);
137
138 const char *value = NULL;
139
140 if (params != NULL) {
141 value = g_hash_table_lookup(params, attr);
142 }
143 if (value != NULL) {
144 out->begin_list(out, NULL, NULL, "Attributes");
145 out->list_item(out, attr, "%s", value);
146 out->end_list(out);
147 } else {
148 out->err(out, "Attribute '%s' not found for '%s'", attr, rsc->id);
149 }
150
151 return pcmk_rc_ok;
152 }
153
154 PCMK__OUTPUT_ARGS("agent-status", "int", "const char *", "const char *", "const char *",
155 "const char *", "const char *", "crm_exit_t", "const char *")
156 static int
157 agent_status_default(pcmk__output_t *out, va_list args) {
158 int status = va_arg(args, int);
159 const char *action = va_arg(args, const char *);
160 const char *name = va_arg(args, const char *);
161 const char *class = va_arg(args, const char *);
162 const char *provider = va_arg(args, const char *);
163 const char *type = va_arg(args, const char *);
164 crm_exit_t rc = va_arg(args, crm_exit_t);
165 const char *exit_reason = va_arg(args, const char *);
166
167 if (status == PCMK_EXEC_DONE) {
168
169
170
171 out->info(out, "Operation %s%s%s (%s%s%s:%s) returned %d (%s%s%s)",
172 action,
173 ((name == NULL)? "" : " for "), ((name == NULL)? "" : name),
174 class,
175 ((provider == NULL)? "" : ":"),
176 ((provider == NULL)? "" : provider),
177 type, (int) rc, services_ocf_exitcode_str((int) rc),
178 ((exit_reason == NULL)? "" : ": "),
179 ((exit_reason == NULL)? "" : exit_reason));
180 } else {
181
182
183
184 out->err(out,
185 "Operation %s%s%s (%s%s%s:%s) could not be executed (%s%s%s)",
186 action,
187 ((name == NULL)? "" : " for "), ((name == NULL)? "" : name),
188 class,
189 ((provider == NULL)? "" : ":"),
190 ((provider == NULL)? "" : provider),
191 type, pcmk_exec_status_str(status),
192 ((exit_reason == NULL)? "" : ": "),
193 ((exit_reason == NULL)? "" : exit_reason));
194 }
195
196 return pcmk_rc_ok;
197 }
198
199 PCMK__OUTPUT_ARGS("agent-status", "int", "const char *", "const char *", "const char *",
200 "const char *", "const char *", "crm_exit_t", "const char *")
201 static int
202 agent_status_xml(pcmk__output_t *out, va_list args) {
203 int status = va_arg(args, int);
204 const char *action G_GNUC_UNUSED = va_arg(args, const char *);
205 const char *name G_GNUC_UNUSED = va_arg(args, const char *);
206 const char *class G_GNUC_UNUSED = va_arg(args, const char *);
207 const char *provider G_GNUC_UNUSED = va_arg(args, const char *);
208 const char *type G_GNUC_UNUSED = va_arg(args, const char *);
209 crm_exit_t rc = va_arg(args, crm_exit_t);
210 const char *exit_reason = va_arg(args, const char *);
211
212 char *exit_str = pcmk__itoa(rc);
213 char *status_str = pcmk__itoa(status);
214
215 pcmk__output_create_xml_node(out, "agent-status",
216 "code", exit_str,
217 "message", services_ocf_exitcode_str((int) rc),
218 "execution_code", status_str,
219 "execution_message", pcmk_exec_status_str(status),
220 "reason", exit_reason,
221 NULL);
222
223 free(exit_str);
224 free(status_str);
225
226 return pcmk_rc_ok;
227 }
228
229 PCMK__OUTPUT_ARGS("attribute-list", "pe_resource_t *", "char *", "GHashTable *")
230 static int
231 attribute_list_text(pcmk__output_t *out, va_list args) {
232 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
233 char *attr = va_arg(args, char *);
234 GHashTable *params = va_arg(args, GHashTable *);
235
236 const char *value = NULL;
237
238 if (params != NULL) {
239 value = g_hash_table_lookup(params, attr);
240 }
241 if (value != NULL) {
242 pcmk__formatted_printf(out, "%s\n", value);
243 } else {
244 out->err(out, "Attribute '%s' not found for '%s'", attr, rsc->id);
245 }
246
247 return pcmk_rc_ok;
248 }
249
250 PCMK__OUTPUT_ARGS("override", "const char *", "const char *", "const char *")
251 static int
252 override_default(pcmk__output_t *out, va_list args) {
253 const char *rsc_name = va_arg(args, const char *);
254 const char *name = va_arg(args, const char *);
255 const char *value = va_arg(args, const char *);
256
257 if (rsc_name == NULL) {
258 out->list_item(out, NULL, "Overriding the cluster configuration with '%s' = '%s'",
259 name, value);
260 } else {
261 out->list_item(out, NULL, "Overriding the cluster configuration for '%s' with '%s' = '%s'",
262 rsc_name, name, value);
263 }
264
265 return pcmk_rc_ok;
266 }
267
268 PCMK__OUTPUT_ARGS("override", "const char *", "const char *", "const char *")
269 static int
270 override_xml(pcmk__output_t *out, va_list args) {
271 const char *rsc_name = va_arg(args, const char *);
272 const char *name = va_arg(args, const char *);
273 const char *value = va_arg(args, const char *);
274
275 xmlNodePtr node = pcmk__output_create_xml_node(out, "override",
276 "name", name,
277 "value", value,
278 NULL);
279
280 if (rsc_name != NULL) {
281 crm_xml_add(node, "rsc", rsc_name);
282 }
283
284 return pcmk_rc_ok;
285 }
286
287 PCMK__OUTPUT_ARGS("property-list", "pe_resource_t *", "char *")
288 static int
289 property_list_default(pcmk__output_t *out, va_list args) {
290 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
291 char *attr = va_arg(args, char *);
292
293 const char *value = crm_element_value(rsc->xml, attr);
294
295 if (value != NULL) {
296 out->begin_list(out, NULL, NULL, "Properties");
297 out->list_item(out, attr, "%s", value);
298 out->end_list(out);
299 }
300
301 return pcmk_rc_ok;
302 }
303
304 PCMK__OUTPUT_ARGS("property-list", "pe_resource_t *", "char *")
305 static int
306 property_list_text(pcmk__output_t *out, va_list args) {
307 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
308 char *attr = va_arg(args, char *);
309
310 const char *value = crm_element_value(rsc->xml, attr);
311
312 if (value != NULL) {
313 pcmk__formatted_printf(out, "%s\n", value);
314 }
315
316 return pcmk_rc_ok;
317 }
318
319 PCMK__OUTPUT_ARGS("resource-agent-action", "int", "const char *", "const char *",
320 "const char *", "const char *", "const char *", "GHashTable *",
321 "crm_exit_t", "int", "const char *", "char *", "char *")
322 static int
323 resource_agent_action_default(pcmk__output_t *out, va_list args) {
324 int verbose = va_arg(args, int);
325
326 const char *class = va_arg(args, const char *);
327 const char *provider = va_arg(args, const char *);
328 const char *type = va_arg(args, const char *);
329 const char *rsc_name = va_arg(args, const char *);
330 const char *action = va_arg(args, const char *);
331 GHashTable *overrides = va_arg(args, GHashTable *);
332 crm_exit_t rc = va_arg(args, crm_exit_t);
333 int status = va_arg(args, int);
334 const char *exit_reason = va_arg(args, const char *);
335 char *stdout_data = va_arg(args, char *);
336 char *stderr_data = va_arg(args, char *);
337
338 if (overrides) {
339 GHashTableIter iter;
340 const char *name = NULL;
341 const char *value = NULL;
342
343 out->begin_list(out, NULL, NULL, "overrides");
344
345 g_hash_table_iter_init(&iter, overrides);
346 while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &value)) {
347 out->message(out, "override", rsc_name, name, value);
348 }
349
350 out->end_list(out);
351 }
352
353 out->message(out, "agent-status", status, action, rsc_name, class, provider,
354 type, rc, exit_reason);
355
356
357 if (verbose == 0 && pcmk__str_eq(action, "validate-all", pcmk__str_casei)) {
358 return pcmk_rc_ok;
359 }
360
361 if (stdout_data || stderr_data) {
362 xmlNodePtr doc = NULL;
363
364 if (stdout_data != NULL) {
365 doc = string2xml(stdout_data);
366 }
367 if (doc != NULL) {
368 out->output_xml(out, "command", stdout_data);
369 xmlFreeNode(doc);
370 } else {
371 out->subprocess_output(out, rc, stdout_data, stderr_data);
372 }
373 }
374
375 return pcmk_rc_ok;
376 }
377
378 PCMK__OUTPUT_ARGS("resource-agent-action", "int", "const char *", "const char *",
379 "const char *", "const char *", "const char *", "GHashTable *",
380 "crm_exit_t", "int", "const char *", "char *", "char *")
381 static int
382 resource_agent_action_xml(pcmk__output_t *out, va_list args) {
383 int verbose G_GNUC_UNUSED = va_arg(args, int);
384
385 const char *class = va_arg(args, const char *);
386 const char *provider = va_arg(args, const char *);
387 const char *type = va_arg(args, const char *);
388 const char *rsc_name = va_arg(args, const char *);
389 const char *action = va_arg(args, const char *);
390 GHashTable *overrides = va_arg(args, GHashTable *);
391 crm_exit_t rc = va_arg(args, crm_exit_t);
392 int status = va_arg(args, int);
393 const char *exit_reason = va_arg(args, const char *);
394 char *stdout_data = va_arg(args, char *);
395 char *stderr_data = va_arg(args, char *);
396
397 xmlNodePtr node = pcmk__output_xml_create_parent(out, "resource-agent-action",
398 "action", action,
399 "class", class,
400 "type", type,
401 NULL);
402
403 if (rsc_name) {
404 crm_xml_add(node, "rsc", rsc_name);
405 }
406
407 if (provider) {
408 crm_xml_add(node, "provider", provider);
409 }
410
411 if (overrides) {
412 GHashTableIter iter;
413 const char *name = NULL;
414 const char *value = NULL;
415
416 out->begin_list(out, NULL, NULL, "overrides");
417
418 g_hash_table_iter_init(&iter, overrides);
419 while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &value)) {
420 out->message(out, "override", rsc_name, name, value);
421 }
422
423 out->end_list(out);
424 }
425
426 out->message(out, "agent-status", status, action, rsc_name, class, provider,
427 type, rc, exit_reason);
428
429 if (stdout_data || stderr_data) {
430 xmlNodePtr doc = NULL;
431
432 if (stdout_data != NULL) {
433 doc = string2xml(stdout_data);
434 }
435 if (doc != NULL) {
436 out->output_xml(out, "command", stdout_data);
437 xmlFreeNode(doc);
438 } else {
439 out->subprocess_output(out, rc, stdout_data, stderr_data);
440 }
441 }
442
443 pcmk__output_xml_pop_parent(out);
444 return pcmk_rc_ok;
445 }
446
447 PCMK__OUTPUT_ARGS("resource-check-list", "resource_checks_t *")
448 static int
449 resource_check_list_default(pcmk__output_t *out, va_list args) {
450 resource_checks_t *checks = va_arg(args, resource_checks_t *);
451
452 pe_resource_t *parent = uber_parent(checks->rsc);
453 int rc = pcmk_rc_no_output;
454 bool printed = false;
455
456 if (checks->flags != 0 || checks->lock_node != NULL) {
457 printed = true;
458 out->begin_list(out, NULL, NULL, "Resource Checks");
459 }
460
461 if (pcmk_is_set(checks->flags, rsc_remain_stopped)) {
462 out->list_item(out, "check", "Configuration specifies '%s' should remain stopped",
463 parent->id);
464 }
465
466 if (pcmk_is_set(checks->flags, rsc_unpromotable)) {
467 out->list_item(out, "check", "Configuration specifies '%s' should not be promoted",
468 parent->id);
469 }
470
471 if (pcmk_is_set(checks->flags, rsc_unmanaged)) {
472 out->list_item(out, "check", "Configuration prevents cluster from stopping or starting unmanaged '%s'",
473 parent->id);
474 }
475
476 if (checks->lock_node) {
477 out->list_item(out, "check", "'%s' is locked to node %s due to shutdown",
478 parent->id, checks->lock_node);
479 }
480
481 if (printed) {
482 out->end_list(out);
483 rc = pcmk_rc_ok;
484 }
485
486 return rc;
487 }
488
489 PCMK__OUTPUT_ARGS("resource-check-list", "resource_checks_t *")
490 static int
491 resource_check_list_xml(pcmk__output_t *out, va_list args) {
492 resource_checks_t *checks = va_arg(args, resource_checks_t *);
493
494 pe_resource_t *parent = uber_parent(checks->rsc);
495
496 xmlNodePtr node = pcmk__output_create_xml_node(out, "check",
497 "id", parent->id,
498 NULL);
499
500 if (pcmk_is_set(checks->flags, rsc_remain_stopped)) {
501 pcmk__xe_set_bool_attr(node, "remain_stopped", true);
502 }
503
504 if (pcmk_is_set(checks->flags, rsc_unpromotable)) {
505 pcmk__xe_set_bool_attr(node, "promotable", false);
506 }
507
508 if (pcmk_is_set(checks->flags, rsc_unmanaged)) {
509 pcmk__xe_set_bool_attr(node, "unmanaged", true);
510 }
511
512 if (checks->lock_node) {
513 crm_xml_add(node, "locked-to", checks->lock_node);
514 }
515
516 return pcmk_rc_ok;
517 }
518
519 PCMK__OUTPUT_ARGS("resource-search-list", "GList *", "gchar *")
520 static int
521 resource_search_list_default(pcmk__output_t *out, va_list args)
522 {
523 GList *nodes = va_arg(args, GList *);
524 gchar *requested_name = va_arg(args, gchar *);
525
526 bool printed = false;
527 int rc = pcmk_rc_no_output;
528
529 if (!out->is_quiet(out) && nodes == NULL) {
530 out->err(out, "resource %s is NOT running", requested_name);
531 return rc;
532 }
533
534 for (GList *lpc = nodes; lpc != NULL; lpc = lpc->next) {
535 node_info_t *ni = (node_info_t *) lpc->data;
536
537 if (!printed) {
538 out->begin_list(out, NULL, NULL, "Nodes");
539 printed = true;
540 rc = pcmk_rc_ok;
541 }
542
543 if (out->is_quiet(out)) {
544 out->list_item(out, "node", "%s", ni->node_name);
545 } else {
546 const char *role_text = "";
547
548 if (ni->promoted) {
549 #ifdef PCMK__COMPAT_2_0
550 role_text = " " RSC_ROLE_PROMOTED_LEGACY_S;
551 #else
552 role_text = " " RSC_ROLE_PROMOTED_S;
553 #endif
554 }
555 out->list_item(out, "node", "resource %s is running on: %s%s",
556 requested_name, ni->node_name, role_text);
557 }
558 }
559
560 if (printed) {
561 out->end_list(out);
562 }
563
564 return rc;
565 }
566
567 PCMK__OUTPUT_ARGS("resource-search-list", "GList *", "gchar *")
568 static int
569 resource_search_list_xml(pcmk__output_t *out, va_list args)
570 {
571 GList *nodes = va_arg(args, GList *);
572 gchar *requested_name = va_arg(args, gchar *);
573
574 pcmk__output_xml_create_parent(out, "nodes",
575 "resource", requested_name,
576 NULL);
577
578 for (GList *lpc = nodes; lpc != NULL; lpc = lpc->next) {
579 node_info_t *ni = (node_info_t *) lpc->data;
580 xmlNodePtr sub_node = pcmk__output_create_xml_text_node(out, "node", ni->node_name);
581
582 if (ni->promoted) {
583 crm_xml_add(sub_node, "state", "promoted");
584 }
585 }
586
587 return pcmk_rc_ok;
588 }
589
590 PCMK__OUTPUT_ARGS("resource-reasons-list", "cib_t *", "GList *", "pe_resource_t *",
591 "pe_node_t *")
592 static int
593 resource_reasons_list_default(pcmk__output_t *out, va_list args)
594 {
595 cib_t *cib_conn = va_arg(args, cib_t *);
596 GList *resources = va_arg(args, GList *);
597 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
598 pe_node_t *node = va_arg(args, pe_node_t *);
599
600 const char *host_uname = (node == NULL)? NULL : node->details->uname;
601
602 out->begin_list(out, NULL, NULL, "Resource Reasons");
603
604 if ((rsc == NULL) && (host_uname == NULL)) {
605 GList *lpc = NULL;
606 GList *hosts = NULL;
607
608 for (lpc = resources; lpc != NULL; lpc = lpc->next) {
609 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
610 rsc->fns->location(rsc, &hosts, TRUE);
611
612 if (hosts == NULL) {
613 out->list_item(out, "reason", "Resource %s is not running", rsc->id);
614 } else {
615 out->list_item(out, "reason", "Resource %s is running", rsc->id);
616 }
617
618 cli_resource_check(out, cib_conn, rsc);
619 g_list_free(hosts);
620 hosts = NULL;
621 }
622
623 } else if ((rsc != NULL) && (host_uname != NULL)) {
624 if (resource_is_running_on(rsc, host_uname)) {
625 out->list_item(out, "reason", "Resource %s is running on host %s",
626 rsc->id, host_uname);
627 } else {
628 out->list_item(out, "reason", "Resource %s is not running on host %s",
629 rsc->id, host_uname);
630 }
631
632 cli_resource_check(out, cib_conn, rsc);
633
634 } else if ((rsc == NULL) && (host_uname != NULL)) {
635 const char* host_uname = node->details->uname;
636 GList *allResources = node->details->allocated_rsc;
637 GList *activeResources = node->details->running_rsc;
638 GList *unactiveResources = pcmk__subtract_lists(allResources, activeResources, (GCompareFunc) strcmp);
639 GList *lpc = NULL;
640
641 for (lpc = activeResources; lpc != NULL; lpc = lpc->next) {
642 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
643 out->list_item(out, "reason", "Resource %s is running on host %s",
644 rsc->id, host_uname);
645 cli_resource_check(out, cib_conn, rsc);
646 }
647
648 for(lpc = unactiveResources; lpc != NULL; lpc = lpc->next) {
649 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
650 out->list_item(out, "reason", "Resource %s is assigned to host %s but not running",
651 rsc->id, host_uname);
652 cli_resource_check(out, cib_conn, rsc);
653 }
654
655 g_list_free(allResources);
656 g_list_free(activeResources);
657 g_list_free(unactiveResources);
658
659 } else if ((rsc != NULL) && (host_uname == NULL)) {
660 GList *hosts = NULL;
661
662 rsc->fns->location(rsc, &hosts, TRUE);
663 out->list_item(out, "reason", "Resource %s is %srunning",
664 rsc->id, (hosts? "" : "not "));
665 cli_resource_check(out, cib_conn, rsc);
666 g_list_free(hosts);
667 }
668
669 out->end_list(out);
670 return pcmk_rc_ok;
671 }
672
673 PCMK__OUTPUT_ARGS("resource-reasons-list", "cib_t *", "GList *", "pe_resource_t *",
674 "pe_node_t *")
675 static int
676 resource_reasons_list_xml(pcmk__output_t *out, va_list args)
677 {
678 cib_t *cib_conn = va_arg(args, cib_t *);
679 GList *resources = va_arg(args, GList *);
680 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
681 pe_node_t *node = va_arg(args, pe_node_t *);
682
683 const char *host_uname = (node == NULL)? NULL : node->details->uname;
684
685 xmlNodePtr xml_node = pcmk__output_xml_create_parent(out, "reason", NULL);
686
687 if ((rsc == NULL) && (host_uname == NULL)) {
688 GList *lpc = NULL;
689 GList *hosts = NULL;
690
691 pcmk__output_xml_create_parent(out, "resources", NULL);
692
693 for (lpc = resources; lpc != NULL; lpc = lpc->next) {
694 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
695
696 rsc->fns->location(rsc, &hosts, TRUE);
697
698 pcmk__output_xml_create_parent(out, "resource",
699 "id", rsc->id,
700 "running", pcmk__btoa(hosts != NULL),
701 NULL);
702
703 cli_resource_check(out, cib_conn, rsc);
704 pcmk__output_xml_pop_parent(out);
705 g_list_free(hosts);
706 hosts = NULL;
707 }
708
709 pcmk__output_xml_pop_parent(out);
710
711 } else if ((rsc != NULL) && (host_uname != NULL)) {
712 if (resource_is_running_on(rsc, host_uname)) {
713 crm_xml_add(xml_node, "running_on", host_uname);
714 }
715
716 cli_resource_check(out, cib_conn, rsc);
717
718 } else if ((rsc == NULL) && (host_uname != NULL)) {
719 const char* host_uname = node->details->uname;
720 GList *allResources = node->details->allocated_rsc;
721 GList *activeResources = node->details->running_rsc;
722 GList *unactiveResources = pcmk__subtract_lists(allResources, activeResources, (GCompareFunc) strcmp);
723 GList *lpc = NULL;
724
725 pcmk__output_xml_create_parent(out, "resources", NULL);
726
727 for (lpc = activeResources; lpc != NULL; lpc = lpc->next) {
728 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
729
730 pcmk__output_xml_create_parent(out, "resource",
731 "id", rsc->id,
732 "running", "true",
733 "host", host_uname,
734 NULL);
735
736 cli_resource_check(out, cib_conn, rsc);
737 pcmk__output_xml_pop_parent(out);
738 }
739
740 for(lpc = unactiveResources; lpc != NULL; lpc = lpc->next) {
741 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
742
743 pcmk__output_xml_create_parent(out, "resource",
744 "id", rsc->id,
745 "running", "false",
746 "host", host_uname,
747 NULL);
748
749 cli_resource_check(out, cib_conn, rsc);
750 pcmk__output_xml_pop_parent(out);
751 }
752
753 pcmk__output_xml_pop_parent(out);
754 g_list_free(allResources);
755 g_list_free(activeResources);
756 g_list_free(unactiveResources);
757
758 } else if ((rsc != NULL) && (host_uname == NULL)) {
759 GList *hosts = NULL;
760
761 rsc->fns->location(rsc, &hosts, TRUE);
762 crm_xml_add(xml_node, "running", pcmk__btoa(hosts != NULL));
763 cli_resource_check(out, cib_conn, rsc);
764 g_list_free(hosts);
765 }
766
767 return pcmk_rc_ok;
768 }
769
770 static void
771 add_resource_name(pe_resource_t *rsc, pcmk__output_t *out) {
772 if (rsc->children == NULL) {
773 out->list_item(out, "resource", "%s", rsc->id);
774 } else {
775 g_list_foreach(rsc->children, (GFunc) add_resource_name, out);
776 }
777 }
778
779 PCMK__OUTPUT_ARGS("resource-names-list", "GList *")
780 static int
781 resource_names(pcmk__output_t *out, va_list args) {
782 GList *resources = va_arg(args, GList *);
783
784 if (resources == NULL) {
785 out->err(out, "NO resources configured\n");
786 return pcmk_rc_no_output;
787 }
788
789 out->begin_list(out, NULL, NULL, "Resource Names");
790 g_list_foreach(resources, (GFunc) add_resource_name, out);
791 out->end_list(out);
792 return pcmk_rc_ok;
793 }
794
795 static pcmk__message_entry_t fmt_functions[] = {
796 { "agent-status", "default", agent_status_default },
797 { "agent-status", "xml", agent_status_xml },
798 { "attribute-list", "default", attribute_list_default },
799 { "attribute-list", "text", attribute_list_text },
800 { "override", "default", override_default },
801 { "override", "xml", override_xml },
802 { "property-list", "default", property_list_default },
803 { "property-list", "text", property_list_text },
804 { "resource-agent-action", "default", resource_agent_action_default },
805 { "resource-agent-action", "xml", resource_agent_action_xml },
806 { "resource-check-list", "default", resource_check_list_default },
807 { "resource-check-list", "xml", resource_check_list_xml },
808 { "resource-search-list", "default", resource_search_list_default },
809 { "resource-search-list", "xml", resource_search_list_xml },
810 { "resource-reasons-list", "default", resource_reasons_list_default },
811 { "resource-reasons-list", "xml", resource_reasons_list_xml },
812 { "resource-names-list", "default", resource_names },
813
814 { NULL, NULL, NULL }
815 };
816
817 void
818 crm_resource_register_messages(pcmk__output_t *out) {
819 pcmk__register_messages(out, fmt_functions);
820 }