22 #ifdef PCMK__COMPAT_2_0 23 #define PROVIDER_SEP "::" 25 #define PROVIDER_SEP ":" 35 unsigned int count = 0;
37 if (pcmk__is_primitive(rsc)) {
49 if ((rsc->
priority == 0) || (failed == TRUE)) {
62 pcmk__rsc_trace(rsc,
"%s now has priority %d with %s'%s' (priority: %d%s)",
74 for (; gIter != NULL; gIter = gIter->next) {
79 "%s now has priority %d with %s'%s' " 80 "(priority: %d%s) from guest node %s",
85 pcmk__node_name(node));
97 for (; gIter != NULL; gIter = gIter->next) {
110 if (pcmk__is_primitive(rsc)) {
112 native_priority_to_node(rsc, node, failed);
134 if (is_multiply_active(rsc)) {
138 GHashTableIter gIter;
147 while (g_hash_table_iter_next(&gIter, NULL, (
void **)&local_node)) {
160 if ((pcmk__is_group(rsc->
parent)
161 || pcmk__is_bundle(rsc->
parent))
165 for (; gIter != NULL; gIter = gIter->next) {
181 crm_debug(
"%s is active on multiple nodes including %s: %s",
182 rsc->
id, pcmk__node_name(node),
187 rsc->
id, pcmk__node_name(node));
190 if (rsc->
parent != NULL) {
200 g_list_foreach(rsc->
children, (GFunc) recursive_clear_unique, NULL);
215 && pcmk__is_clone(
parent)) {
229 recursive_clear_unique(
parent, NULL);
230 recursive_clear_unique(rsc, NULL);
236 "cannot be used as a promotable clone resource",
247 rsc->
id, pcmk__node_name(node));
252 for (GList *iter = rsc->
running_on; iter; iter = iter->next) {
253 if (pcmk__same_node((
pcmk_node_t *) iter->data, node)) {
280 const char *rid = pcmk__xe_id(rsc->
xml);
289 }
else if (!strcmp(
id, rsc->
id)) {
299 match = pe_base_name_eq(rsc,
id);
302 if (match && on_node) {
303 if (!rsc_is_on_node(rsc, on_node,
flags)) {
312 for (GList *gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
328 const char *value = NULL;
329 GHashTable *params = NULL;
336 value = g_hash_table_lookup(params,
name);
339 value = g_hash_table_lookup(rsc->
meta,
name);
347 for (GList *gIter = rsc->
running_on; gIter != NULL; gIter = gIter->next) {
352 rsc->
id, pcmk__node_name(a_node));
357 rsc->
id, pcmk__node_name(a_node));
360 rsc->
id, pcmk__node_name(a_node));
367 struct print_data_s {
375 const char *pending_state = NULL;
378 pending_state =
"Starting";
382 pending_state =
"Stopping";
386 pending_state =
"Migrating";
391 pending_state =
"Migrating";
395 pending_state =
"Promoting";
399 pending_state =
"Demoting";
402 return pending_state;
408 const char *pending_task = NULL;
411 pending_task =
"Monitoring";
442 native_displayable_state(
const pcmk_resource_t *rsc,
bool print_pending)
444 const char *rsc_state = NULL;
447 rsc_state = native_pending_state(rsc);
449 if (rsc_state == NULL) {
460 native_print_xml(
pcmk_resource_t *rsc,
const char *pre_text,
long options,
466 const char *target_role = NULL;
473 ((prov == NULL)?
"" : prov),
497 const char *pending_task = native_pending_task(rsc);
512 for (; gIter != NULL; gIter = gIter->next) {
528 add_output_flag(GString *s,
const char *flag_desc,
bool have_flags)
530 g_string_append(s, (have_flags?
", " :
" ("));
531 g_string_append(s, flag_desc);
537 add_output_node(GString *s,
const char *node,
bool have_nodes)
539 g_string_append(s, (have_nodes?
" " :
" [ "));
540 g_string_append(s, node);
561 const char *target_role,
bool show_nodes)
564 const char *provider = NULL;
566 GString *outstr = NULL;
567 bool have_flags =
false;
569 if (!pcmk__is_primitive(rsc)) {
574 CRM_CHECK(kind != NULL, kind =
"unknown");
575 CRM_CHECK(
class != NULL,
class =
"unknown");
581 if ((node == NULL) && (rsc->lock_node != NULL)) {
582 node = rsc->lock_node;
585 || pcmk__list_of_multiple(rsc->running_on)) {
589 outstr = g_string_sized_new(128);
594 pcmk__s(provider,
""),
":", kind,
"):\t", NULL);
598 g_string_append(outstr,
" ORPHANED");
601 enum rsc_role_e role = native_displayable_role(rsc);
603 g_string_append(outstr,
" FAILED");
610 pcmk__add_word(&outstr, 0, native_displayable_state(rsc, show_pending));
613 pcmk__add_word(&outstr, 0, pcmk__node_name(node));
619 if (probe_op != NULL) {
631 have_flags = add_output_flag(outstr,
"UNCLEAN", have_flags);
633 if (node && (node == rsc->lock_node)) {
634 have_flags = add_output_flag(outstr,
"LOCKED", have_flags);
637 const char *pending_task = native_pending_task(rsc);
640 have_flags = add_output_flag(outstr, pending_task, have_flags);
643 if (target_role != NULL) {
647 " %s for resource %s", target_role, rsc->id);
651 have_flags = add_output_flag(outstr,
"disabled", have_flags);
657 have_flags = add_output_flag(outstr,
660 g_string_append(outstr, target_role);
674 if (pcmk_any_flags_set(rsc->flags,
677 have_flags = add_output_flag(outstr,
"blocked", have_flags);
680 have_flags = add_output_flag(outstr,
"maintenance", have_flags);
683 have_flags = add_output_flag(outstr,
"unmanaged", have_flags);
687 have_flags = add_output_flag(outstr,
"failure ignored", have_flags);
692 g_string_append_c(outstr,
')');
697 || pcmk__list_of_multiple(rsc->running_on)) {
701 g_string_append(outstr,
" (");
702 g_string_append(outstr, desc);
703 g_string_append(outstr,
")");
709 && pcmk__list_of_multiple(rsc->running_on)) {
710 bool have_nodes =
false;
712 for (GList *iter = rsc->running_on; iter != NULL; iter = iter->next) {
715 have_nodes = add_output_node(outstr, n->
details->
uname, have_nodes);
718 g_string_append(outstr,
" ]");
722 return g_string_free(outstr, FALSE);
731 const char *target_role = NULL;
732 const char *cl = NULL;
734 xmlNode *child = NULL;
735 gchar *content = NULL;
737 pcmk__assert((kind != NULL) && pcmk__is_primitive(rsc));
740 const char *is_internal = g_hash_table_lookup(rsc->
meta,
746 crm_trace(
"skipping print of internal resource %s", rsc->
id);
758 }
else if (pcmk__is_primitive(rsc) && (rsc->
running_on == NULL)) {
761 }
else if (pcmk__list_of_multiple(rsc->
running_on)) {
786 const char *target_role = NULL;
791 const char *is_internal = g_hash_table_lookup(rsc->
meta,
797 crm_trace(
"skipping print of internal resource %s", rsc->
id);
820 const pcmk_node_t *node,
long options,
void *print_data)
822 const char *target_role = NULL;
827 const char *is_internal = g_hash_table_lookup(rsc->
meta,
833 crm_trace(
"skipping print of internal resource %s", rsc->
id);
840 native_print_xml(rsc, pre_text, options, print_data);
858 }
else if (pcmk__list_of_multiple(rsc->
running_on)) {
893 for (; gIter != NULL; gIter = gIter->next) {
947 native_print_xml(rsc, pre_text, options, print_data);
951 node = pcmk__current_node(rsc);
966 uint32_t show_opts = va_arg(args, uint32_t);
968 GList *only_node G_GNUC_UNUSED = va_arg(args, GList *);
969 GList *only_rsc = va_arg(args, GList *);
976 char ra_name[LINE_MAX];
977 const char *rsc_state = native_displayable_state(rsc, print_pending);
978 const char *target_role = NULL;
979 const char *active = pcmk__btoa(rsc->fns->active(rsc, TRUE));
986 char *nodes_running_on = NULL;
987 const char *pending = print_pending? native_pending_task(rsc) : NULL;
988 const char *locked_to = NULL;
993 if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) {
998 snprintf(ra_name, LINE_MAX,
"%s%s%s:%s",
class,
999 ((prov == NULL)?
"" :
PROVIDER_SEP), ((prov == NULL)?
"" : prov),
1002 if (rsc->meta != NULL) {
1006 nodes_running_on = pcmk__itoa(g_list_length(rsc->running_on));
1008 if (rsc->lock_node != NULL) {
1009 locked_to = rsc->lock_node->details->uname;
1029 free(nodes_running_on);
1033 if (rsc->running_on != NULL) {
1034 GList *gIter = rsc->running_on;
1036 for (; gIter != NULL; gIter = gIter->next) {
1058 uint32_t show_opts = va_arg(args, uint32_t);
1060 GList *only_node G_GNUC_UNUSED = va_arg(args, GList *);
1061 GList *only_rsc = va_arg(args, GList *);
1063 const pcmk_node_t *node = pcmk__current_node(rsc);
1083 uint32_t show_opts = va_arg(args, uint32_t);
1085 GList *only_node G_GNUC_UNUSED = va_arg(args, GList *);
1086 GList *only_rsc = va_arg(args, GList *);
1088 const pcmk_node_t *node = pcmk__current_node(rsc);
1143 for (; gIter != NULL; gIter = gIter->next) {
1149 }
else if (current) {
1170 for (; gIter != NULL; gIter = gIter->next) {
1174 *list = g_list_append(*list, node);
1184 get_rscs_brief(GList *rsc_list, GHashTable * rsc_table, GHashTable * active_table)
1186 GList *gIter = rsc_list;
1188 for (; gIter != NULL; gIter = gIter->next) {
1195 char buffer[LINE_MAX];
1197 int *rsc_counter = NULL;
1198 int *active_counter = NULL;
1200 if (!pcmk__is_primitive(rsc)) {
1204 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
class);
1209 offset += snprintf(buffer + offset, LINE_MAX - offset,
1213 offset += snprintf(buffer + offset, LINE_MAX - offset,
":%s", kind);
1217 rsc_counter = g_hash_table_lookup(rsc_table, buffer);
1218 if (rsc_counter == NULL) {
1221 g_hash_table_insert(rsc_table, strdup(buffer), rsc_counter);
1229 for (; gIter2 != NULL; gIter2 = gIter2->next) {
1231 GHashTable *node_table = NULL;
1238 node_table = g_hash_table_lookup(active_table, node->
details->
uname);
1239 if (node_table == NULL) {
1241 g_hash_table_insert(active_table, strdup(node->
details->
uname), node_table);
1244 active_counter = g_hash_table_lookup(node_table, buffer);
1245 if (active_counter == NULL) {
1247 *active_counter = 0;
1248 g_hash_table_insert(node_table, strdup(buffer), active_counter);
1250 (*active_counter)++;
1257 destroy_node_table(gpointer
data)
1259 GHashTable *node_table =
data;
1262 g_hash_table_destroy(node_table);
1272 void *print_data, gboolean print_all)
1276 GHashTableIter hash_iter;
1278 int *rsc_counter = NULL;
1280 get_rscs_brief(rsc_list, rsc_table, active_table);
1282 g_hash_table_iter_init(&hash_iter, rsc_table);
1283 while (g_hash_table_iter_next(&hash_iter, (gpointer *)&
type, (gpointer *)&rsc_counter)) {
1284 GHashTableIter hash_iter2;
1285 char *node_name = NULL;
1286 GHashTable *node_table = NULL;
1287 int active_counter_all = 0;
1289 g_hash_table_iter_init(&hash_iter2, active_table);
1290 while (g_hash_table_iter_next(&hash_iter2, (gpointer *)&node_name, (gpointer *)&node_table)) {
1291 int *active_counter = g_hash_table_lookup(node_table,
type);
1293 if (active_counter == NULL || *active_counter == 0) {
1297 active_counter_all += *active_counter;
1309 status_print(
"%s%d/%d\t(%s):\tActive %s\n", pre_text ? pre_text :
"",
1310 active_counter ? *active_counter : 0,
1311 rsc_counter ? *rsc_counter : 0,
type,
1312 active_counter && (*active_counter > 0) && node_name ? node_name :
"");
1314 status_print(
"%s%d\t(%s):\tActive %s\n", pre_text ? pre_text :
"",
1315 active_counter ? *active_counter : 0,
type,
1316 active_counter && (*active_counter > 0) && node_name ? node_name :
"");
1324 if (print_all && active_counter_all == 0) {
1329 status_print(
"%s%d/%d\t(%s):\tActive\n", pre_text ? pre_text :
"",
1331 rsc_counter ? *rsc_counter : 0,
type);
1340 g_hash_table_destroy(rsc_table);
1344 g_hash_table_destroy(active_table);
1345 active_table = NULL;
1357 get_rscs_brief(rsc_list, rsc_table, active_table);
1362 sorted_rscs = g_hash_table_get_keys(rsc_table);
1363 sorted_rscs = g_list_sort(sorted_rscs, (GCompareFunc) strcmp);
1365 for (GList *gIter = sorted_rscs; gIter; gIter = gIter->next) {
1366 char *
type = (
char *) gIter->data;
1367 int *rsc_counter = g_hash_table_lookup(rsc_table,
type);
1369 GList *sorted_nodes = NULL;
1370 int active_counter_all = 0;
1376 sorted_nodes = g_hash_table_get_keys(active_table);
1379 for (GList *gIter2 = sorted_nodes; gIter2; gIter2 = gIter2->next) {
1380 char *node_name = (
char *) gIter2->data;
1381 GHashTable *node_table = g_hash_table_lookup(active_table, node_name);
1382 int *active_counter = NULL;
1384 if (node_table == NULL) {
1388 active_counter = g_hash_table_lookup(node_table,
type);
1390 if (active_counter == NULL || *active_counter == 0) {
1394 active_counter_all += *active_counter;
1402 out->
list_item(out, NULL,
"%d/%d\t(%s):\tActive %s",
1404 rsc_counter ? *rsc_counter : 0,
type,
1405 (*active_counter > 0) && node_name ? node_name :
"");
1407 out->
list_item(out, NULL,
"%d\t(%s):\tActive %s",
1408 *active_counter,
type,
1409 (*active_counter > 0) && node_name ? node_name :
"");
1416 out->
list_item(out, NULL,
"%d/%d\t(%s):\tActive",
1418 rsc_counter ? *rsc_counter : 0,
type);
1423 g_list_free(sorted_nodes);
1428 g_hash_table_destroy(rsc_table);
1432 g_hash_table_destroy(active_table);
1433 active_table = NULL;
1436 g_list_free(sorted_rscs);
1444 gboolean check_parent)
1449 }
else if (check_parent && rsc->
parent) {
const pcmk_resource_t * pe__const_top_resource(const pcmk_resource_t *rsc, bool include_bundle)
#define CRM_CHECK(expr, failure_action)
#define PCMK__VALUE_RSC_OK
void native_print(pcmk_resource_t *rsc, const char *pre_text, long options, void *print_data)
const char * pcmk_role_text(enum rsc_role_e role)
Get readable description of a resource role.
Also match anonymous clone instances by base name.
pcmk_node_t *(* location)(const pcmk_resource_t *rsc, GList **list, int current)
Control output from tools.
int pcmk__scan_min_int(const char *text, int *result, int minimum)
pcmk_node_t * pe__find_active_requires(const pcmk_resource_t *rsc, unsigned int *count)
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
#define PCMK_XA_NODES_RUNNING_ON
xmlNode * pe__failed_probe_for_rsc(const pcmk_resource_t *rsc, const char *name)
#define pcmk__rsc_trace(rsc, fmt, args...)
Match only clones and their instances, by either clone or instance ID.
#define PCMK__VALUE_RSC_MULTIPLE
int pe__rscs_brief_output(pcmk__output_t *out, GList *rsc_list, uint32_t show_opts)
#define pcmk__rsc_info(rsc, fmt, args...)
void pe__force_anon(const char *standard, pcmk_resource_t *rsc, const char *rid, pcmk_scheduler_t *scheduler)
enum rsc_role_e next_role
#define pcmk__insert_meta(obj, name, value)
#define pcmk__config_err(fmt...)
char * native_parameter(pcmk_resource_t *rsc, pcmk_node_t *node, gboolean create, const char *name, pcmk_scheduler_t *scheduler)
#define PCMK_ACTION_MONITOR
const char * pe__resource_description(const pcmk_resource_t *rsc, uint32_t show_opts)
#define PCMK_XA_FAILURE_IGNORED
gboolean pe__native_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
#define PCMK_ACTION_MIGRATE_TO
#define CRM_LOG_ASSERT(expr)
enum crm_ais_msg_types type
const char * rsc_printable_id(const pcmk_resource_t *rsc)
xmlNodePtr pcmk__output_create_html_node(pcmk__output_t *out, const char *element_name, const char *id, const char *class_name, const char *text)
pcmk_resource_t * container
int pe__resource_text(pcmk__output_t *out, va_list args)
#define PCMK_XA_TARGET_ROLE
int pe__common_output_html(pcmk__output_t *out, const pcmk_resource_t *rsc, const char *name, const pcmk_node_t *node, uint32_t show_opts)
enum rsc_role_e pcmk_parse_role(const char *role)
Parse a resource role from a string role specification.
void pcmk__xe_set_content(xmlNode *node, const char *format,...) G_GNUC_PRINTF(2
#define PCMK__VALUE_RSC_FAILURE_IGNORED
void print_rscs_brief(GList *rsc_list, const char *pre_text, long options, void *print_data, gboolean print_all)
Also match clone instance ID from resource history.
pcmk_resource_t *(* find_rsc)(pcmk_resource_t *rsc, const char *search, const pcmk_node_t *node, int flags)
const char * pcmk__multiply_active_text(enum rsc_recovery_type recovery)
Get readable description of a multiply-active recovery type.
#define PCMK_META_GLOBALLY_UNIQUE
#define PCMK_ACTION_DEMOTE
void common_free(pcmk_resource_t *rsc)
int pe__common_output_text(pcmk__output_t *out, const pcmk_resource_t *rsc, const char *name, const pcmk_node_t *node, uint32_t show_opts)
#define crm_debug(fmt, args...)
#define PCMK_XA_LOCKED_TO
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
int pe__name_and_nvpairs_xml(pcmk__output_t *out, bool is_list, const char *tag_name,...) G_GNUC_NULL_TERMINATED
pcmk_node_t * pe_find_node_id(const GList *node_list, const char *id)
Find a node by ID in a list of nodes.
void resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, const char *tag, pcmk_scheduler_t *scheduler)
void native_add_running(pcmk_resource_t *rsc, pcmk_node_t *node, pcmk_scheduler_t *scheduler, gboolean failed)
unsigned int pe__primitive_max_per_node(const pcmk_resource_t *rsc)
#define PCMK_XA_DESCRIPTION
#define crm_trace(fmt, args...)
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
enum rsc_recovery_type recovery_type
#define PCMK_ACTION_START
gboolean native_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
#define PCMK__VALUE_RSC_FAILED
Wrappers for and extensions to libxml2.
#define PCMK_META_TARGET_ROLE
Match clone instances (even unique) by base name as well as exact ID.
enum rsc_role_e native_resource_state(const pcmk_resource_t *rsc, gboolean current)
GHashTable * pe__node_list2table(const GList *list)
#define PCMK_XA_RESOURCE_AGENT
#define pcmk__set_rsc_flags(resource, flags_to_set)
PCMK__OUTPUT_ARGS("primitive", "uint32_t", "pcmk_resource_t *", "GList *", "GList *")
gboolean native_active(pcmk_resource_t *rsc, gboolean all)
#define pcmk__str_copy(str)
void pcmk__output_xml_pop_parent(pcmk__output_t *out)
xmlNode * pcmk__html_create(xmlNode *parent, const char *name, const char *id, const char *class)
#define PCMK_XA_MAINTENANCE
int pe__resource_xml(pcmk__output_t *out, va_list args)
#define pcmk__assert(expr)
gboolean(* active)(pcmk_resource_t *rsc, gboolean all)
Cluster status and scheduling.
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
pcmk__action_result_t result
pcmk_scheduler_t * scheduler
gchar * pcmk__native_output_string(const pcmk_resource_t *rsc, const char *name, const pcmk_node_t *node, uint32_t show_opts, const char *target_role, bool show_nodes)
If matching by node, compare current node instead of assigned node.
void(*) void(* list_item)(pcmk__output_t *out, const char *name, const char *format,...) G_GNUC_PRINTF(3
#define status_print(fmt, args...)
#define PCMK_ACTION_MIGRATE_FROM
This structure contains everything that makes up a single output formatter.
pcmk_node_t * allocated_to
#define PCMK_ACTION_PROMOTE
int pe__resource_html(pcmk__output_t *out, va_list args)
int pcmk__numeric_strcasecmp(const char *s1, const char *s2)
gboolean(* is_filtered)(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
#define PCMK__VALUE_RSC_MANAGED
pcmk_node_t * native_location(const pcmk_resource_t *rsc, GList **list, int current)
#define PCMK__META_INTERNAL_RSC
uint32_t pcmk_get_ra_caps(const char *standard)
Get capabilities of a resource agent standard.
pcmk_node_t * pending_node
gboolean crm_is_true(const char *s)
void common_print(pcmk_resource_t *rsc, const char *pre_text, const char *name, const pcmk_node_t *node, long options, void *print_data)
Resource role is unknown.
GHashTable * pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Get a table of resource parameters.
#define pcmk__assert_alloc(nmemb, size)
#define pcmk__clear_rsc_flags(resource, flags_to_clear)
pcmk_resource_t * native_find_rsc(pcmk_resource_t *rsc, const char *id, const pcmk_node_t *on_node, int flags)
void native_free(pcmk_resource_t *rsc)
pcmk_resource_t * remote_rsc
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
GHashTable * allowed_nodes
gboolean pcmk__str_in_list(const gchar *s, const GList *lst, uint32_t flags)