int master_max = crm_atoi(master_max_s, "1"); int master_node_max = crm_atoi(master_node_max_s, "1");
int master_max = crm_parse_int(master_max_s, "1"); int master_node_max = crm_parse_int(master_node_max_s, "1");
void master_create_actions(resource_t *rsc, pe_working_set_t *data_set){	int len = 0;	node_t *chosen = NULL;	char *attr_name = NULL;	const char *attr_value = NULL;	node_t *cons_node = NULL;		action_t *action = NULL;	action_t *action_complete = NULL;	gboolean any_promoting = FALSE;	gboolean any_demoting = FALSE;	resource_t *last_promote_rsc = NULL;	resource_t *last_demote_rsc = NULL;	const char *master_max_s =		get_rsc_param(rsc, XML_RSC_ATTR_MASTER_MAX);	const char *master_node_max_s =		get_rsc_param(rsc, XML_RSC_ATTR_MASTER_NODEMAX);	int promoted = 0;	int max_nodes = 0;	int master_max = crm_atoi(master_max_s, "1");	int master_node_max = crm_atoi(master_node_max_s, "1");	struct masters_s *master_hash_obj = NULL;	GHashTable *master_hash = g_hash_table_new_full(		g_str_hash, g_str_equal,		g_hash_destroy_str, g_hash_destroy_str);		clone_variant_data_t *clone_data = NULL;	get_clone_variant_data(clone_data, rsc);	/* how many can we have? */	if(master_max >  clone_data->max_nodes * clone_data->clone_node_max) {		master_max = clone_data->max_nodes * clone_data->clone_node_max;		crm_info("Limited to %d masters (potential slaves)",master_max);	}	if(master_max >  max_nodes * master_node_max) {		master_max = clone_data->max_nodes * master_node_max;		crm_info("Limited to %d masters (available nodes)", master_max);	}		/*	 * assign priority	 */	slist_iter(		child_rsc, resource_t, clone_data->child_list, lpc,		crm_debug_2("Assigning priority for %s", child_rsc->id);		CRM_DEV_ASSERT(child_rsc->color != NULL);		chosen = child_rsc->color->details->chosen_node;				switch(child_rsc->next_role) {			case RSC_ROLE_STARTED:				if(NO_MASTER_PREFS) {					child_rsc->priority =						clone_data->clone_max - lpc;					break;				}								child_rsc->priority = -1;				CRM_DEV_ASSERT(chosen != NULL);				len = 8 + strlen(child_rsc->id);				crm_malloc0(attr_name, len);				sprintf(attr_name, "master-%s", child_rsc->id);								attr_value = g_hash_table_lookup(					chosen->details->attrs, attr_name);				crm_info("%s=%s for %s", attr_name,					 crm_str(attr_value),					 chosen->details->uname);								if(attr_value != NULL) {					child_rsc->priority = char2score(						attr_value);				}				crm_free(attr_name);				apply_master_location(child_rsc->rsc_location);				apply_master_location(rsc->rsc_location);				break;			case RSC_ROLE_SLAVE:			case RSC_ROLE_STOPPED:				child_rsc->priority = -INFINITY;				break;			default:				CRM_DEV_ASSERT(FALSE/* unhandled */);		}		);		/* sort based on the new "promote" priority */	clone_data->child_list = g_list_sort(		clone_data->child_list, sort_rsc_priority);	/* mark the first N as masters */	slist_iter(		child_rsc, resource_t, clone_data->child_list, lpc,		CRM_DEV_ASSERT(child_rsc->color != NULL);		chosen = child_rsc->color->details->chosen_node;		switch(child_rsc->next_role) {			case RSC_ROLE_STARTED:				master_hash_obj = g_hash_table_lookup(					master_hash, chosen->details->id);				if(master_hash_obj == NULL) {					crm_malloc0(master_hash_obj,						    sizeof(struct masters_s));					master_hash_obj->node = chosen;					g_hash_table_insert(						master_hash,						crm_strdup(chosen->details->id),						master_hash_obj);				}				if(master_hash_obj->num_masters >= master_node_max) {					crm_info("Demoting %s (node master max)",						 child_rsc->id);					child_rsc->next_role = RSC_ROLE_SLAVE;				} else if(child_rsc->priority < 0) {					crm_info("Demoting %s (priority)",						 child_rsc->id);					child_rsc->next_role = RSC_ROLE_SLAVE;									} else if(master_max <= promoted) {					crm_info("Demoting %s (masters max)",						 child_rsc->id);					child_rsc->next_role = RSC_ROLE_SLAVE;				} else {					crm_info("Promoting %s", child_rsc->id);					child_rsc->next_role = RSC_ROLE_MASTER;					promoted++;					master_hash_obj->num_masters++;				}				break;							case RSC_ROLE_SLAVE:				if(child_rsc->priority < 0 ||master_max <= lpc){					pe_warn("Cannot promote %s (slave)",						child_rsc->id);					lpc--;				}				break;			case RSC_ROLE_STOPPED:				if(child_rsc->priority < 0 ||master_max <= lpc){					pe_warn("Cannot promote %s (stopping)",						child_rsc->id);					lpc--;				}				break;			default:				CRM_DEV_ASSERT(FALSE/* unhandled */);		}		);	crm_info("Promoted %d (of %d) slaves to master", promoted, master_max);	g_hash_table_destroy(master_hash);	/* create actions as normal */	clone_create_actions(rsc, data_set);	slist_iter(		child_rsc, resource_t, clone_data->child_list, lpc,		gboolean child_promoting = FALSE;		gboolean child_demoting = FALSE;		master_update_pseudo_status(			child_rsc, &child_demoting, &child_promoting);		any_demoting = any_demoting || child_demoting;		any_promoting = any_promoting || child_promoting;		);		/* promote */	action = promote_action(clone_data->self, NULL, !any_promoting);	action_complete = custom_action(		clone_data->self, promoted_key(rsc),		CRMD_ACTION_PROMOTED, NULL, !any_promoting, TRUE, data_set);	action->pseudo = TRUE;	action_complete->pseudo = TRUE;		child_promoting_constraints(clone_data, pe_ordering_optional, 				   NULL, last_promote_rsc, data_set);	clone_create_notifications(rsc, action, action_complete, data_set);		/* demote */	action = demote_action(clone_data->self, NULL, !any_demoting);	action_complete = custom_action(		clone_data->self, demoted_key(rsc),		CRMD_ACTION_DEMOTED, NULL, !any_demoting, TRUE, data_set);	action->pseudo = TRUE;	action_complete->pseudo = TRUE;		child_demoting_constraints(clone_data, pe_ordering_optional,				   NULL, last_demote_rsc, data_set);	clone_create_notifications(rsc, action, action_complete, data_set);	}