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