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
- 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
15 #define cons_string(x) x?x:"NA"
16 void
17 cli_resource_print_cts_constraints(pe_working_set_t * data_set)
18 {
19 pcmk__output_t *out = data_set->priv;
20 xmlNode *xml_obj = NULL;
21 xmlNode *lifetime = NULL;
22 xmlNode *cib_constraints = get_object_root(XML_CIB_TAG_CONSTRAINTS, data_set->input);
23
24 for (xml_obj = pcmk__xe_first_child(cib_constraints); xml_obj != NULL;
25 xml_obj = pcmk__xe_next(xml_obj)) {
26 const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
27
28 if (id == NULL) {
29 continue;
30 }
31
32
33 lifetime = first_named_child(xml_obj, "lifetime");
34 if (pe_evaluate_rules(lifetime, NULL, data_set->now, NULL) == FALSE) {
35 continue;
36 }
37
38 if (!pcmk__str_eq(XML_CONS_TAG_RSC_DEPEND, crm_element_name(xml_obj), pcmk__str_casei)) {
39 continue;
40 }
41
42 out->info(out, "Constraint %s %s %s %s %s %s %s",
43 crm_element_name(xml_obj),
44 cons_string(crm_element_value(xml_obj, XML_ATTR_ID)),
45 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE)),
46 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET)),
47 cons_string(crm_element_value(xml_obj, XML_RULE_ATTR_SCORE)),
48 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE)),
49 cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET_ROLE)));
50 }
51 }
52
53 void
54 cli_resource_print_cts(pcmk__output_t *out, pe_resource_t * rsc)
55 {
56 GList *lpc = NULL;
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 for (lpc = rsc->children; lpc != NULL; lpc = lpc->next) {
81 pe_resource_t *child = (pe_resource_t *) lpc->data;
82
83 cli_resource_print_cts(out, child);
84 }
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 unsigned int opts = pe_print_pending;
118 GList *all = NULL;
119
120 all = g_list_prepend(all, strdup("*"));
121
122 out->begin_list(out, NULL, NULL, "Resource Config");
123 out->message(out, crm_map_element_name(rsc->xml), opts, rsc, all, all);
124 out->message(out, "resource-config", rsc, !expanded);
125 out->end_list(out);
126
127 g_list_free_full(all, free);
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("attribute-list", "pe_resource_t *", "char *", "GHashTable *")
155 static int
156 attribute_list_text(pcmk__output_t *out, va_list args) {
157 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
158 char *attr = va_arg(args, char *);
159 GHashTable *params = va_arg(args, GHashTable *);
160
161 const char *value = NULL;
162
163 if (params != NULL) {
164 value = g_hash_table_lookup(params, attr);
165 }
166 if (value != NULL) {
167 pcmk__formatted_printf(out, "%s\n", value);
168 } else {
169 out->err(out, "Attribute '%s' not found for '%s'", attr, rsc->id);
170 }
171
172 return pcmk_rc_ok;
173 }
174
175 PCMK__OUTPUT_ARGS("property-list", "pe_resource_t *", "char *")
176 static int
177 property_list_default(pcmk__output_t *out, va_list args) {
178 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
179 char *attr = va_arg(args, char *);
180
181 const char *value = crm_element_value(rsc->xml, attr);
182
183 if (value != NULL) {
184 out->begin_list(out, NULL, NULL, "Properties");
185 out->list_item(out, attr, "%s", value);
186 out->end_list(out);
187 }
188
189 return pcmk_rc_ok;
190 }
191
192 PCMK__OUTPUT_ARGS("property-list", "pe_resource_t *", "char *")
193 static int
194 property_list_text(pcmk__output_t *out, va_list args) {
195 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
196 char *attr = va_arg(args, char *);
197
198 const char *value = crm_element_value(rsc->xml, attr);
199
200 if (value != NULL) {
201 pcmk__formatted_printf(out, "%s\n", value);
202 }
203
204 return pcmk_rc_ok;
205 }
206
207 PCMK__OUTPUT_ARGS("resource-check-list", "resource_checks_t *")
208 static int
209 resource_check_list_default(pcmk__output_t *out, va_list args) {
210 resource_checks_t *checks = va_arg(args, resource_checks_t *);
211
212 pe_resource_t *parent = uber_parent(checks->rsc);
213 int rc = pcmk_rc_no_output;
214 bool printed = false;
215
216 if (checks->flags != 0 || checks->lock_node != NULL) {
217 printed = true;
218 out->begin_list(out, NULL, NULL, "Resource Checks");
219 }
220
221 if (pcmk_is_set(checks->flags, rsc_remain_stopped)) {
222 out->list_item(out, "check", "Configuration specifies '%s' should remain stopped",
223 parent->id);
224 }
225
226 if (pcmk_is_set(checks->flags, rsc_unpromotable)) {
227 out->list_item(out, "check", "Configuration specifies '%s' should not be promoted",
228 parent->id);
229 }
230
231 if (pcmk_is_set(checks->flags, rsc_unmanaged)) {
232 out->list_item(out, "check", "Configuration prevents cluster from stopping or starting unmanaged '%s'",
233 parent->id);
234 }
235
236 if (checks->lock_node) {
237 out->list_item(out, "check", "'%s' is locked to node %s due to shutdown",
238 parent->id, checks->lock_node);
239 }
240
241 if (printed) {
242 out->end_list(out);
243 rc = pcmk_rc_ok;
244 }
245
246 return rc;
247 }
248
249 PCMK__OUTPUT_ARGS("resource-check-list", "resource_checks_t *")
250 static int
251 resource_check_list_xml(pcmk__output_t *out, va_list args) {
252 resource_checks_t *checks = va_arg(args, resource_checks_t *);
253
254 pe_resource_t *parent = uber_parent(checks->rsc);
255
256 xmlNodePtr node = pcmk__output_create_xml_node(out, "check",
257 "id", parent->id,
258 NULL);
259
260 if (pcmk_is_set(checks->flags, rsc_remain_stopped)) {
261 crm_xml_add(node, "remain_stopped", "true");
262 }
263
264 if (pcmk_is_set(checks->flags, rsc_unpromotable)) {
265 crm_xml_add(node, "promotable", "false");
266 }
267
268 if (pcmk_is_set(checks->flags, rsc_unmanaged)) {
269 crm_xml_add(node, "unmanaged", "true");
270 }
271
272 if (checks->lock_node) {
273 crm_xml_add(node, "locked-to", checks->lock_node);
274 }
275
276 return pcmk_rc_ok;
277 }
278
279 PCMK__OUTPUT_ARGS("resource-search-list", "GList *", "gchar *")
280 static int
281 resource_search_list_default(pcmk__output_t *out, va_list args)
282 {
283 GList *nodes = va_arg(args, GList *);
284 gchar *requested_name = va_arg(args, gchar *);
285
286 bool printed = false;
287 int rc = pcmk_rc_no_output;
288
289 if (!out->is_quiet(out) && nodes == NULL) {
290 out->err(out, "resource %s is NOT running", requested_name);
291 return rc;
292 }
293
294 for (GList *lpc = nodes; lpc != NULL; lpc = lpc->next) {
295 node_info_t *ni = (node_info_t *) lpc->data;
296
297 if (!printed) {
298 out->begin_list(out, NULL, NULL, "Nodes");
299 printed = true;
300 rc = pcmk_rc_ok;
301 }
302
303 if (out->is_quiet(out)) {
304 out->list_item(out, "node", "%s", ni->node_name);
305 } else {
306 const char *role_text = "";
307
308 if (ni->promoted) {
309 #ifdef PCMK__COMPAT_2_0
310 role_text = " " RSC_ROLE_PROMOTED_LEGACY_S;
311 #else
312 role_text = " " RSC_ROLE_PROMOTED_S;
313 #endif
314 }
315 out->list_item(out, "node", "resource %s is running on: %s%s",
316 requested_name, ni->node_name, role_text);
317 }
318 }
319
320 if (printed) {
321 out->end_list(out);
322 }
323
324 return rc;
325 }
326
327 PCMK__OUTPUT_ARGS("resource-search-list", "GList *", "gchar *")
328 static int
329 resource_search_list_xml(pcmk__output_t *out, va_list args)
330 {
331 GList *nodes = va_arg(args, GList *);
332 gchar *requested_name = va_arg(args, gchar *);
333
334 pcmk__output_xml_create_parent(out, "nodes",
335 "resource", requested_name,
336 NULL);
337
338 for (GList *lpc = nodes; lpc != NULL; lpc = lpc->next) {
339 node_info_t *ni = (node_info_t *) lpc->data;
340 xmlNodePtr sub_node = pcmk__output_create_xml_text_node(out, "node", ni->node_name);
341
342 if (ni->promoted) {
343 crm_xml_add(sub_node, "state", "promoted");
344 }
345 }
346
347 return pcmk_rc_ok;
348 }
349
350 PCMK__OUTPUT_ARGS("resource-reasons-list", "cib_t *", "GList *", "pe_resource_t *",
351 "pe_node_t *")
352 static int
353 resource_reasons_list_default(pcmk__output_t *out, va_list args)
354 {
355 cib_t *cib_conn = va_arg(args, cib_t *);
356 GList *resources = va_arg(args, GList *);
357 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
358 pe_node_t *node = va_arg(args, pe_node_t *);
359
360 const char *host_uname = (node == NULL)? NULL : node->details->uname;
361
362 out->begin_list(out, NULL, NULL, "Resource Reasons");
363
364 if ((rsc == NULL) && (host_uname == NULL)) {
365 GList *lpc = NULL;
366 GList *hosts = NULL;
367
368 for (lpc = resources; lpc != NULL; lpc = lpc->next) {
369 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
370 rsc->fns->location(rsc, &hosts, TRUE);
371
372 if (hosts == NULL) {
373 out->list_item(out, "reason", "Resource %s is not running", rsc->id);
374 } else {
375 out->list_item(out, "reason", "Resource %s is running", rsc->id);
376 }
377
378 cli_resource_check(out, cib_conn, rsc);
379 g_list_free(hosts);
380 hosts = NULL;
381 }
382
383 } else if ((rsc != NULL) && (host_uname != NULL)) {
384 if (resource_is_running_on(rsc, host_uname)) {
385 out->list_item(out, "reason", "Resource %s is running on host %s",
386 rsc->id, host_uname);
387 } else {
388 out->list_item(out, "reason", "Resource %s is not running on host %s",
389 rsc->id, host_uname);
390 }
391
392 cli_resource_check(out, cib_conn, rsc);
393
394 } else if ((rsc == NULL) && (host_uname != NULL)) {
395 const char* host_uname = node->details->uname;
396 GList *allResources = node->details->allocated_rsc;
397 GList *activeResources = node->details->running_rsc;
398 GList *unactiveResources = pcmk__subtract_lists(allResources, activeResources, (GCompareFunc) strcmp);
399 GList *lpc = NULL;
400
401 for (lpc = activeResources; lpc != NULL; lpc = lpc->next) {
402 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
403 out->list_item(out, "reason", "Resource %s is running on host %s",
404 rsc->id, host_uname);
405 cli_resource_check(out, cib_conn, rsc);
406 }
407
408 for(lpc = unactiveResources; lpc != NULL; lpc = lpc->next) {
409 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
410 out->list_item(out, "reason", "Resource %s is assigned to host %s but not running",
411 rsc->id, host_uname);
412 cli_resource_check(out, cib_conn, rsc);
413 }
414
415 g_list_free(allResources);
416 g_list_free(activeResources);
417 g_list_free(unactiveResources);
418
419 } else if ((rsc != NULL) && (host_uname == NULL)) {
420 GList *hosts = NULL;
421
422 rsc->fns->location(rsc, &hosts, TRUE);
423 out->list_item(out, "reason", "Resource %s is %srunning",
424 rsc->id, (hosts? "" : "not "));
425 cli_resource_check(out, cib_conn, rsc);
426 g_list_free(hosts);
427 }
428
429 out->end_list(out);
430 return pcmk_rc_ok;
431 }
432
433 PCMK__OUTPUT_ARGS("resource-reasons-list", "cib_t *", "GList *", "pe_resource_t *",
434 "pe_node_t *")
435 static int
436 resource_reasons_list_xml(pcmk__output_t *out, va_list args)
437 {
438 cib_t *cib_conn = va_arg(args, cib_t *);
439 GList *resources = va_arg(args, GList *);
440 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
441 pe_node_t *node = va_arg(args, pe_node_t *);
442
443 const char *host_uname = (node == NULL)? NULL : node->details->uname;
444
445 xmlNodePtr xml_node = pcmk__output_xml_create_parent(out, "reason", NULL);
446
447 if ((rsc == NULL) && (host_uname == NULL)) {
448 GList *lpc = NULL;
449 GList *hosts = NULL;
450
451 pcmk__output_xml_create_parent(out, "resources", NULL);
452
453 for (lpc = resources; lpc != NULL; lpc = lpc->next) {
454 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
455
456 rsc->fns->location(rsc, &hosts, TRUE);
457
458 pcmk__output_xml_create_parent(out, "resource",
459 "id", rsc->id,
460 "running", pcmk__btoa(hosts != NULL),
461 NULL);
462
463 cli_resource_check(out, cib_conn, rsc);
464 pcmk__output_xml_pop_parent(out);
465 g_list_free(hosts);
466 hosts = NULL;
467 }
468
469 pcmk__output_xml_pop_parent(out);
470
471 } else if ((rsc != NULL) && (host_uname != NULL)) {
472 if (resource_is_running_on(rsc, host_uname)) {
473 crm_xml_add(xml_node, "running_on", host_uname);
474 }
475
476 cli_resource_check(out, cib_conn, rsc);
477
478 } else if ((rsc == NULL) && (host_uname != NULL)) {
479 const char* host_uname = node->details->uname;
480 GList *allResources = node->details->allocated_rsc;
481 GList *activeResources = node->details->running_rsc;
482 GList *unactiveResources = pcmk__subtract_lists(allResources, activeResources, (GCompareFunc) strcmp);
483 GList *lpc = NULL;
484
485 pcmk__output_xml_create_parent(out, "resources", NULL);
486
487 for (lpc = activeResources; lpc != NULL; lpc = lpc->next) {
488 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
489
490 pcmk__output_xml_create_parent(out, "resource",
491 "id", rsc->id,
492 "running", "true",
493 "host", host_uname,
494 NULL);
495
496 cli_resource_check(out, cib_conn, rsc);
497 pcmk__output_xml_pop_parent(out);
498 }
499
500 for(lpc = unactiveResources; lpc != NULL; lpc = lpc->next) {
501 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
502
503 pcmk__output_xml_create_parent(out, "resource",
504 "id", rsc->id,
505 "running", "false",
506 "host", host_uname,
507 NULL);
508
509 cli_resource_check(out, cib_conn, rsc);
510 pcmk__output_xml_pop_parent(out);
511 }
512
513 pcmk__output_xml_pop_parent(out);
514 g_list_free(allResources);
515 g_list_free(activeResources);
516 g_list_free(unactiveResources);
517
518 } else if ((rsc != NULL) && (host_uname == NULL)) {
519 GList *hosts = NULL;
520
521 rsc->fns->location(rsc, &hosts, TRUE);
522 crm_xml_add(xml_node, "running", pcmk__btoa(hosts != NULL));
523 cli_resource_check(out, cib_conn, rsc);
524 g_list_free(hosts);
525 }
526
527 return pcmk_rc_ok;
528 }
529
530 static void
531 add_resource_name(pcmk__output_t *out, pe_resource_t *rsc) {
532 if (rsc->children == NULL) {
533 out->list_item(out, "resource", "%s", rsc->id);
534 } else {
535 for (GList *lpc = rsc->children; lpc != NULL; lpc = lpc->next) {
536 pe_resource_t *child = (pe_resource_t *) lpc->data;
537 add_resource_name(out, child);
538 }
539 }
540 }
541
542 PCMK__OUTPUT_ARGS("resource-names-list", "GList *")
543 static int
544 resource_names(pcmk__output_t *out, va_list args) {
545 GList *resources = va_arg(args, GList *);
546
547 if (resources == NULL) {
548 out->err(out, "NO resources configured\n");
549 return pcmk_rc_no_output;
550 }
551
552 out->begin_list(out, NULL, NULL, "Resource Names");
553
554 for (GList *lpc = resources; lpc != NULL; lpc = lpc->next) {
555 pe_resource_t *rsc = (pe_resource_t *) lpc->data;
556 add_resource_name(out, rsc);
557 }
558
559 out->end_list(out);
560 return pcmk_rc_ok;
561 }
562
563 static pcmk__message_entry_t fmt_functions[] = {
564 { "attribute-list", "default", attribute_list_default },
565 { "attribute-list", "text", attribute_list_text },
566 { "property-list", "default", property_list_default },
567 { "property-list", "text", property_list_text },
568 { "resource-check-list", "default", resource_check_list_default },
569 { "resource-check-list", "xml", resource_check_list_xml },
570 { "resource-search-list", "default", resource_search_list_default },
571 { "resource-search-list", "xml", resource_search_list_xml },
572 { "resource-reasons-list", "default", resource_reasons_list_default },
573 { "resource-reasons-list", "xml", resource_reasons_list_xml },
574 { "resource-names-list", "default", resource_names },
575
576 { NULL, NULL, NULL }
577 };
578
579 void
580 crm_resource_register_messages(pcmk__output_t *out) {
581 pcmk__register_messages(out, fmt_functions);
582 }