19 #define VARIANT_CLONE 1 26 if (pe_rsc_is_clone(rsc)) {
27 clone_variant_data_t *clone_data = NULL;
29 get_clone_variant_data(clone_data, rsc);
32 "such as %s can be used only as anonymous clones",
33 rsc->
id, standard, rid);
35 clone_data->clone_node_max = 1;
36 clone_data->clone_max = QB_MIN(clone_data->clone_max,
37 g_list_length(data_set->
nodes));
44 char *child_id = NULL;
46 const char *child_base = NULL;
47 clone_variant_data_t *clone_data = NULL;
49 get_clone_variant_data(clone_data, rsc);
51 child_base =
ID(clone_data->xml_obj_child);
62 gboolean as_orphan = FALSE;
66 xmlNode *child_copy = NULL;
67 clone_variant_data_t *clone_data = NULL;
69 get_clone_variant_data(clone_data, rsc);
71 CRM_CHECK(clone_data->xml_obj_child != NULL,
return FALSE);
73 if (clone_data->total_clones >= clone_data->clone_max) {
79 inc_num = crm_itoa(clone_data->total_clones);
80 inc_max = crm_itoa(clone_data->clone_max);
82 child_copy =
copy_xml(clone_data->xml_obj_child);
86 if (
common_unpack(child_copy, &child_rsc, rsc, data_set) == FALSE) {
94 clone_data->total_clones += 1;
95 pe_rsc_trace(child_rsc,
"Setting clone attributes for: %s", child_rsc->
id);
115 xmlNode *a_child = NULL;
116 xmlNode *xml_obj = rsc->
xml;
117 clone_variant_data_t *clone_data = NULL;
125 clone_data = calloc(1,
sizeof(clone_variant_data_t));
129 const char *promoted_max = NULL;
130 const char *promoted_node_max = NULL;
132 promoted_max = g_hash_table_lookup(rsc->
meta,
134 if (promoted_max == NULL) {
136 promoted_max = g_hash_table_lookup(rsc->
meta,
140 promoted_node_max = g_hash_table_lookup(rsc->
meta,
142 if (promoted_node_max == NULL) {
144 promoted_node_max = g_hash_table_lookup(rsc->
meta,
149 clone_data->promoted_node_max =
crm_parse_int(promoted_node_max,
"1");
155 clone_data->clone_node_max =
crm_parse_int(max_clones_node,
"1");
160 }
else if (pcmk__list_of_multiple(data_set->
nodes)) {
161 clone_data->clone_max = g_list_length(data_set->
nodes);
164 clone_data->clone_max = 1;
171 "because anonymous clones support only one instance " 172 "per node", rsc->
id);
173 clone_data->clone_node_max = 1;
177 pe_rsc_trace(rsc,
"\tClone max: %d", clone_data->clone_max);
178 pe_rsc_trace(rsc,
"\tClone node max: %d", clone_data->clone_node_max);
185 for (a_child = pcmk__xe_first_child(xml_obj); a_child != NULL;
186 a_child = pcmk__xe_next(a_child)) {
189 clone_data->xml_obj_child = a_child;
194 if (clone_data->xml_obj_child == NULL) {
215 if (clone_data->clone_max <= 0) {
225 for (lpc = 0; lpc < clone_data->clone_max; lpc++) {
232 pe_rsc_trace(rsc,
"Added %d children to resource %s...", clone_data->clone_max, rsc->
id);
241 for (; gIter != NULL; gIter = gIter->next) {
243 gboolean child_active = child_rsc->
fns->
active(child_rsc, all);
245 if (all == FALSE && child_active) {
247 }
else if (all && child_active == FALSE) {
260 short_print(
char *list,
const char *prefix,
const char *
type,
const char *suffix,
long options,
void *print_data)
287 const char *target_role = g_hash_table_lookup(rsc->
meta,
300 const char *target_role = configured_role_str(rsc);
309 clone_print_xml(
pe_resource_t * rsc,
const char *pre_text,
long options,
void *print_data)
312 const char *target_role = configured_role_str(rsc);
329 for (; gIter != NULL; gIter = gIter->next) {
332 child_rsc->
fns->
print(child_rsc, child_text, options, print_data);
352 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
372 char *list_text = NULL;
373 char *child_text = NULL;
374 char *stopped_list = NULL;
375 size_t list_text_len = 0;
376 size_t stopped_list_len = 0;
382 clone_variant_data_t *clone_data = NULL;
383 int active_instances = 0;
385 if (pre_text == NULL) {
390 clone_print_xml(rsc, pre_text, options, print_data);
394 get_clone_variant_data(clone_data, rsc);
399 pre_text ? pre_text :
"", rsc->
id,
ID(clone_data->xml_obj_child),
411 for (; gIter != NULL; gIter = gIter->next) {
412 gboolean print_full = FALSE;
414 gboolean partially_active = child_rsc->
fns->
active(child_rsc, FALSE);
434 }
else if (partially_active == FALSE) {
438 pcmk__add_word(&stopped_list, &stopped_list_len, child_rsc->
id);
448 }
else if (child_rsc->
fns->
active(child_rsc, TRUE)) {
462 master_list = g_list_append(master_list, location);
465 started_list = g_list_append(started_list, location);
482 child_rsc->
fns->
print(child_rsc, child_text, options, print_data);
491 for (gIter = master_list; gIter; gIter = gIter->next) {
494 pcmk__add_word(&list_text, &list_text_len,
host->details->
uname);
498 short_print(list_text, child_text,
"Masters", NULL, options, print_data);
499 g_list_free(master_list);
506 for (gIter = started_list; gIter; gIter = gIter->next) {
509 pcmk__add_word(&list_text, &list_text_len,
host->details->
uname);
517 short_print(list_text, child_text,
"Slaves (target-role)", NULL, options, print_data);
519 short_print(list_text, child_text,
"Slaves", NULL, options, print_data);
523 short_print(list_text, child_text,
"Started", NULL, options, print_data);
526 g_list_free(started_list);
532 const char *state =
"Stopped";
536 state =
"Stopped (disabled)";
540 && (clone_data->clone_max > active_instances)) {
548 stopped_list_len = 0;
554 list = g_hash_table_get_values(rsc->
known_on);
558 for (nIter = list; nIter != NULL; nIter = nIter->next) {
562 pcmk__add_word(&stopped_list, &stopped_list_len,
569 short_print(stopped_list, child_text, state, NULL, options, print_data);
580 PCMK__OUTPUT_ARGS(
"clone",
"unsigned int",
"pe_resource_t *",
"GListPtr",
"GListPtr")
584 unsigned int options = va_arg(args,
unsigned int);
591 gboolean printed_header = FALSE;
592 gboolean print_everything = TRUE;
601 for (; gIter != NULL; gIter = gIter->next) {
608 if (child_rsc->
fns->
is_filtered(child_rsc, only_rsc, print_everything)) {
612 if (!printed_header) {
613 printed_header = TRUE;
623 "target_role", configured_role_str(rsc));
627 out->message(out, crm_map_element_name(child_rsc->
xml), options,
628 child_rsc, only_node, only_rsc);
631 if (printed_header) {
638 PCMK__OUTPUT_ARGS(
"clone",
"unsigned int",
"pe_resource_t *",
"GListPtr",
"GListPtr")
642 unsigned int options = va_arg(args,
unsigned int);
647 char *list_text = NULL;
648 char *stopped_list = NULL;
649 size_t list_text_len = 0;
650 size_t stopped_list_len = 0;
656 clone_variant_data_t *clone_data = NULL;
657 int active_instances = 0;
659 gboolean print_everything = TRUE;
661 get_clone_variant_data(clone_data, rsc);
670 out->begin_list(out, NULL, NULL,
"Clone Set: %s [%s]%s%s%s%s",
671 rsc->
id,
ID(clone_data->xml_obj_child),
678 for (; gIter != NULL; gIter = gIter->next) {
679 gboolean print_full = FALSE;
681 gboolean partially_active = child_rsc->
fns->
active(child_rsc, FALSE);
687 if (child_rsc->
fns->
is_filtered(child_rsc, only_rsc, print_everything)) {
709 }
else if (partially_active == FALSE) {
713 pcmk__add_word(&stopped_list, &stopped_list_len, child_rsc->
id);
723 }
else if (child_rsc->
fns->
active(child_rsc, TRUE)) {
737 master_list = g_list_append(master_list, location);
740 started_list = g_list_append(started_list, location);
757 all = g_list_prepend(all, strdup(
"*"));
758 out->message(out, crm_map_element_name(child_rsc->
xml), options,
759 child_rsc, only_node, all);
760 g_list_free_full(all, free);
772 for (gIter = master_list; gIter; gIter = gIter->next) {
779 pcmk__add_word(&list_text, &list_text_len,
host->details->
uname);
783 if (list_text != NULL) {
784 out->list_item(out, NULL,
" Masters: [ %s ]", list_text);
785 g_list_free(master_list);
793 for (gIter = started_list; gIter; gIter = gIter->next) {
800 pcmk__add_word(&list_text, &list_text_len,
host->details->
uname);
804 if (list_text != NULL) {
809 out->list_item(out, NULL,
" Slaves (target-role): [ %s ]", list_text);
811 out->list_item(out, NULL,
" Slaves: [ %s ]", list_text);
815 out->list_item(out, NULL,
" Started: [ %s ]", list_text);
818 g_list_free(started_list);
825 const char *state =
"Stopped";
829 state =
"Stopped (disabled)";
833 && (clone_data->clone_max > active_instances)) {
841 stopped_list_len = 0;
847 list = g_hash_table_get_values(rsc->
known_on);
851 for (nIter = list; nIter != NULL; nIter = nIter->next) {
856 pcmk__add_word(&stopped_list, &stopped_list_len,
863 if (stopped_list != NULL) {
864 out->list_item(out, NULL,
" %s: [ %s ]", state, stopped_list);
866 stopped_list_len = 0;
875 PCMK__OUTPUT_ARGS(
"clone",
"unsigned int",
"pe_resource_t *",
"GListPtr",
"GListPtr")
879 unsigned int options = va_arg(args,
unsigned int);
884 char *list_text = NULL;
885 char *stopped_list = NULL;
886 size_t list_text_len = 0;
887 size_t stopped_list_len = 0;
893 clone_variant_data_t *clone_data = NULL;
894 int active_instances = 0;
896 gboolean print_everything = TRUE;
898 get_clone_variant_data(clone_data, rsc);
907 out->begin_list(out, NULL, NULL,
"Clone Set: %s [%s]%s%s%s%s",
908 rsc->
id,
ID(clone_data->xml_obj_child),
915 for (; gIter != NULL; gIter = gIter->next) {
916 gboolean print_full = FALSE;
918 gboolean partially_active = child_rsc->
fns->
active(child_rsc, FALSE);
924 if (child_rsc->
fns->
is_filtered(child_rsc, only_rsc, print_everything)) {
946 }
else if (partially_active == FALSE) {
950 pcmk__add_word(&stopped_list, &stopped_list_len, child_rsc->
id);
960 }
else if (child_rsc->
fns->
active(child_rsc, TRUE)) {
974 master_list = g_list_append(master_list, location);
977 started_list = g_list_append(started_list, location);
994 all = g_list_prepend(all, strdup(
"*"));
995 out->message(out, crm_map_element_name(child_rsc->
xml), options,
996 child_rsc, only_node, all);
997 g_list_free_full(all, free);
1009 for (gIter = master_list; gIter; gIter = gIter->next) {
1016 pcmk__add_word(&list_text, &list_text_len,
host->details->
uname);
1020 if (list_text != NULL) {
1021 out->list_item(out,
"Masters",
"[ %s ]", list_text);
1022 g_list_free(master_list);
1030 for (gIter = started_list; gIter; gIter = gIter->next) {
1037 pcmk__add_word(&list_text, &list_text_len,
host->details->
uname);
1041 if (list_text != NULL) {
1046 out->list_item(out,
"Slaves (target-role)",
"[ %s ]", list_text);
1048 out->list_item(out,
"Slaves",
"[ %s ]", list_text);
1051 out->list_item(out,
"Started",
"[ %s ]", list_text);
1054 g_list_free(started_list);
1060 const char *state =
"Stopped";
1064 state =
"Stopped (disabled)";
1068 && (clone_data->clone_max > active_instances)) {
1075 stopped_list = NULL;
1076 stopped_list_len = 0;
1082 list = g_hash_table_get_values(rsc->
known_on);
1086 for (nIter = list; nIter != NULL; nIter = nIter->next) {
1091 pcmk__add_word(&stopped_list, &stopped_list_len,
1098 if (stopped_list != NULL) {
1099 out->list_item(out, state,
"[ %s ]", stopped_list);
1112 clone_variant_data_t *clone_data = NULL;
1114 get_clone_variant_data(clone_data, rsc);
1124 child_rsc->
xml = NULL;
1128 child_rsc->
fns->
free(child_rsc);
1134 CRM_ASSERT(clone_data->demote_notify == NULL);
1136 CRM_ASSERT(clone_data->start_notify == NULL);
1137 CRM_ASSERT(clone_data->promote_notify == NULL);
1149 for (; gIter != NULL; gIter = gIter->next) {
1153 if (a_role > clone_role) {
1154 clone_role = a_role;
1173 if (pe_rsc_is_clone(rsc)) {
1174 clone_variant_data_t *clone_data = NULL;
1176 get_clone_variant_data(clone_data, rsc);
1177 if (clone_data->clone_max == g_list_length(data_set->
nodes)) {
1187 gboolean passes = FALSE;
1188 clone_variant_data_t *clone_data = NULL;
1193 get_clone_variant_data(clone_data, rsc);
#define CRM_CHECK(expr, failure_action)
pe_resource_t * find_clone_instance(pe_resource_t *rsc, const char *sub_id, pe_working_set_t *data_set)
void clone_print(pe_resource_t *rsc, const char *pre_text, long options, void *print_data)
bool is_set_recursive(pe_resource_t *rsc, long long flag, bool any)
gboolean clone_unpack(pe_resource_t *rsc, pe_working_set_t *data_set)
#define pcmk__config_err(fmt...)
gboolean pe__clone_is_filtered(pe_resource_t *rsc, GListPtr only_rsc, gboolean check_parent)
gboolean pcmk__str_in_list(GList *lst, const gchar *s)
#define XML_RSC_ATTR_INCARNATION
bool pe__is_universal_clone(pe_resource_t *rsc, pe_working_set_t *data_set)
void pe__force_anon(const char *standard, pe_resource_t *rsc, const char *rid, pe_working_set_t *data_set)
resource_object_functions_t * fns
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
gboolean(* is_filtered)(pe_resource_t *, GListPtr, gboolean)
pe_node_t * pe_find_node(GListPtr node_list, const char *uname)
#define XML_RSC_ATTR_STICKINESS
enum rsc_role_e clone_resource_state(const pe_resource_t *rsc, gboolean current)
#define XML_RSC_ATTR_MASTER_NODEMAX
#define XML_RSC_ATTR_INCARNATION_MAX
int pe__clone_xml(pcmk__output_t *out, va_list args)
int pe__clone_text(pcmk__output_t *out, va_list args)
xmlNode * copy_xml(xmlNode *src_node)
void pe__set_resource_flags_recursive(pe_resource_t *rsc, uint64_t flags)
const char * role2text(enum rsc_role_e role)
pe_node_t *(* location)(const pe_resource_t *, GList **, int)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define XML_CIB_TAG_RESOURCE
#define PCMK__OUTPUT_ARGS(ARGS...)
int pe__name_and_nvpairs_xml(pcmk__output_t *out, bool is_list, const char *tag_name, size_t pairs_count,...)
int pe__clone_html(pcmk__output_t *out, va_list args)
void clone_free(pe_resource_t *rsc)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
void common_free(pe_resource_t *rsc)
#define pe_rsc_promotable
#define XML_RSC_ATTR_ORDERED
void(* print)(pe_resource_t *, const char *, long, void *)
#define XML_RSC_ATTR_INCARNATION_NODEMAX
pe_resource_t * pe__create_clone_child(pe_resource_t *rsc, pe_working_set_t *data_set)
#define XML_RSC_ATTR_TARGET_ROLE
void(* free)(pe_resource_t *)
void free_xml(xmlNode *child)
enum rsc_role_e text2role(const char *role)
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
void pcmk__output_xml_pop_parent(pcmk__output_t *out)
pe_resource_t * pe_find_resource(GListPtr rsc_list, const char *id_rh)
#define XML_RSC_ATTR_UNIQUE
enum rsc_role_e(* state)(const pe_resource_t *, gboolean)
#define XML_RSC_ATTR_MASTER_MAX
#define XML_RSC_ATTR_PROMOTED_MAX
Cluster status and scheduling.
void add_hash_param(GHashTable *hash, const char *name, const char *value)
const char * rsc_printable_id(pe_resource_t *rsc)
bool pcmk__rsc_filtered_by_node(pe_resource_t *rsc, GListPtr only_node)
#define status_print(fmt, args...)
This structure contains everything that makes up a single output formatter.
#define XML_RSC_ATTR_PROMOTED_NODEMAX
#define pe_rsc_failure_ignored
gboolean common_unpack(xmlNode *xml_obj, pe_resource_t **rsc, pe_resource_t *parent, pe_working_set_t *data_set)
gboolean clone_active(pe_resource_t *rsc, gboolean all)
gboolean crm_is_true(const char *s)
#define XML_CIB_TAG_GROUP
#define pe_rsc_trace(rsc, fmt, args...)
bool pe__resource_is_disabled(pe_resource_t *rsc)
gint sort_node_uname(gconstpointer a, gconstpointer b)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
enum crm_ais_msg_types type
gboolean(* active)(pe_resource_t *, gboolean)
GHashTable * allowed_nodes