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