27 #define VARIANT_CLONE 1 42 for (; gIter != NULL; gIter = gIter->next) {
45 mark_as_orphan(child);
53 clone_variant_data_t *clone_data = NULL;
55 get_clone_variant_data(clone_data, rsc);
58 "can only be used as an anonymous clone. " 61 clone_data->clone_node_max = 1;
62 clone_data->clone_max = g_list_length(data_set->
nodes);
70 char *child_id = NULL;
72 const char *child_base = NULL;
73 clone_variant_data_t *clone_data = NULL;
75 get_clone_variant_data(clone_data, rsc);
77 child_base =
ID(clone_data->xml_obj_child);
78 child_id =
crm_concat(child_base, sub_id,
':');
88 gboolean as_orphan = FALSE;
92 xmlNode *child_copy = NULL;
93 clone_variant_data_t *clone_data = NULL;
95 get_clone_variant_data(clone_data, rsc);
97 CRM_CHECK(clone_data->xml_obj_child != NULL,
return FALSE);
101 sub_id = clone_data->total_clones;
104 inc_max =
crm_itoa(clone_data->clone_max);
106 child_copy =
copy_xml(clone_data->xml_obj_child);
110 if (
common_unpack(child_copy, &child_rsc, rsc, data_set) == FALSE) {
118 clone_data->total_clones += 1;
119 pe_rsc_trace(child_rsc,
"Setting clone attributes for: %s", child_rsc->
id);
122 mark_as_orphan(child_rsc);
144 clone_variant_data_t *clone_data = NULL;
146 get_clone_variant_data(clone_data, rsc);
148 clone_data->master_node_max =
crm_parse_int(master_node_max,
"1");
158 const char *
type = NULL;
159 int num_xml_children = 0;
160 xmlNode *a_child = NULL;
161 xmlNode *xml_obj = rsc->
xml;
162 clone_variant_data_t *clone_data = NULL;
171 clone_data = calloc(1,
sizeof(clone_variant_data_t));
173 clone_data->interleave = FALSE;
174 clone_data->ordered = FALSE;
176 clone_data->active_clones = 0;
177 clone_data->xml_obj_child = NULL;
178 clone_data->clone_node_max =
crm_parse_int(max_clones_node,
"1");
183 }
else if (g_list_length(data_set->
nodes) > 0) {
184 clone_data->clone_max = g_list_length(data_set->
nodes);
187 clone_data->clone_max = 1;
191 clone_data->interleave = TRUE;
194 clone_data->ordered = TRUE;
197 crm_config_err(
"Anonymous clones (%s) may only support one copy per node", rsc->
id);
198 clone_data->clone_node_max = 1;
202 pe_rsc_trace(rsc,
"\tClone max: %d", clone_data->clone_max);
203 pe_rsc_trace(rsc,
"\tClone node max: %d", clone_data->clone_node_max);
209 if (clone_data->xml_obj_child == NULL) {
211 for (a_child = __xml_first_child(xml_obj); a_child != NULL; a_child = __xml_next_element(a_child)) {
218 if (clone_data->xml_obj_child == NULL) {
223 for (a_child = __xml_first_child(xml_obj); a_child != NULL; a_child = __xml_next_element(a_child)) {
224 if (
crm_str_eq((
const char *)a_child->name, type, TRUE)) {
229 if (num_xml_children > 1) {
230 crm_config_err(
"%s has too many children. Only the first (%s) will be cloned.",
231 rsc->
id,
ID(clone_data->xml_obj_child));
250 for (lpc = 0; lpc < clone_data->clone_max; lpc++) {
256 if (clone_data->clone_max == 0) {
265 pe_rsc_trace(rsc,
"Added %d children to resource %s...", clone_data->clone_max, rsc->
id);
274 for (; gIter != NULL; gIter = gIter->next) {
276 gboolean child_active = child_rsc->
fns->
active(child_rsc, all);
278 if (all == FALSE && child_active) {
280 }
else if (all && child_active == FALSE) {
293 short_print(
char *list,
const char *prefix,
const char *
type,
long options,
void *print_data)
301 if (options & pe_print_html) {
314 clone_print_xml(
resource_t * rsc,
const char *pre_text,
long options,
void *print_data)
317 char *child_text =
crm_concat(pre_text,
" ",
' ');
322 status_print(
"multi_state=\"%s\" ", is_master_slave ?
"true" :
"false");
330 for (; gIter != NULL; gIter = gIter->next) {
333 child_rsc->
fns->
print(child_rsc, child_text, options, print_data);
345 if(is_set(rsc->
flags, flag)) {
353 for (gIter = rsc->
children; gIter != NULL; gIter = gIter->next) {
373 char *list_text = NULL;
374 char *child_text = NULL;
375 char *stopped_list = NULL;
376 const char *type =
"Clone";
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 type =
"Master/Slave";
403 pre_text ? pre_text :
"", type, rsc->
id,
ID(clone_data->xml_obj_child),
414 for (; gIter != NULL; gIter = gIter->next) {
415 gboolean print_full = FALSE;
422 if (child_rsc->
fns->
active(child_rsc, FALSE) == FALSE) {
446 }
else if (child_rsc->
fns->
active(child_rsc, TRUE)) {
458 master_list = g_list_append(master_list, location);
462 started_list = g_list_append(started_list, location);
476 if (options & pe_print_html) {
479 child_rsc->
fns->
print(child_rsc, child_text, options, print_data);
480 if (options & pe_print_html) {
488 for (gIter = master_list; gIter; gIter = gIter->next) {
495 short_print(list_text, child_text,
"Masters", options, print_data);
496 g_list_free(master_list);
502 for (gIter = started_list; gIter; gIter = gIter->next) {
509 short_print(list_text, child_text, rsc->
variant ==
pe_master ?
"Slaves" :
"Started", options,
511 g_list_free(started_list);
518 && (clone_data->clone_max > active_instances)) {
524 free(stopped_list); stopped_list = NULL;
526 if (g_list_length(list) == 0) {
530 list = g_hash_table_get_values(rsc->
known_on);
534 for (nIter = list; nIter != NULL; nIter = nIter->next) {
543 short_print(stopped_list, child_text,
"Stopped", options, print_data);
547 if (options & pe_print_html) {
558 clone_variant_data_t *clone_data = NULL;
560 get_clone_variant_data(clone_data, rsc);
564 for (; gIter != NULL; gIter = gIter->next) {
570 child_rsc->
xml = NULL;
574 child_rsc->
fns->
free(child_rsc);
580 CRM_ASSERT(clone_data->demote_notify == NULL);
583 CRM_ASSERT(clone_data->promote_notify == NULL);
595 for (; gIter != NULL; gIter = gIter->next) {
599 if (a_role > clone_role) {
#define CRM_CHECK(expr, failure_action)
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
gboolean clone_unpack(resource_t *rsc, pe_working_set_t *data_set)
void(* free)(resource_t *)
#define XML_BOOLEAN_FALSE
#define crm_config_err(fmt...)
#define XML_RSC_ATTR_INCARNATION
gboolean common_unpack(xmlNode *xml_obj, resource_t **rsc, resource_t *parent, pe_working_set_t *data_set)
enum pe_obj_types variant
void common_free(resource_t *rsc)
#define status_print(fmt, args...)
int crm_parse_int(const char *text, const char *default_text)
enum rsc_role_e(* state)(const resource_t *, gboolean)
node_t * pe_find_node(GListPtr node_list, const char *uname)
char * add_list_element(char *list, const char *value)
#define XML_RSC_ATTR_STICKINESS
void force_non_unique_clone(resource_t *rsc, const char *rid, pe_working_set_t *data_set)
gboolean master_unpack(resource_t *rsc, pe_working_set_t *data_set)
gboolean clone_active(resource_t *rsc, gboolean all)
#define XML_RSC_ATTR_MASTER_NODEMAX
#define XML_RSC_ATTR_INCARNATION_MAX
xmlNode * copy_xml(xmlNode *src_node)
const char * role2text(enum rsc_role_e role)
struct node_shared_s * details
#define set_bit(word, bit)
void clone_free(resource_t *rsc)
enum rsc_role_e clone_resource_state(const resource_t *rsc, gboolean current)
#define XML_CIB_TAG_RESOURCE
resource_object_functions_t * fns
GHashTable * allowed_nodes
void clone_create_notifications(resource_t *rsc, action_t *action, action_t *action_complete, pe_working_set_t *data_set)
#define XML_RSC_ATTR_ORDERED
const char * crm_element_value(xmlNode *data, const char *name)
#define XML_RSC_ATTR_INCARNATION_NODEMAX
node_t *(* location)(resource_t *, GListPtr *, gboolean)
void free_xml(xmlNode *child)
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
#define XML_RSC_ATTR_UNIQUE
void clone_print(resource_t *rsc, const char *pre_text, long options, void *print_data)
gboolean(* active)(resource_t *, gboolean)
#define crm_config_warn(fmt...)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
#define XML_RSC_ATTR_MASTER_MAX
void(* print)(resource_t *, const char *, long, void *)
resource_t * create_child_clone(resource_t *rsc, int sub_id, pe_working_set_t *data_set)
void add_hash_param(GHashTable *hash, const char *name, const char *value)
#define pe_rsc_failure_ignored
resource_t * find_clone_instance(resource_t *rsc, const char *sub_id, pe_working_set_t *data_set)
bool is_set_recursive(resource_t *rsc, long long flag, bool any)
void clear_bit_recursive(resource_t *rsc, unsigned long long flag)
gboolean crm_is_true(const char *s)
#define XML_CIB_TAG_GROUP
#define pe_rsc_trace(rsc, fmt, args...)
char * crm_concat(const char *prefix, const char *suffix, char join)
void print_resource(int log_level, const char *pre_text, resource_t *rsc, gboolean details)
char * crm_itoa(int an_int)
resource_t * pe_find_resource(GListPtr rsc_list, const char *id_rh)
#define XML_RSC_ATTR_INTERLEAVE
gint sort_node_uname(gconstpointer a, gconstpointer b)
enum crm_ais_msg_types type