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