pacemaker 2.1.1-77db578727
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
native.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2021 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10#include <crm_internal.h>
11
12#include <crm/common/output.h>
13#include <crm/pengine/rules.h>
14#include <crm/pengine/status.h>
15#include <crm/pengine/complex.h>
17#include <crm/msg_xml.h>
18#include <pe_status_private.h>
19
20#define VARIANT_NATIVE 1
21#include "./variant.h"
22
23#ifdef PCMK__COMPAT_2_0
24#define PROVIDER_SEP "::"
25#else
26#define PROVIDER_SEP ":"
27#endif
28
33static bool
34is_multiply_active(pe_resource_t *rsc)
35{
36 unsigned int count = 0;
37
38 if (rsc->variant == pe_native) {
39 pe__find_active_requires(rsc, &count);
40 }
41 return count > 1;
42}
43
44static void
45native_priority_to_node(pe_resource_t * rsc, pe_node_t * node, gboolean failed)
46{
47 int priority = 0;
48
49 if ((rsc->priority == 0) || (failed == TRUE)) {
50 return;
51 }
52
53 if (rsc->role == RSC_ROLE_PROMOTED) {
54 // Promoted instance takes base priority + 1
55 priority = rsc->priority + 1;
56
57 } else {
58 priority = rsc->priority;
59 }
60
61 node->details->priority += priority;
62 pe_rsc_trace(rsc, "Node '%s' now has priority %d with %s'%s' (priority: %d%s)",
63 node->details->uname, node->details->priority,
64 (rsc->role == RSC_ROLE_PROMOTED)? "promoted " : "",
65 rsc->id, rsc->priority,
66 (rsc->role == RSC_ROLE_PROMOTED)? " + 1" : "");
67
68 /* Priority of a resource running on a guest node is added to the cluster
69 * node as well. */
70 if (node->details->remote_rsc
71 && node->details->remote_rsc->container) {
72 GList *gIter = node->details->remote_rsc->container->running_on;
73
74 for (; gIter != NULL; gIter = gIter->next) {
75 pe_node_t *a_node = gIter->data;
76
77 a_node->details->priority += priority;
78 pe_rsc_trace(rsc, "Node '%s' now has priority %d with %s'%s' (priority: %d%s) "
79 "from guest node '%s'",
80 a_node->details->uname, a_node->details->priority,
81 (rsc->role == RSC_ROLE_PROMOTED)? "promoted " : "",
82 rsc->id, rsc->priority,
83 (rsc->role == RSC_ROLE_PROMOTED)? " + 1" : "",
84 node->details->uname);
85 }
86 }
87}
88
89void
90native_add_running(pe_resource_t * rsc, pe_node_t * node, pe_working_set_t * data_set, gboolean failed)
91{
92 GList *gIter = rsc->running_on;
93
94 CRM_CHECK(node != NULL, return);
95 for (; gIter != NULL; gIter = gIter->next) {
96 pe_node_t *a_node = (pe_node_t *) gIter->data;
97
98 CRM_CHECK(a_node != NULL, return);
99 if (pcmk__str_eq(a_node->details->id, node->details->id, pcmk__str_casei)) {
100 return;
101 }
102 }
103
104 pe_rsc_trace(rsc, "Adding %s to %s %s", rsc->id, node->details->uname,
105 pcmk_is_set(rsc->flags, pe_rsc_managed)? "" : "(unmanaged)");
106
107 rsc->running_on = g_list_append(rsc->running_on, node);
108 if (rsc->variant == pe_native) {
109 node->details->running_rsc = g_list_append(node->details->running_rsc, rsc);
110
111 native_priority_to_node(rsc, node, failed);
112 }
113
114 if (rsc->variant == pe_native && node->details->maintenance) {
116 }
117
118 if (!pcmk_is_set(rsc->flags, pe_rsc_managed)) {
119 pe_resource_t *p = rsc->parent;
120
121 pe_rsc_info(rsc, "resource %s isn't managed", rsc->id);
122 resource_location(rsc, node, INFINITY, "not_managed_default", data_set);
123
124 while(p && node->details->online) {
125 /* add without the additional location constraint */
126 p->running_on = g_list_append(p->running_on, node);
127 p = p->parent;
128 }
129 return;
130 }
131
132 if (is_multiply_active(rsc)) {
133 switch (rsc->recovery_type) {
135 {
136 GHashTableIter gIter;
137 pe_node_t *local_node = NULL;
138
139 /* make sure it doesn't come up again */
140 if (rsc->allowed_nodes != NULL) {
141 g_hash_table_destroy(rsc->allowed_nodes);
142 }
143 rsc->allowed_nodes = pe__node_list2table(data_set->nodes);
144 g_hash_table_iter_init(&gIter, rsc->allowed_nodes);
145 while (g_hash_table_iter_next(&gIter, NULL, (void **)&local_node)) {
146 local_node->weight = -INFINITY;
147 }
148 }
149 break;
151 break;
152 case recovery_block:
155
156 /* If the resource belongs to a group or bundle configured with
157 * multiple-active=block, block the entire entity.
158 */
159 if (rsc->parent
160 && (rsc->parent->variant == pe_group || rsc->parent->variant == pe_container)
161 && rsc->parent->recovery_type == recovery_block) {
162 GList *gIter = rsc->parent->children;
163
164 for (; gIter != NULL; gIter = gIter->next) {
165 pe_resource_t *child = (pe_resource_t *) gIter->data;
166
169 }
170 }
171 break;
172 }
173 crm_debug("%s is active on multiple nodes including %s: %s",
174 rsc->id, node->details->uname,
175 recovery2text(rsc->recovery_type));
176
177 } else {
178 pe_rsc_trace(rsc, "Resource %s is active on: %s", rsc->id, node->details->uname);
179 }
180
181 if (rsc->parent != NULL) {
182 native_add_running(rsc->parent, node, data_set, FALSE);
183 }
184}
185
186static void
187recursive_clear_unique(pe_resource_t *rsc)
188{
191
192 for (GList *child = rsc->children; child != NULL; child = child->next) {
193 recursive_clear_unique((pe_resource_t *) child->data);
194 }
195}
196
197gboolean
199{
200 pe_resource_t *parent = uber_parent(rsc);
201 native_variant_data_t *native_data = NULL;
202 const char *standard = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
203 uint32_t ra_caps = pcmk_get_ra_caps(standard);
204
205 pe_rsc_trace(rsc, "Processing resource %s...", rsc->id);
206
207 native_data = calloc(1, sizeof(native_variant_data_t));
208 rsc->variant_opaque = native_data;
209
210 // Only some agent standards support unique and promotable clones
211 if (!pcmk_is_set(ra_caps, pcmk_ra_cap_unique)
212 && pcmk_is_set(rsc->flags, pe_rsc_unique) && pe_rsc_is_clone(parent)) {
213
214 /* @COMPAT We should probably reject this situation as an error (as we
215 * do for promotable below) rather than warn and convert, but that would
216 * be a backward-incompatible change that we should probably do with a
217 * transform at a schema major version bump.
218 */
219 pe__force_anon(standard, parent, rsc->id, data_set);
220
221 /* Clear globally-unique on the parent and all its descendents unpacked
222 * so far (clearing the parent should make any future children unpacking
223 * correct). We have to clear this resource explicitly because it isn't
224 * hooked into the parent's children yet.
225 */
226 recursive_clear_unique(parent);
227 recursive_clear_unique(rsc);
228 }
230 && pcmk_is_set(parent->flags, pe_rsc_promotable)) {
231
232 pe_err("Resource %s is of type %s and therefore "
233 "cannot be used as a promotable clone resource",
234 rsc->id, standard);
235 return FALSE;
236 }
237 return TRUE;
238}
239
240static bool
241rsc_is_on_node(pe_resource_t *rsc, const pe_node_t *node, int flags)
242{
243 pe_rsc_trace(rsc, "Checking whether %s is on %s",
244 rsc->id, node->details->uname);
245
247
248 for (GList *iter = rsc->running_on; iter; iter = iter->next) {
249 pe_node_t *loc = (pe_node_t *) iter->data;
250
251 if (loc->details == node->details) {
252 return TRUE;
253 }
254 }
255
257 && (rsc->running_on == NULL)) {
258 return TRUE;
259
260 } else if (!pcmk_is_set(flags, pe_find_current) && rsc->allocated_to
261 && (rsc->allocated_to->details == node->details)) {
262 return TRUE;
263 }
264 return FALSE;
265}
266
268native_find_rsc(pe_resource_t * rsc, const char *id, const pe_node_t *on_node,
269 int flags)
270{
271 bool match = FALSE;
272 pe_resource_t *result = NULL;
273
274 CRM_CHECK(id && rsc && rsc->id, return NULL);
275
276 if (flags & pe_find_clone) {
277 const char *rid = ID(rsc->xml);
278
279 if (!pe_rsc_is_clone(uber_parent(rsc))) {
280 match = FALSE;
281
282 } else if (!strcmp(id, rsc->id) || pcmk__str_eq(id, rid, pcmk__str_casei)) {
283 match = TRUE;
284 }
285
286 } else if (!strcmp(id, rsc->id)) {
287 match = TRUE;
288
290 && rsc->clone_name && strcmp(rsc->clone_name, id) == 0) {
291 match = TRUE;
292
293 } else if (pcmk_is_set(flags, pe_find_any)
295 && !pcmk_is_set(rsc->flags, pe_rsc_unique))) {
296 match = pe_base_name_eq(rsc, id);
297 }
298
299 if (match && on_node) {
300 bool match_node = rsc_is_on_node(rsc, on_node, flags);
301
302 if (match_node == FALSE) {
303 match = FALSE;
304 }
305 }
306
307 if (match) {
308 return rsc;
309 }
310
311 for (GList *gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
312 pe_resource_t *child = (pe_resource_t *) gIter->data;
313
314 result = rsc->fns->find_rsc(child, id, on_node, flags);
315 if (result) {
316 return result;
317 }
318 }
319 return NULL;
320}
321
322// create is ignored
323char *
324native_parameter(pe_resource_t * rsc, pe_node_t * node, gboolean create, const char *name,
325 pe_working_set_t * data_set)
326{
327 char *value_copy = NULL;
328 const char *value = NULL;
329 GHashTable *params = NULL;
330
331 CRM_CHECK(rsc != NULL, return NULL);
332 CRM_CHECK(name != NULL && strlen(name) != 0, return NULL);
333
334 pe_rsc_trace(rsc, "Looking up %s in %s", name, rsc->id);
335 params = pe_rsc_params(rsc, node, data_set);
336 value = g_hash_table_lookup(params, name);
337 if (value == NULL) {
338 /* try meta attributes instead */
339 value = g_hash_table_lookup(rsc->meta, name);
340 }
341 if (value != NULL) {
342 value_copy = strdup(value);
343 }
344 return value_copy;
345}
346
347gboolean
348native_active(pe_resource_t * rsc, gboolean all)
349{
350 for (GList *gIter = rsc->running_on; gIter != NULL; gIter = gIter->next) {
351 pe_node_t *a_node = (pe_node_t *) gIter->data;
352
353 if (a_node->details->unclean) {
354 pe_rsc_trace(rsc, "Resource %s: node %s is unclean",
355 rsc->id, a_node->details->uname);
356 return TRUE;
357 } else if (a_node->details->online == FALSE && pcmk_is_set(rsc->flags, pe_rsc_managed)) {
358 pe_rsc_trace(rsc, "Resource %s: node %s is offline",
359 rsc->id, a_node->details->uname);
360 } else {
361 pe_rsc_trace(rsc, "Resource %s active on %s",
362 rsc->id, a_node->details->uname);
363 return TRUE;
364 }
365 }
366 return FALSE;
367}
368
369struct print_data_s {
370 long options;
371 void *print_data;
372};
373
374static const char *
375native_pending_state(pe_resource_t * rsc)
376{
377 const char *pending_state = NULL;
378
379 if (pcmk__str_eq(rsc->pending_task, CRMD_ACTION_START, pcmk__str_casei)) {
380 pending_state = "Starting";
381
382 } else if (pcmk__str_eq(rsc->pending_task, CRMD_ACTION_STOP, pcmk__str_casei)) {
383 pending_state = "Stopping";
384
385 } else if (pcmk__str_eq(rsc->pending_task, CRMD_ACTION_MIGRATE, pcmk__str_casei)) {
386 pending_state = "Migrating";
387
388 } else if (pcmk__str_eq(rsc->pending_task, CRMD_ACTION_MIGRATED, pcmk__str_casei)) {
389 /* Work might be done in here. */
390 pending_state = "Migrating";
391
392 } else if (pcmk__str_eq(rsc->pending_task, CRMD_ACTION_PROMOTE, pcmk__str_casei)) {
393 pending_state = "Promoting";
394
395 } else if (pcmk__str_eq(rsc->pending_task, CRMD_ACTION_DEMOTE, pcmk__str_casei)) {
396 pending_state = "Demoting";
397 }
398
399 return pending_state;
400}
401
402static const char *
403native_pending_task(pe_resource_t * rsc)
404{
405 const char *pending_task = NULL;
406
407 if (pcmk__str_eq(rsc->pending_task, CRMD_ACTION_STATUS, pcmk__str_casei)) {
408 pending_task = "Monitoring";
409
410 /* Pending probes are not printed, even if pending
411 * operations are requested. If someone ever requests that
412 * behavior, uncomment this and the corresponding part of
413 * unpack.c:unpack_rsc_op().
414 */
415 /*
416 } else if (pcmk__str_eq(rsc->pending_task, "probe", pcmk__str_casei)) {
417 pending_task = "Checking";
418 */
419 }
420
421 return pending_task;
422}
423
424static enum rsc_role_e
425native_displayable_role(pe_resource_t *rsc)
426{
427 enum rsc_role_e role = rsc->role;
428
429 if ((role == RSC_ROLE_STARTED)
431
432 role = RSC_ROLE_UNPROMOTED;
433 }
434 return role;
435}
436
437static const char *
438native_displayable_state(pe_resource_t *rsc, bool print_pending)
439{
440 const char *rsc_state = NULL;
441
442 if (print_pending) {
443 rsc_state = native_pending_state(rsc);
444 }
445 if (rsc_state == NULL) {
446 rsc_state = role2text(native_displayable_role(rsc));
447 }
448 return rsc_state;
449}
450
451static void
452native_print_xml(pe_resource_t * rsc, const char *pre_text, long options, void *print_data)
453{
454 const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
455 const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
456 const char *rsc_state = native_displayable_state(rsc, pcmk_is_set(options, pe_print_pending));
457 const char *target_role = NULL;
458
459 /* resource information. */
460 status_print("%s<resource ", pre_text);
461 status_print("id=\"%s\" ", rsc_printable_id(rsc));
462 status_print("resource_agent=\"%s%s%s:%s\" ", class,
463 ((prov == NULL)? "" : PROVIDER_SEP),
464 ((prov == NULL)? "" : prov),
466
467 status_print("role=\"%s\" ", rsc_state);
468 if (rsc->meta) {
469 target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE);
470 }
471 if (target_role) {
472 status_print("target_role=\"%s\" ", target_role);
473 }
474 status_print("active=\"%s\" ", pcmk__btoa(rsc->fns->active(rsc, TRUE)));
475 status_print("orphaned=\"%s\" ", pe__rsc_bool_str(rsc, pe_rsc_orphan));
476 status_print("blocked=\"%s\" ", pe__rsc_bool_str(rsc, pe_rsc_block));
477 status_print("managed=\"%s\" ", pe__rsc_bool_str(rsc, pe_rsc_managed));
478 status_print("failed=\"%s\" ", pe__rsc_bool_str(rsc, pe_rsc_failed));
479 status_print("failure_ignored=\"%s\" ",
480 pe__rsc_bool_str(rsc, pe_rsc_failure_ignored));
481 status_print("nodes_running_on=\"%d\" ", g_list_length(rsc->running_on));
482
483 if (options & pe_print_pending) {
484 const char *pending_task = native_pending_task(rsc);
485
486 if (pending_task) {
487 status_print("pending=\"%s\" ", pending_task);
488 }
489 }
490
491 /* print out the nodes this resource is running on */
492 if (options & pe_print_rsconly) {
493 status_print("/>\n");
494 /* do nothing */
495 } else if (rsc->running_on != NULL) {
496 GList *gIter = rsc->running_on;
497
498 status_print(">\n");
499 for (; gIter != NULL; gIter = gIter->next) {
500 pe_node_t *node = (pe_node_t *) gIter->data;
501
502 status_print("%s <node name=\"%s\" id=\"%s\" cached=\"%s\"/>\n", pre_text,
503 node->details->uname, node->details->id,
504 pcmk__btoa(node->details->online == FALSE));
505 }
506 status_print("%s</resource>\n", pre_text);
507 } else {
508 status_print("/>\n");
509 }
510}
511
512// Append a flag to resource description string's flags list
513static bool
514add_output_flag(GString *s, const char *flag_desc, bool have_flags)
515{
516 g_string_append(s, (have_flags? ", " : " ("));
517 g_string_append(s, flag_desc);
518 return true;
519}
520
521// Append a node name to resource description string's node list
522static bool
523add_output_node(GString *s, const char *node, bool have_nodes)
524{
525 g_string_append(s, (have_nodes? " " : " [ "));
526 g_string_append(s, node);
527 return true;
528}
529
544gchar *
546 unsigned long show_opts, const char *target_role, bool show_nodes)
547{
548 const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
549 const char *provider = NULL;
550 const char *kind = crm_element_value(rsc->xml, XML_ATTR_TYPE);
551 gchar *retval = NULL;
552 GString *outstr = NULL;
553 bool have_flags = false;
554
555 if (rsc->variant != pe_native) {
556 return NULL;
557 }
558
559 CRM_CHECK(name != NULL, name = "unknown");
560 CRM_CHECK(kind != NULL, kind = "unknown");
561 CRM_CHECK(class != NULL, class = "unknown");
562
565 }
566
567 if ((node == NULL) && (rsc->lock_node != NULL)) {
568 node = rsc->lock_node;
569 }
570 if (pcmk_is_set(show_opts, pcmk_show_rsc_only)
571 || pcmk__list_of_multiple(rsc->running_on)) {
572 node = NULL;
573 }
574
575 // We need a string of at least this size
576 outstr = g_string_sized_new(strlen(name) + strlen(class) + strlen(kind)
577 + (provider? (strlen(provider) + 2) : 0)
578 + (node? strlen(node->details->uname) + 1 : 0)
579 + 11);
580
581 // Resource name and agent
582 g_string_printf(outstr, "%s\t(%s%s%s:%s):\t", name, class,
583 ((provider == NULL)? "" : PROVIDER_SEP),
584 ((provider == NULL)? "" : provider), kind);
585
586 // State on node
587 if (pcmk_is_set(rsc->flags, pe_rsc_orphan)) {
588 g_string_append(outstr, " ORPHANED");
589 }
590 if (pcmk_is_set(rsc->flags, pe_rsc_failed)) {
591 enum rsc_role_e role = native_displayable_role(rsc);
592
593 if (role > RSC_ROLE_UNPROMOTED) {
594 g_string_append_printf(outstr, " FAILED %s", role2text(role));
595 } else {
596 g_string_append(outstr, " FAILED");
597 }
598 } else {
599 g_string_append_printf(outstr, " %s", native_displayable_state(rsc, pcmk_is_set(show_opts, pcmk_show_pending)));
600 }
601 if (node) {
602 g_string_append_printf(outstr, " %s", node->details->uname);
603 }
604
605 // Flags, as: (<flag> [...])
606 if (node && !(node->details->online) && node->details->unclean) {
607 have_flags = add_output_flag(outstr, "UNCLEAN", have_flags);
608 }
609 if (node && (node == rsc->lock_node)) {
610 have_flags = add_output_flag(outstr, "LOCKED", have_flags);
611 }
612 if (pcmk_is_set(show_opts, pcmk_show_pending)) {
613 const char *pending_task = native_pending_task(rsc);
614
615 if (pending_task) {
616 have_flags = add_output_flag(outstr, pending_task, have_flags);
617 }
618 }
619 if (target_role) {
620 enum rsc_role_e target_role_e = text2role(target_role);
621
622 /* Only show target role if it limits our abilities (i.e. ignore
623 * Started, as it is the default anyways, and doesn't prevent the
624 * resource from becoming promoted).
625 */
626 if (target_role_e == RSC_ROLE_STOPPED) {
627 have_flags = add_output_flag(outstr, "disabled", have_flags);
628
630 && target_role_e == RSC_ROLE_UNPROMOTED) {
631 have_flags = add_output_flag(outstr, "target-role:", have_flags);
632 g_string_append(outstr, target_role);
633 }
634 }
635 if (pcmk_is_set(rsc->flags, pe_rsc_block)) {
636 have_flags = add_output_flag(outstr, "blocked", have_flags);
637 } else if (!pcmk_is_set(rsc->flags, pe_rsc_managed)) {
638 have_flags = add_output_flag(outstr, "unmanaged", have_flags);
639 }
641 have_flags = add_output_flag(outstr, "failure ignored", have_flags);
642 }
643 if (have_flags) {
644 g_string_append(outstr, ")");
645 }
646
647 // User-supplied description
648 if (pcmk_is_set(show_opts, pcmk_show_rsc_only)
649 || pcmk__list_of_multiple(rsc->running_on)) {
650 const char *desc = crm_element_value(rsc->xml, XML_ATTR_DESC);
651
652 if (desc) {
653 g_string_append_printf(outstr, " %s", desc);
654 }
655 }
656
657 if (show_nodes && !pcmk_is_set(show_opts, pcmk_show_rsc_only)
658 && pcmk__list_of_multiple(rsc->running_on)) {
659 bool have_nodes = false;
660
661 for (GList *iter = rsc->running_on; iter != NULL; iter = iter->next) {
662 pe_node_t *n = (pe_node_t *) iter->data;
663
664 have_nodes = add_output_node(outstr, n->details->uname, have_nodes);
665 }
666 if (have_nodes) {
667 g_string_append(outstr, " ]");
668 }
669 }
670
671 retval = outstr->str;
672 g_string_free(outstr, FALSE);
673 return retval;
674}
675
676int
678 const char *name, pe_node_t *node, unsigned int show_opts)
679{
680 const char *kind = crm_element_value(rsc->xml, XML_ATTR_TYPE);
681 const char *target_role = NULL;
682
683 xmlNodePtr list_node = NULL;
684 const char *cl = NULL;
685
687 CRM_ASSERT(kind != NULL);
688
689 if (rsc->meta) {
690 const char *is_internal = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_INTERNAL_RSC);
691
692 if (crm_is_true(is_internal)
693 && !pcmk_is_set(show_opts, pcmk_show_implicit_rscs)) {
694
695 crm_trace("skipping print of internal resource %s", rsc->id);
696 return pcmk_rc_no_output;
697 }
698 target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE);
699 }
700
701 if (!pcmk_is_set(rsc->flags, pe_rsc_managed)) {
702 cl = "rsc-managed";
703
704 } else if (pcmk_is_set(rsc->flags, pe_rsc_failed)) {
705 cl = "rsc-failed";
706
707 } else if (rsc->variant == pe_native && (rsc->running_on == NULL)) {
708 cl = "rsc-failed";
709
710 } else if (pcmk__list_of_multiple(rsc->running_on)) {
711 cl = "rsc-multiple";
712
713 } else if (pcmk_is_set(rsc->flags, pe_rsc_failure_ignored)) {
714 cl = "rsc-failure-ignored";
715
716 } else {
717 cl = "rsc-ok";
718 }
719
720 {
721 gchar *s = pcmk__native_output_string(rsc, name, node, show_opts,
722 target_role, true);
723
724 list_node = pcmk__output_create_html_node(out, "li", NULL, NULL, NULL);
725 pcmk_create_html_node(list_node, "span", NULL, cl, s);
726 g_free(s);
727 }
728
729 return pcmk_rc_ok;
730}
731
732int
734 const char *name, pe_node_t *node, unsigned int show_opts)
735{
736 const char *target_role = NULL;
737
739
740 if (rsc->meta) {
741 const char *is_internal = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_INTERNAL_RSC);
742
743 if (crm_is_true(is_internal)
744 && !pcmk_is_set(show_opts, pcmk_show_implicit_rscs)) {
745
746 crm_trace("skipping print of internal resource %s", rsc->id);
747 return pcmk_rc_no_output;
748 }
749 target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE);
750 }
751
752 {
753 gchar *s = pcmk__native_output_string(rsc, name, node, show_opts,
754 target_role, true);
755
756 out->list_item(out, NULL, "%s", s);
757 g_free(s);
758 }
759
760 return pcmk_rc_ok;
761}
762
763void
764common_print(pe_resource_t * rsc, const char *pre_text, const char *name, pe_node_t *node, long options, void *print_data)
765{
766 const char *target_role = NULL;
767
769
770 if (rsc->meta) {
771 const char *is_internal = g_hash_table_lookup(rsc->meta,
773
774 if (crm_is_true(is_internal)
775 && !pcmk_is_set(options, pe_print_implicit)) {
776
777 crm_trace("skipping print of internal resource %s", rsc->id);
778 return;
779 }
780 target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE);
781 }
782
783 if (options & pe_print_xml) {
784 native_print_xml(rsc, pre_text, options, print_data);
785 return;
786 }
787
788 if ((pre_text == NULL) && (options & pe_print_printf)) {
789 pre_text = " ";
790 }
791
792 if (options & pe_print_html) {
793 if (!pcmk_is_set(rsc->flags, pe_rsc_managed)) {
794 status_print("<font color=\"yellow\">");
795
796 } else if (pcmk_is_set(rsc->flags, pe_rsc_failed)) {
797 status_print("<font color=\"red\">");
798
799 } else if (rsc->running_on == NULL) {
800 status_print("<font color=\"red\">");
801
802 } else if (pcmk__list_of_multiple(rsc->running_on)) {
803 status_print("<font color=\"orange\">");
804
805 } else if (pcmk_is_set(rsc->flags, pe_rsc_failure_ignored)) {
806 status_print("<font color=\"yellow\">");
807
808 } else {
809 status_print("<font color=\"green\">");
810 }
811 }
812
813 {
814 gchar *resource_s = pcmk__native_output_string(rsc, name, node, options,
815 target_role, false);
816 status_print("%s%s", (pre_text? pre_text : ""), resource_s);
817 g_free(resource_s);
818 }
819
820 if (pcmk_is_set(options, pe_print_html)) {
821 status_print(" </font> ");
822 }
823
824 if (!pcmk_is_set(options, pe_print_rsconly)
825 && pcmk__list_of_multiple(rsc->running_on)) {
826
827 GList *gIter = rsc->running_on;
828 int counter = 0;
829
830 if (options & pe_print_html) {
831 status_print("<ul>\n");
832 } else if ((options & pe_print_printf)
833 || (options & pe_print_ncurses)) {
834 status_print("[");
835 }
836
837 for (; gIter != NULL; gIter = gIter->next) {
838 pe_node_t *n = (pe_node_t *) gIter->data;
839
840 counter++;
841
842 if (options & pe_print_html) {
843 status_print("<li>\n%s", n->details->uname);
844
845 } else if ((options & pe_print_printf)
846 || (options & pe_print_ncurses)) {
847 status_print(" %s", n->details->uname);
848
849 } else if ((options & pe_print_log)) {
850 status_print("\t%d : %s", counter, n->details->uname);
851
852 } else {
853 status_print("%s", n->details->uname);
854 }
855 if (options & pe_print_html) {
856 status_print("</li>\n");
857
858 }
859 }
860
861 if (options & pe_print_html) {
862 status_print("</ul>\n");
863 } else if ((options & pe_print_printf)
864 || (options & pe_print_ncurses)) {
865 status_print(" ]");
866 }
867 }
868
869 if (options & pe_print_html) {
870 status_print("<br/>\n");
871 } else if (options & pe_print_suppres_nl) {
872 /* nothing */
873 } else if ((options & pe_print_printf) || (options & pe_print_ncurses)) {
874 status_print("\n");
875 }
876}
877
878void
879native_print(pe_resource_t * rsc, const char *pre_text, long options, void *print_data)
880{
881 pe_node_t *node = NULL;
882
884 if (options & pe_print_xml) {
885 native_print_xml(rsc, pre_text, options, print_data);
886 return;
887 }
888
889 node = pe__current_node(rsc);
890
891 if (node == NULL) {
892 // This is set only if a non-probe action is pending on this node
893 node = rsc->pending_node;
894 }
895
896 common_print(rsc, pre_text, rsc_printable_id(rsc), node, options, print_data);
897}
898
899PCMK__OUTPUT_ARGS("primitive", "unsigned int", "pe_resource_t *", "GList *", "GList *")
900int
902{
903 unsigned int show_opts = va_arg(args, unsigned int);
904 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
905 GList *only_node G_GNUC_UNUSED = va_arg(args, GList *);
906 GList *only_rsc = va_arg(args, GList *);
907
908 bool print_pending = pcmk_is_set(show_opts, pcmk_show_pending);
909 const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
910 const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
911 const char *rsc_state = native_displayable_state(rsc, print_pending);
912
913 char ra_name[LINE_MAX];
914 char *nodes_running_on = NULL;
915 char *priority = NULL;
916 int rc = pcmk_rc_no_output;
917 const char *target_role = NULL;
918
919 if (rsc->meta != NULL) {
920 target_role = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET_ROLE);
921 }
922
924
925 if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) {
926 return pcmk_rc_no_output;
927 }
928
929 /* resource information. */
930 snprintf(ra_name, LINE_MAX, "%s%s%s:%s", class,
931 ((prov == NULL)? "" : PROVIDER_SEP), ((prov == NULL)? "" : prov),
933
934 nodes_running_on = pcmk__itoa(g_list_length(rsc->running_on));
935 priority = pcmk__ftoa(rsc->priority);
936
937 rc = pe__name_and_nvpairs_xml(out, true, "resource", 12,
938 "id", rsc_printable_id(rsc),
939 "resource_agent", ra_name,
940 "role", rsc_state,
941 "target_role", target_role,
942 "active", pcmk__btoa(rsc->fns->active(rsc, TRUE)),
943 "orphaned", pe__rsc_bool_str(rsc, pe_rsc_orphan),
944 "blocked", pe__rsc_bool_str(rsc, pe_rsc_block),
945 "managed", pe__rsc_bool_str(rsc, pe_rsc_managed),
946 "failed", pe__rsc_bool_str(rsc, pe_rsc_failed),
947 "failure_ignored", pe__rsc_bool_str(rsc, pe_rsc_failure_ignored),
948 "nodes_running_on", nodes_running_on,
949 "pending", (print_pending? native_pending_task(rsc) : NULL));
950 free(priority);
951 free(nodes_running_on);
952
954
955 if (rsc->running_on != NULL) {
956 GList *gIter = rsc->running_on;
957
958 for (; gIter != NULL; gIter = gIter->next) {
959 pe_node_t *node = (pe_node_t *) gIter->data;
960
961 rc = pe__name_and_nvpairs_xml(out, false, "node", 3,
962 "name", node->details->uname,
963 "id", node->details->id,
964 "cached", pcmk__btoa(node->details->online));
966 }
967 }
968
970 return rc;
971}
972
973PCMK__OUTPUT_ARGS("primitive", "unsigned int", "pe_resource_t *", "GList *", "GList *")
974int
976{
977 unsigned int show_opts = va_arg(args, unsigned int);
978 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
979 GList *only_node G_GNUC_UNUSED = va_arg(args, GList *);
980 GList *only_rsc = va_arg(args, GList *);
981
982 pe_node_t *node = pe__current_node(rsc);
983
984 if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) {
985 return pcmk_rc_no_output;
986 }
987
989
990 if (node == NULL) {
991 // This is set only if a non-probe action is pending on this node
992 node = rsc->pending_node;
993 }
994 return pe__common_output_html(out, rsc, rsc_printable_id(rsc), node, show_opts);
995}
996
997PCMK__OUTPUT_ARGS("primitive", "unsigned int", "pe_resource_t *", "GList *", "GList *")
998int
1000{
1001 unsigned int show_opts = va_arg(args, unsigned int);
1002 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
1003 GList *only_node G_GNUC_UNUSED = va_arg(args, GList *);
1004 GList *only_rsc = va_arg(args, GList *);
1005
1006 pe_node_t *node = pe__current_node(rsc);
1007
1008 CRM_ASSERT(rsc->variant == pe_native);
1009
1010 if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) {
1011 return pcmk_rc_no_output;
1012 }
1013
1014 if (node == NULL) {
1015 // This is set only if a non-probe action is pending on this node
1016 node = rsc->pending_node;
1017 }
1018 return pe__common_output_text(out, rsc, rsc_printable_id(rsc), node, show_opts);
1019}
1020
1021void
1023{
1024 pe_rsc_trace(rsc, "Freeing resource action list (not the data)");
1025 common_free(rsc);
1026}
1027
1028enum rsc_role_e
1029native_resource_state(const pe_resource_t * rsc, gboolean current)
1030{
1031 enum rsc_role_e role = rsc->next_role;
1032
1033 if (current) {
1034 role = rsc->role;
1035 }
1036 pe_rsc_trace(rsc, "%s state: %s", rsc->id, role2text(role));
1037 return role;
1038}
1039
1051pe_node_t *
1052native_location(const pe_resource_t *rsc, GList **list, int current)
1053{
1054 pe_node_t *one = NULL;
1055 GList *result = NULL;
1056
1057 if (rsc->children) {
1058 GList *gIter = rsc->children;
1059
1060 for (; gIter != NULL; gIter = gIter->next) {
1061 pe_resource_t *child = (pe_resource_t *) gIter->data;
1062
1063 child->fns->location(child, &result, current);
1064 }
1065
1066 } else if (current) {
1067
1068 if (rsc->running_on) {
1069 result = g_list_copy(rsc->running_on);
1070 }
1071 if ((current == 2) && rsc->pending_node
1072 && !pe_find_node_id(result, rsc->pending_node->details->id)) {
1073 result = g_list_append(result, rsc->pending_node);
1074 }
1075
1076 } else if (current == FALSE && rsc->allocated_to) {
1077 result = g_list_append(NULL, rsc->allocated_to);
1078 }
1079
1080 if (result && (result->next == NULL)) {
1081 one = result->data;
1082 }
1083
1084 if (list) {
1085 GList *gIter = result;
1086
1087 for (; gIter != NULL; gIter = gIter->next) {
1088 pe_node_t *node = (pe_node_t *) gIter->data;
1089
1090 if (*list == NULL || pe_find_node_id(*list, node->details->id) == NULL) {
1091 *list = g_list_append(*list, node);
1092 }
1093 }
1094 }
1095
1096 g_list_free(result);
1097 return one;
1098}
1099
1100static void
1101get_rscs_brief(GList *rsc_list, GHashTable * rsc_table, GHashTable * active_table)
1102{
1103 GList *gIter = rsc_list;
1104
1105 for (; gIter != NULL; gIter = gIter->next) {
1106 pe_resource_t *rsc = (pe_resource_t *) gIter->data;
1107
1108 const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
1109 const char *kind = crm_element_value(rsc->xml, XML_ATTR_TYPE);
1110
1111 int offset = 0;
1112 char buffer[LINE_MAX];
1113
1114 int *rsc_counter = NULL;
1115 int *active_counter = NULL;
1116
1117 if (rsc->variant != pe_native) {
1118 continue;
1119 }
1120
1121 offset += snprintf(buffer + offset, LINE_MAX - offset, "%s", class);
1123 const char *prov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
1124
1125 if (prov != NULL) {
1126 offset += snprintf(buffer + offset, LINE_MAX - offset,
1127 PROVIDER_SEP "%s", prov);
1128 }
1129 }
1130 offset += snprintf(buffer + offset, LINE_MAX - offset, ":%s", kind);
1131 CRM_LOG_ASSERT(offset > 0);
1132
1133 if (rsc_table) {
1134 rsc_counter = g_hash_table_lookup(rsc_table, buffer);
1135 if (rsc_counter == NULL) {
1136 rsc_counter = calloc(1, sizeof(int));
1137 *rsc_counter = 0;
1138 g_hash_table_insert(rsc_table, strdup(buffer), rsc_counter);
1139 }
1140 (*rsc_counter)++;
1141 }
1142
1143 if (active_table) {
1144 GList *gIter2 = rsc->running_on;
1145
1146 for (; gIter2 != NULL; gIter2 = gIter2->next) {
1147 pe_node_t *node = (pe_node_t *) gIter2->data;
1148 GHashTable *node_table = NULL;
1149
1150 if (node->details->unclean == FALSE && node->details->online == FALSE &&
1152 continue;
1153 }
1154
1155 node_table = g_hash_table_lookup(active_table, node->details->uname);
1156 if (node_table == NULL) {
1157 node_table = pcmk__strkey_table(free, free);
1158 g_hash_table_insert(active_table, strdup(node->details->uname), node_table);
1159 }
1160
1161 active_counter = g_hash_table_lookup(node_table, buffer);
1162 if (active_counter == NULL) {
1163 active_counter = calloc(1, sizeof(int));
1164 *active_counter = 0;
1165 g_hash_table_insert(node_table, strdup(buffer), active_counter);
1166 }
1167 (*active_counter)++;
1168 }
1169 }
1170 }
1171}
1172
1173static void
1174destroy_node_table(gpointer data)
1175{
1176 GHashTable *node_table = data;
1177
1178 if (node_table) {
1179 g_hash_table_destroy(node_table);
1180 }
1181}
1182
1183void
1184print_rscs_brief(GList *rsc_list, const char *pre_text, long options,
1185 void *print_data, gboolean print_all)
1186{
1187 GHashTable *rsc_table = pcmk__strkey_table(free, free);
1188 GHashTable *active_table = pcmk__strkey_table(free, destroy_node_table);
1189 GHashTableIter hash_iter;
1190 char *type = NULL;
1191 int *rsc_counter = NULL;
1192
1193 get_rscs_brief(rsc_list, rsc_table, active_table);
1194
1195 g_hash_table_iter_init(&hash_iter, rsc_table);
1196 while (g_hash_table_iter_next(&hash_iter, (gpointer *)&type, (gpointer *)&rsc_counter)) {
1197 GHashTableIter hash_iter2;
1198 char *node_name = NULL;
1199 GHashTable *node_table = NULL;
1200 int active_counter_all = 0;
1201
1202 g_hash_table_iter_init(&hash_iter2, active_table);
1203 while (g_hash_table_iter_next(&hash_iter2, (gpointer *)&node_name, (gpointer *)&node_table)) {
1204 int *active_counter = g_hash_table_lookup(node_table, type);
1205
1206 if (active_counter == NULL || *active_counter == 0) {
1207 continue;
1208
1209 } else {
1210 active_counter_all += *active_counter;
1211 }
1212
1213 if (options & pe_print_rsconly) {
1214 node_name = NULL;
1215 }
1216
1217 if (options & pe_print_html) {
1218 status_print("<li>\n");
1219 }
1220
1221 if (print_all) {
1222 status_print("%s%d/%d\t(%s):\tActive %s\n", pre_text ? pre_text : "",
1223 active_counter ? *active_counter : 0,
1224 rsc_counter ? *rsc_counter : 0, type,
1225 active_counter && (*active_counter > 0) && node_name ? node_name : "");
1226 } else {
1227 status_print("%s%d\t(%s):\tActive %s\n", pre_text ? pre_text : "",
1228 active_counter ? *active_counter : 0, type,
1229 active_counter && (*active_counter > 0) && node_name ? node_name : "");
1230 }
1231
1232 if (options & pe_print_html) {
1233 status_print("</li>\n");
1234 }
1235 }
1236
1237 if (print_all && active_counter_all == 0) {
1238 if (options & pe_print_html) {
1239 status_print("<li>\n");
1240 }
1241
1242 status_print("%s%d/%d\t(%s):\tActive\n", pre_text ? pre_text : "",
1243 active_counter_all,
1244 rsc_counter ? *rsc_counter : 0, type);
1245
1246 if (options & pe_print_html) {
1247 status_print("</li>\n");
1248 }
1249 }
1250 }
1251
1252 if (rsc_table) {
1253 g_hash_table_destroy(rsc_table);
1254 rsc_table = NULL;
1255 }
1256 if (active_table) {
1257 g_hash_table_destroy(active_table);
1258 active_table = NULL;
1259 }
1260}
1261
1262int
1263pe__rscs_brief_output(pcmk__output_t *out, GList *rsc_list, unsigned int show_opts)
1264{
1265 GHashTable *rsc_table = pcmk__strkey_table(free, free);
1266 GHashTable *active_table = pcmk__strkey_table(free, destroy_node_table);
1267 GList *sorted_rscs;
1268 int rc = pcmk_rc_no_output;
1269
1270 get_rscs_brief(rsc_list, rsc_table, active_table);
1271
1272 /* Make a list of the rsc_table keys so that it can be sorted. This is to make sure
1273 * output order stays consistent between systems.
1274 */
1275 sorted_rscs = g_hash_table_get_keys(rsc_table);
1276 sorted_rscs = g_list_sort(sorted_rscs, (GCompareFunc) strcmp);
1277
1278 for (GList *gIter = sorted_rscs; gIter; gIter = gIter->next) {
1279 char *type = (char *) gIter->data;
1280 int *rsc_counter = g_hash_table_lookup(rsc_table, type);
1281
1282 GList *sorted_nodes = NULL;
1283 int active_counter_all = 0;
1284
1285 /* Also make a list of the active_table keys so it can be sorted. If there's
1286 * more than one instance of a type of resource running, we need the nodes to
1287 * be sorted to make sure output order stays consistent between systems.
1288 */
1289 sorted_nodes = g_hash_table_get_keys(active_table);
1290 sorted_nodes = g_list_sort(sorted_nodes, (GCompareFunc) pcmk__numeric_strcasecmp);
1291
1292 for (GList *gIter2 = sorted_nodes; gIter2; gIter2 = gIter2->next) {
1293 char *node_name = (char *) gIter2->data;
1294 GHashTable *node_table = g_hash_table_lookup(active_table, node_name);
1295 int *active_counter = NULL;
1296
1297 if (node_table == NULL) {
1298 continue;
1299 }
1300
1301 active_counter = g_hash_table_lookup(node_table, type);
1302
1303 if (active_counter == NULL || *active_counter == 0) {
1304 continue;
1305
1306 } else {
1307 active_counter_all += *active_counter;
1308 }
1309
1310 if (pcmk_is_set(show_opts, pcmk_show_rsc_only)) {
1311 node_name = NULL;
1312 }
1313
1314 if (pcmk_is_set(show_opts, pcmk_show_inactive_rscs)) {
1315 out->list_item(out, NULL, "%d/%d\t(%s):\tActive %s",
1316 *active_counter,
1317 rsc_counter ? *rsc_counter : 0, type,
1318 (*active_counter > 0) && node_name ? node_name : "");
1319 } else {
1320 out->list_item(out, NULL, "%d\t(%s):\tActive %s",
1321 *active_counter, type,
1322 (*active_counter > 0) && node_name ? node_name : "");
1323 }
1324
1325 rc = pcmk_rc_ok;
1326 }
1327
1328 if (pcmk_is_set(show_opts, pcmk_show_inactive_rscs) && active_counter_all == 0) {
1329 out->list_item(out, NULL, "%d/%d\t(%s):\tActive",
1330 active_counter_all,
1331 rsc_counter ? *rsc_counter : 0, type);
1332 rc = pcmk_rc_ok;
1333 }
1334
1335 if (sorted_nodes) {
1336 g_list_free(sorted_nodes);
1337 }
1338 }
1339
1340 if (rsc_table) {
1341 g_hash_table_destroy(rsc_table);
1342 rsc_table = NULL;
1343 }
1344 if (active_table) {
1345 g_hash_table_destroy(active_table);
1346 active_table = NULL;
1347 }
1348 if (sorted_rscs) {
1349 g_list_free(sorted_rscs);
1350 }
1351
1352 return rc;
1353}
1354
1355gboolean
1356pe__native_is_filtered(pe_resource_t *rsc, GList *only_rsc, gboolean check_parent)
1357{
1358 if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc), pcmk__str_none) ||
1359 pcmk__str_in_list(only_rsc, rsc->id, pcmk__str_none)) {
1360 return FALSE;
1361 } else if (check_parent && rsc->parent) {
1362 pe_resource_t *up = uber_parent(rsc);
1363
1364 if (pe_rsc_is_bundled(rsc)) {
1365 return up->parent->fns->is_filtered(up->parent, only_rsc, FALSE);
1366 } else {
1367 return up->fns->is_filtered(up, only_rsc, FALSE);
1368 }
1369 }
1370
1371 return TRUE;
1372}
uint32_t pcmk_get_ra_caps(const char *standard)
Get capabilities of a resource agent standard.
Definition agents.c:31
@ pcmk_ra_cap_unique
Definition agents.h:50
@ pcmk_ra_cap_promotable
Definition agents.h:51
@ pcmk_ra_cap_provider
Definition agents.h:47
void pe__force_anon(const char *standard, pe_resource_t *rsc, const char *rid, pe_working_set_t *data_set)
Definition clone.c:65
uint64_t flags
Definition remote.c:3
gboolean crm_is_true(const char *s)
Definition strings.c:415
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition util.h:114
@ pe_print_ncurses
Definition common.h:122
@ pe_print_printf
Definition common.h:123
@ pe_print_rsconly
Ignored.
Definition common.h:127
@ pe_print_implicit
Definition common.h:135
@ pe_print_log
Definition common.h:120
@ pe_print_xml
Definition common.h:130
@ pe_print_pending
Definition common.h:132
@ pe_print_suppres_nl
Definition common.h:129
@ pe_print_html
Definition common.h:121
@ recovery_stop_start
Definition common.h:80
@ recovery_block
Definition common.h:82
@ recovery_stop_only
Definition common.h:81
const char * role2text(enum rsc_role_e role)
Definition common.c:459
rsc_role_e
Possible roles that a resource can be in.
Definition common.h:92
@ RSC_ROLE_STARTED
Definition common.h:95
@ RSC_ROLE_STOPPED
Definition common.h:94
@ RSC_ROLE_PROMOTED
Definition common.h:97
@ RSC_ROLE_UNPROMOTED
Definition common.h:96
enum rsc_role_e text2role(const char *role)
Definition common.c:488
#define resource_s
pe_resource_t * uber_parent(pe_resource_t *rsc)
Definition complex.c:903
GHashTable * pe_rsc_params(pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
Get a table of resource parameters.
Definition complex.c:457
enum crm_ais_msg_types type
Definition cpg.c:3
char uname[MAX_NAME]
Definition cpg.c:5
char data[0]
Definition cpg.c:10
uint32_t id
Definition cpg.c:0
#define CRMD_ACTION_STOP
Definition crm.h:179
#define CRMD_ACTION_MIGRATED
Definition crm.h:174
#define CRMD_ACTION_STATUS
Definition crm.h:190
#define CRMD_ACTION_DEMOTE
Definition crm.h:184
#define INFINITY
Definition crm.h:99
#define CRMD_ACTION_MIGRATE
Definition crm.h:173
#define CRMD_ACTION_START
Definition crm.h:176
#define CRMD_ACTION_PROMOTE
Definition crm.h:182
#define CRM_LOG_ASSERT(expr)
Definition logging.h:202
#define CRM_CHECK(expr, failure_action)
Definition logging.h:218
#define crm_debug(fmt, args...)
Definition logging.h:355
#define crm_trace(fmt, args...)
Definition logging.h:356
#define ID(x)
Definition msg_xml.h:456
#define XML_RSC_ATTR_TARGET_ROLE
Definition msg_xml.h:233
#define XML_AGENT_ATTR_PROVIDER
Definition msg_xml.h:267
#define XML_AGENT_ATTR_CLASS
Definition msg_xml.h:266
#define XML_BOOLEAN_FALSE
Definition msg_xml.h:141
#define XML_ATTR_TYPE
Definition msg_xml.h:132
#define XML_RSC_ATTR_INTERNAL_RSC
Definition msg_xml.h:242
#define XML_RSC_ATTR_UNIQUE
Definition msg_xml.h:234
#define XML_ATTR_DESC
Definition msg_xml.h:128
gboolean pe__native_is_filtered(pe_resource_t *rsc, GList *only_rsc, gboolean check_parent)
Definition native.c:1356
gchar * pcmk__native_output_string(pe_resource_t *rsc, const char *name, pe_node_t *node, unsigned long show_opts, const char *target_role, bool show_nodes)
Definition native.c:545
#define PROVIDER_SEP
Definition native.c:26
char * native_parameter(pe_resource_t *rsc, pe_node_t *node, gboolean create, const char *name, pe_working_set_t *data_set)
Definition native.c:324
pe_resource_t * native_find_rsc(pe_resource_t *rsc, const char *id, const pe_node_t *on_node, int flags)
Definition native.c:268
void common_print(pe_resource_t *rsc, const char *pre_text, const char *name, pe_node_t *node, long options, void *print_data)
Definition native.c:764
gboolean native_active(pe_resource_t *rsc, gboolean all)
Definition native.c:348
void native_add_running(pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set, gboolean failed)
Definition native.c:90
pe_node_t * native_location(const pe_resource_t *rsc, GList **list, int current)
Definition native.c:1052
void native_print(pe_resource_t *rsc, const char *pre_text, long options, void *print_data)
Definition native.c:879
void print_rscs_brief(GList *rsc_list, const char *pre_text, long options, void *print_data, gboolean print_all)
Definition native.c:1184
gboolean native_unpack(pe_resource_t *rsc, pe_working_set_t *data_set)
Definition native.c:198
void native_free(pe_resource_t *rsc)
Definition native.c:1022
int pe__rscs_brief_output(pcmk__output_t *out, GList *rsc_list, unsigned int show_opts)
Definition native.c:1263
enum rsc_role_e native_resource_state(const pe_resource_t *rsc, gboolean current)
Definition native.c:1029
int pe__common_output_html(pcmk__output_t *out, pe_resource_t *rsc, const char *name, pe_node_t *node, unsigned int show_opts)
Definition native.c:677
int pe__common_output_text(pcmk__output_t *out, pe_resource_t *rsc, const char *name, pe_node_t *node, unsigned int show_opts)
Definition native.c:733
int pe__resource_xml(pcmk__output_t *out, va_list args)
Definition native.c:901
int pe__resource_text(pcmk__output_t *out, va_list args)
Definition native.c:999
int pe__resource_html(pcmk__output_t *out, va_list args)
Definition native.c:975
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition nvpair.c:530
Control output from tools.
@ pcmk_show_implicit_rscs
Definition output.h:59
@ pcmk_show_pending
Definition output.h:63
@ pcmk_show_rsc_only
Definition output.h:64
@ pcmk_show_inactive_rscs
Definition output.h:61
void pcmk__output_xml_pop_parent(pcmk__output_t *out)
Definition output_xml.c:511
xmlNodePtr pcmk__output_create_html_node(pcmk__output_t *out, const char *element_name, const char *id, const char *class_name, const char *text)
#define PCMK__OUTPUT_ARGS(ARGS...)
char * name
Definition pcmk_fence.c:31
int rc
Definition pcmk_fence.c:35
#define status_print(fmt, args...)
#define pe_rsc_block
Definition pe_types.h:250
#define pe_rsc_managed
Definition pe_types.h:249
#define pe_rsc_unique
Definition pe_types.h:254
#define pe_rsc_orphan
Definition pe_types.h:248
@ pe_find_inactive
match resource not running anywhere
Definition pe_types.h:88
@ pe_find_any
match base name of any clone instance
Definition pe_types.h:89
@ pe_find_clone
match only clone instances
Definition pe_types.h:86
@ pe_find_renamed
match resource ID or LRM history ID
Definition pe_types.h:84
@ pe_find_current
match resource active on specified node
Definition pe_types.h:87
@ pe_find_anon
match base name of anonymous clone instances
Definition pe_types.h:85
@ pe_group
Definition pe_types.h:38
@ pe_container
Definition pe_types.h:40
@ pe_native
Definition pe_types.h:37
#define pe_rsc_failed
Definition pe_types.h:267
#define pe_rsc_failure_ignored
Definition pe_types.h:275
#define pe_rsc_promotable
Definition pe_types.h:256
int pe__name_and_nvpairs_xml(pcmk__output_t *out, bool is_list, const char *tag_name, size_t pairs_count,...)
Definition pe_output.c:543
GHashTable * pe__node_list2table(GList *list)
Definition utils.c:204
pe_node_t * pe__find_active_requires(const pe_resource_t *rsc, unsigned int *count)
Definition complex.c:1079
#define pe__clear_resource_flags(resource, flags_to_clear)
Definition internal.h:53
#define pe_rsc_trace(rsc, fmt, args...)
Definition internal.h:20
void resource_location(pe_resource_t *rsc, pe_node_t *node, int score, const char *tag, pe_working_set_t *data_set)
Definition utils.c:1594
#define pe__set_resource_flags(resource, flags_to_set)
Definition internal.h:47
#define pe_rsc_info(rsc, fmt, args...)
Definition internal.h:18
void common_free(pe_resource_t *rsc)
Definition complex.c:917
#define pe_err(fmt...)
Definition internal.h:22
void add_hash_param(GHashTable *hash, const char *name, const char *value)
Definition common.c:579
#define CRM_ASSERT(expr)
Definition results.h:42
@ pcmk_rc_no_output
Definition results.h:112
@ pcmk_rc_ok
Definition results.h:142
Cluster status and scheduling.
pe_node_t * pe_find_node_id(GList *node_list, const char *id)
Definition status.c:418
const char * rsc_printable_id(pe_resource_t *rsc)
Definition utils.c:1917
int pcmk__numeric_strcasecmp(const char *s1, const char *s2)
Definition strings.c:1045
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
Definition strings.c:610
@ pcmk__str_none
@ pcmk__str_casei
gboolean pcmk__str_in_list(GList *lst, const gchar *s, uint32_t flags)
Definition strings.c:895
This structure contains everything that makes up a single output formatter.
void(*) void(* list_item)(pcmk__output_t *out, const char *name, const char *format,...) G_GNUC_PRINTF(3
int weight
Definition pe_types.h:241
struct pe_node_shared_s * details
Definition pe_types.h:244
const char * id
Definition pe_types.h:208
gboolean online
Definition pe_types.h:213
const char * uname
Definition pe_types.h:209
pe_resource_t * remote_rsc
Definition pe_types.h:230
gboolean unclean
Definition pe_types.h:217
gboolean maintenance
Definition pe_types.h:222
GList * running_rsc
Definition pe_types.h:231
GList * running_on
Definition pe_types.h:367
enum pe_obj_types variant
Definition pe_types.h:331
GHashTable * meta
Definition pe_types.h:374
GList * children
Definition pe_types.h:378
pe_resource_t * container
Definition pe_types.h:381
char * clone_name
Definition pe_types.h:323
xmlNode * xml
Definition pe_types.h:324
GHashTable * allowed_nodes
Definition pe_types.h:369
pe_node_t * pending_node
Definition pe_types.h:384
pe_node_t * allocated_to
Definition pe_types.h:364
void * variant_opaque
Definition pe_types.h:332
unsigned long long flags
Definition pe_types.h:349
char * pending_task
Definition pe_types.h:347
enum rsc_recovery_type recovery_type
Definition pe_types.h:336
pe_resource_t * parent
Definition pe_types.h:329
enum rsc_role_e next_role
Definition pe_types.h:372
enum rsc_role_e role
Definition pe_types.h:371
resource_object_functions_t * fns
Definition pe_types.h:333
pe_node_t * lock_node
Definition pe_types.h:385
gboolean(* is_filtered)(pe_resource_t *, GList *, gboolean)
Definition pe_types.h:57
gboolean(* active)(pe_resource_t *, gboolean)
Definition pe_types.h:52
pe_node_t *(* location)(const pe_resource_t *, GList **, int)
Definition pe_types.h:54
pe_resource_t *(* find_rsc)(pe_resource_t *parent, const char *search, const pe_node_t *node, int flags)
Definition pe_types.h:45
xmlNode * pcmk_create_html_node(xmlNode *parent, const char *element_name, const char *id, const char *class_name, const char *text)
Definition xml.c:733