22 #ifdef PCMK__COMPAT_2_0 23 #define PROVIDER_SEP "::" 25 #define PROVIDER_SEP ":" 35 unsigned int count = 0;
49 if ((rsc->
priority == 0) || (failed == TRUE)) {
62 pe_rsc_trace(rsc,
"%s now has priority %d with %s'%s' (priority: %d%s)",
74 for (; gIter != NULL; gIter = gIter->next) {
78 pe_rsc_trace(rsc,
"%s now has priority %d with %s'%s' (priority: %d%s) " 96 for (; gIter != NULL; gIter = gIter->next) {
105 pe_rsc_trace(rsc,
"Adding %s to %s %s", rsc->
id, pe__node_name(node),
112 native_priority_to_node(rsc, node, failed);
136 if (is_multiply_active(rsc)) {
140 GHashTableIter gIter;
149 while (g_hash_table_iter_next(&gIter, NULL, (
void **)&local_node)) {
167 for (; gIter != NULL; gIter = gIter->next) {
183 crm_debug(
"%s is active on multiple nodes including %s: %s",
184 rsc->
id, pe__node_name(node),
189 rsc->
id, pe__node_name(node));
192 if (rsc->
parent != NULL) {
202 g_list_foreach(rsc->
children, (GFunc) recursive_clear_unique, NULL);
217 && pe_rsc_is_clone(
parent)) {
231 recursive_clear_unique(
parent, NULL);
232 recursive_clear_unique(rsc, NULL);
237 pe_err(
"Resource %s is of type %s and therefore " 238 "cannot be used as a promotable clone resource",
249 rsc->
id, pe__node_name(node));
254 for (GList *iter = rsc->
running_on; iter; iter = iter->next) {
284 const char *rid =
ID(rsc->
xml);
293 }
else if (!strcmp(
id, rsc->
id)) {
303 match = pe_base_name_eq(rsc,
id);
306 if (match && on_node) {
307 if (!rsc_is_on_node(rsc, on_node,
flags)) {
316 for (GList *gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
332 char *value_copy = NULL;
333 const char *value = NULL;
334 GHashTable *params = NULL;
341 value = g_hash_table_lookup(params,
name);
344 value = g_hash_table_lookup(rsc->
meta,
name);
353 for (GList *gIter = rsc->
running_on; gIter != NULL; gIter = gIter->next) {
358 rsc->
id, pe__node_name(a_node));
363 rsc->
id, pe__node_name(a_node));
366 rsc->
id, pe__node_name(a_node));
373 struct print_data_s {
381 const char *pending_state = NULL;
384 pending_state =
"Starting";
388 pending_state =
"Stopping";
392 pending_state =
"Migrating";
397 pending_state =
"Migrating";
401 pending_state =
"Promoting";
405 pending_state =
"Demoting";
408 return pending_state;
414 const char *pending_task = NULL;
417 pending_task =
"Monitoring";
448 native_displayable_state(
const pcmk_resource_t *rsc,
bool print_pending)
450 const char *rsc_state = NULL;
453 rsc_state = native_pending_state(rsc);
455 if (rsc_state == NULL) {
456 rsc_state =
role2text(native_displayable_role(rsc));
466 native_print_xml(
pcmk_resource_t *rsc,
const char *pre_text,
long options,
472 const char *target_role = NULL;
479 ((prov == NULL)?
"" : prov),
501 const char *pending_task = native_pending_task(rsc);
516 for (; gIter != NULL; gIter = gIter->next) {
532 add_output_flag(GString *s,
const char *flag_desc,
bool have_flags)
534 g_string_append(s, (have_flags?
", " :
" ("));
535 g_string_append(s, flag_desc);
541 add_output_node(GString *s,
const char *node,
bool have_nodes)
543 g_string_append(s, (have_nodes?
" " :
" [ "));
544 g_string_append(s, node);
565 const char *target_role,
bool show_nodes)
568 const char *provider = NULL;
570 GString *outstr = NULL;
571 bool have_flags =
false;
578 CRM_CHECK(kind != NULL, kind =
"unknown");
579 CRM_CHECK(
class != NULL,
class =
"unknown");
585 if ((node == NULL) && (rsc->lock_node != NULL)) {
586 node = rsc->lock_node;
589 || pcmk__list_of_multiple(rsc->running_on)) {
593 outstr = g_string_sized_new(128);
598 pcmk__s(provider,
""),
":", kind,
"):\t", NULL);
602 g_string_append(outstr,
" ORPHANED");
605 enum rsc_role_e role = native_displayable_role(rsc);
607 g_string_append(outstr,
" FAILED");
609 pcmk__add_word(&outstr, 0,
role2text(role));
614 pcmk__add_word(&outstr, 0, native_displayable_state(rsc, show_pending));
617 pcmk__add_word(&outstr, 0, pe__node_name(node));
623 if (probe_op != NULL) {
634 have_flags = add_output_flag(outstr,
"UNCLEAN", have_flags);
636 if (node && (node == rsc->lock_node)) {
637 have_flags = add_output_flag(outstr,
"LOCKED", have_flags);
640 const char *pending_task = native_pending_task(rsc);
643 have_flags = add_output_flag(outstr, pending_task, have_flags);
654 have_flags = add_output_flag(outstr,
"disabled", have_flags);
659 have_flags = add_output_flag(outstr,
"target-role:", have_flags);
660 g_string_append(outstr, target_role);
665 if (pcmk_any_flags_set(rsc->flags,
668 have_flags = add_output_flag(outstr,
"blocked", have_flags);
671 have_flags = add_output_flag(outstr,
"maintenance", have_flags);
674 have_flags = add_output_flag(outstr,
"unmanaged", have_flags);
678 have_flags = add_output_flag(outstr,
"failure ignored", have_flags);
683 g_string_append_c(outstr,
')');
688 || pcmk__list_of_multiple(rsc->running_on)) {
692 g_string_append(outstr,
" (");
693 g_string_append(outstr, desc);
694 g_string_append(outstr,
")");
700 && pcmk__list_of_multiple(rsc->running_on)) {
701 bool have_nodes =
false;
703 for (GList *iter = rsc->running_on; iter != NULL; iter = iter->next) {
706 have_nodes = add_output_node(outstr, n->
details->
uname, have_nodes);
709 g_string_append(outstr,
" ]");
713 return g_string_free(outstr, FALSE);
722 const char *target_role = NULL;
724 xmlNodePtr list_node = NULL;
725 const char *cl = NULL;
736 crm_trace(
"skipping print of internal resource %s", rsc->
id);
752 }
else if (pcmk__list_of_multiple(rsc->
running_on)) {
756 cl =
"rsc-failure-ignored";
779 const char *target_role = NULL;
789 crm_trace(
"skipping print of internal resource %s", rsc->
id);
812 const pcmk_node_t *node,
long options,
void *print_data)
814 const char *target_role = NULL;
819 const char *is_internal = g_hash_table_lookup(rsc->
meta,
825 crm_trace(
"skipping print of internal resource %s", rsc->
id);
832 native_print_xml(rsc, pre_text, options, print_data);
850 }
else if (pcmk__list_of_multiple(rsc->
running_on)) {
885 for (; gIter != NULL; gIter = gIter->next) {
938 native_print_xml(rsc, pre_text, options, print_data);
942 node = pe__current_node(rsc);
957 uint32_t show_opts = va_arg(args, uint32_t);
959 GList *only_node G_GNUC_UNUSED = va_arg(args, GList *);
960 GList *only_rsc = va_arg(args, GList *);
965 const char *rsc_state = native_displayable_state(rsc, print_pending);
967 const char *desc = NULL;
968 char ra_name[LINE_MAX];
969 char *nodes_running_on = NULL;
970 const char *lock_node_name = NULL;
972 const char *target_role = NULL;
976 if (rsc->meta != NULL) {
982 if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) {
987 snprintf(ra_name, LINE_MAX,
"%s%s%s:%s",
class,
988 ((prov == NULL)?
"" :
PROVIDER_SEP), ((prov == NULL)?
"" : prov),
991 nodes_running_on = pcmk__itoa(g_list_length(rsc->running_on));
993 if (rsc->lock_node != NULL) {
994 lock_node_name = rsc->lock_node->details->uname;
999 "resource_agent", ra_name,
1001 "target_role", target_role,
1002 "active", pcmk__btoa(rsc->fns->active(rsc, TRUE)),
1009 "nodes_running_on", nodes_running_on,
1010 "pending", (print_pending? native_pending_task(rsc) : NULL),
1011 "locked_to", lock_node_name,
1012 "description", desc);
1013 free(nodes_running_on);
1017 if (rsc->running_on != NULL) {
1018 GList *gIter = rsc->running_on;
1020 for (; gIter != NULL; gIter = gIter->next) {
1040 uint32_t show_opts = va_arg(args, uint32_t);
1042 GList *only_node G_GNUC_UNUSED = va_arg(args, GList *);
1043 GList *only_rsc = va_arg(args, GList *);
1065 uint32_t show_opts = va_arg(args, uint32_t);
1067 GList *only_node G_GNUC_UNUSED = va_arg(args, GList *);
1068 GList *only_rsc = va_arg(args, GList *);
1088 pe_rsc_trace(rsc,
"Freeing resource action list (not the data)");
1125 for (; gIter != NULL; gIter = gIter->next) {
1131 }
else if (current) {
1152 for (; gIter != NULL; gIter = gIter->next) {
1156 *list = g_list_append(*list, node);
1166 get_rscs_brief(GList *rsc_list, GHashTable * rsc_table, GHashTable * active_table)
1168 GList *gIter = rsc_list;
1170 for (; gIter != NULL; gIter = gIter->next) {
1177 char buffer[LINE_MAX];
1179 int *rsc_counter = NULL;
1180 int *active_counter = NULL;
1186 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
class);
1191 offset += snprintf(buffer + offset, LINE_MAX - offset,
1195 offset += snprintf(buffer + offset, LINE_MAX - offset,
":%s", kind);
1199 rsc_counter = g_hash_table_lookup(rsc_table, buffer);
1200 if (rsc_counter == NULL) {
1201 rsc_counter = calloc(1,
sizeof(
int));
1203 g_hash_table_insert(rsc_table, strdup(buffer), rsc_counter);
1211 for (; gIter2 != NULL; gIter2 = gIter2->next) {
1213 GHashTable *node_table = NULL;
1220 node_table = g_hash_table_lookup(active_table, node->
details->
uname);
1221 if (node_table == NULL) {
1223 g_hash_table_insert(active_table, strdup(node->
details->
uname), node_table);
1226 active_counter = g_hash_table_lookup(node_table, buffer);
1227 if (active_counter == NULL) {
1228 active_counter = calloc(1,
sizeof(
int));
1229 *active_counter = 0;
1230 g_hash_table_insert(node_table, strdup(buffer), active_counter);
1232 (*active_counter)++;
1239 destroy_node_table(gpointer
data)
1241 GHashTable *node_table =
data;
1244 g_hash_table_destroy(node_table);
1254 void *print_data, gboolean print_all)
1258 GHashTableIter hash_iter;
1260 int *rsc_counter = NULL;
1262 get_rscs_brief(rsc_list, rsc_table, active_table);
1264 g_hash_table_iter_init(&hash_iter, rsc_table);
1265 while (g_hash_table_iter_next(&hash_iter, (gpointer *)&
type, (gpointer *)&rsc_counter)) {
1266 GHashTableIter hash_iter2;
1267 char *node_name = NULL;
1268 GHashTable *node_table = NULL;
1269 int active_counter_all = 0;
1271 g_hash_table_iter_init(&hash_iter2, active_table);
1272 while (g_hash_table_iter_next(&hash_iter2, (gpointer *)&node_name, (gpointer *)&node_table)) {
1273 int *active_counter = g_hash_table_lookup(node_table,
type);
1275 if (active_counter == NULL || *active_counter == 0) {
1279 active_counter_all += *active_counter;
1291 status_print(
"%s%d/%d\t(%s):\tActive %s\n", pre_text ? pre_text :
"",
1292 active_counter ? *active_counter : 0,
1293 rsc_counter ? *rsc_counter : 0,
type,
1294 active_counter && (*active_counter > 0) && node_name ? node_name :
"");
1296 status_print(
"%s%d\t(%s):\tActive %s\n", pre_text ? pre_text :
"",
1297 active_counter ? *active_counter : 0,
type,
1298 active_counter && (*active_counter > 0) && node_name ? node_name :
"");
1306 if (print_all && active_counter_all == 0) {
1311 status_print(
"%s%d/%d\t(%s):\tActive\n", pre_text ? pre_text :
"",
1313 rsc_counter ? *rsc_counter : 0,
type);
1322 g_hash_table_destroy(rsc_table);
1326 g_hash_table_destroy(active_table);
1327 active_table = NULL;
1339 get_rscs_brief(rsc_list, rsc_table, active_table);
1344 sorted_rscs = g_hash_table_get_keys(rsc_table);
1345 sorted_rscs = g_list_sort(sorted_rscs, (GCompareFunc) strcmp);
1347 for (GList *gIter = sorted_rscs; gIter; gIter = gIter->next) {
1348 char *
type = (
char *) gIter->data;
1349 int *rsc_counter = g_hash_table_lookup(rsc_table,
type);
1351 GList *sorted_nodes = NULL;
1352 int active_counter_all = 0;
1358 sorted_nodes = g_hash_table_get_keys(active_table);
1361 for (GList *gIter2 = sorted_nodes; gIter2; gIter2 = gIter2->next) {
1362 char *node_name = (
char *) gIter2->data;
1363 GHashTable *node_table = g_hash_table_lookup(active_table, node_name);
1364 int *active_counter = NULL;
1366 if (node_table == NULL) {
1370 active_counter = g_hash_table_lookup(node_table,
type);
1372 if (active_counter == NULL || *active_counter == 0) {
1376 active_counter_all += *active_counter;
1384 out->
list_item(out, NULL,
"%d/%d\t(%s):\tActive %s",
1386 rsc_counter ? *rsc_counter : 0,
type,
1387 (*active_counter > 0) && node_name ? node_name :
"");
1389 out->
list_item(out, NULL,
"%d\t(%s):\tActive %s",
1390 *active_counter,
type,
1391 (*active_counter > 0) && node_name ? node_name :
"");
1398 out->
list_item(out, NULL,
"%d/%d\t(%s):\tActive",
1400 rsc_counter ? *rsc_counter : 0,
type);
1405 g_list_free(sorted_nodes);
1410 g_hash_table_destroy(rsc_table);
1414 g_hash_table_destroy(active_table);
1415 active_table = NULL;
1418 g_list_free(sorted_rscs);
1426 gboolean check_parent)
1431 }
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)
void native_print(pcmk_resource_t *rsc, const char *pre_text, long options, void *print_data)
Also match anonymous clone instances by base name.
pcmk_node_t *(* location)(const pcmk_resource_t *rsc, GList **list, int current)
List nodes where a resource (or any of its children) is.
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)
enum rsc_role_e role
Resource's current role.
xmlNode * pe__failed_probe_for_rsc(const pcmk_resource_t *rsc, const char *name)
GList * children
Resource's child resources, if any.
Match only clones and their instances, by either clone or instance ID.
#define XML_BOOLEAN_FALSE
int pe__rscs_brief_output(pcmk__output_t *out, GList *rsc_list, uint32_t show_opts)
void pe__force_anon(const char *standard, pcmk_resource_t *rsc, const char *rid, pcmk_scheduler_t *scheduler)
xmlNode * xml
Resource configuration (possibly expanded from template)
enum rsc_role_e next_role
Resource's scheduled next role.
xmlNode * pcmk_create_html_node(xmlNode *parent, const char *element_name, const char *id, const char *class_name, const char *text)
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)
GHashTable * meta
Resource's meta-attributes.
Whether resource, its node, or entire cluster is in maintenance mode.
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
Resource containing this one, if any.
int pe__resource_text(pcmk__output_t *out, va_list args)
Implementation of pcmk_scheduler_t.
char * pending_task
Pending action in history, if any.
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)
#define pe__set_resource_flags(resource, flags_to_set)
GList * nodes
Nodes in cluster.
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)
Search for a resource ID in a resource and its children.
const char * role2text(enum rsc_role_e role)
Stop on all and leave stopped.
#define PCMK_ACTION_DEMOTE
pcmk_resource_t * parent
Resource's parent resource, if any.
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)
Implementation of pcmk_resource_t.
#define crm_debug(fmt, args...)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
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)
int pe__name_and_nvpairs_xml(pcmk__output_t *out, bool is_list, const char *tag_name, size_t pairs_count,...)
int priority
Configured priority.
unsigned int pe__primitive_max_per_node(const pcmk_resource_t *rsc)
Whether resource is considered failed.
#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
Basic node information.
enum rsc_recovery_type recovery_type
How to recover if failed.
#define PCMK_ACTION_START
gboolean native_unpack(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
#define XML_AGENT_ATTR_PROVIDER
unsigned long long flags
Group of enum pcmk_rsc_flags.
const char * uname
Node name in cluster.
void pcmk__str_update(char **str, const char *value)
char * clone_name
Resource instance ID in history.
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 XML_RSC_ATTR_TARGET_ROLE
PCMK__OUTPUT_ARGS("primitive", "uint32_t", "pcmk_resource_t *", "GList *", "GList *")
gboolean native_active(pcmk_resource_t *rsc, gboolean all)
Whether resource is blocked from further action.
Implementation of pcmk_node_t.
enum rsc_role_e text2role(const char *role)
enum pe_obj_types variant
Resource variant.
void pcmk__output_xml_pop_parent(pcmk__output_t *out)
const char * id
Node ID at the cluster layer.
int pe__resource_xml(pcmk__output_t *out, va_list args)
#define XML_RSC_ATTR_UNIQUE
GList * running_rsc
List of resources active on node.
Whether resource has an ignorable failure.
gboolean(* active)(pcmk_resource_t *rsc, gboolean all)
Check whether a resource is active.
Cluster status and scheduling.
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
pcmk__action_result_t result
void add_hash_param(GHashTable *hash, const char *name, const char *value)
pcmk_rsc_methods_t * fns
Resource object methods.
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
Node resource is assigned to.
#define XML_RSC_ATTR_INTERNAL_RSC
#define pe__clear_resource_flags(resource, flags_to_clear)
#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)
Check whether a given resource is in a list of resources.
GList * running_on
Nodes where resource may be active.
gboolean maintenance
Whether in maintenance mode.
pcmk_node_t * native_location(const pcmk_resource_t *rsc, GList **list, int current)
uint32_t pcmk_get_ra_caps(const char *standard)
Get capabilities of a resource agent standard.
pcmk_node_t * pending_node
Node on which pending_task is happening.
gboolean crm_is_true(const char *s)
Whether resource can be promoted and demoted.
void common_print(pcmk_resource_t *rsc, const char *pre_text, const char *name, const pcmk_node_t *node, long options, void *print_data)
#define pe_rsc_trace(rsc, fmt, args...)
GHashTable * pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Get a table of resource parameters.
Whether resource is managed.
gboolean unclean
Whether node requires fencing.
Whether resource has been removed from the configuration.
pcmk_resource_t * native_find_rsc(pcmk_resource_t *rsc, const char *id, const pcmk_node_t *on_node, int flags)
gboolean online
Whether online.
Whether resource is not an anonymous clone instance.
void native_free(pcmk_resource_t *rsc)
pcmk_resource_t * remote_rsc
Remote connection resource for node, if it is a Pacemaker Remote node.
#define pe_rsc_info(rsc, fmt, args...)
#define XML_AGENT_ATTR_CLASS
char * id
Resource ID in configuration.
GHashTable * allowed_nodes
Nodes where resource may run (key is node ID, not name)
gboolean pcmk__str_in_list(const gchar *s, const GList *lst, uint32_t flags)