native.c

来自「linux集群服务器软件代码包」· C语言 代码 · 共 1,104 行 · 第 1/2 页

C
1,104
字号
/* $Id: native.c,v 1.15 2005/02/19 18:11:04 andrew Exp $ *//*  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net> *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. *  * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <pengine.h>#include <pe_utils.h>#include <crm/msg_xml.h>extern color_t *add_color(resource_t *rh_resource, color_t *color);gboolean native_choose_color(resource_t *lh_resource);void native_assign_color(resource_t *rsc, color_t *color);void native_update_node_weight(resource_t *rsc, rsc_to_node_t *cons,			       const char *id, GListPtr nodes);void native_rsc_dependancy_rh_must(resource_t *rsc_lh, gboolean update_lh,				   resource_t *rsc_rh, gboolean update_rh);void native_rsc_dependancy_rh_mustnot(resource_t *rsc_lh, gboolean update_lh,				      resource_t *rsc_rh, gboolean update_rh);void filter_nodes(resource_t *rsc);int num_allowed_nodes4color(color_t *color);typedef struct native_variant_data_s{		lrm_agent_t *agent;		GListPtr running_on;       /* node_t*           */		color_t *color;		GListPtr node_cons;        /* rsc_to_node_t*    */		GListPtr allowed_nodes;    /* node_t*         */} native_variant_data_t;#define get_native_variant_data(data, rsc)				\	CRM_ASSERT(rsc->variant == pe_native);				\	CRM_ASSERT(rsc->variant_opaque != NULL);			\	data = (native_variant_data_t *)rsc->variant_opaque;voidnative_add_running(resource_t *rsc, node_t *node){	native_variant_data_t *native_data = NULL;	get_native_variant_data(native_data, rsc);		native_data->running_on = g_list_append(native_data->running_on, node);	if(g_list_length(native_data->running_on) > 1) {		crm_warn("Resource %s is (potentially) active on %d nodes."			 "  Latest: %s", rsc->id,			 g_list_length(native_data->running_on),			 node->details->id);	}}void native_unpack(resource_t *rsc){	crm_data_t * xml_obj = rsc->xml;	native_variant_data_t *native_data = NULL;	const char *version  = crm_element_value(xml_obj, XML_ATTR_VERSION);		crm_verbose("Processing resource %s...", rsc->id);	crm_malloc(native_data, sizeof(native_variant_data_t));	crm_malloc(native_data->agent, sizeof(lrm_agent_t));	native_data->agent->class	= crm_element_value(xml_obj, "class");	native_data->agent->type	= crm_element_value(xml_obj, "type");	native_data->agent->version	= version?version:"0.0";		native_data->color		= NULL; 	native_data->allowed_nodes	= NULL;	native_data->node_cons		= NULL; 	native_data->running_on		= NULL;	rsc->variant_opaque = native_data;}resource_t *native_find_child(resource_t *rsc, const char *id){	return NULL;}int native_num_allowed_nodes(resource_t *rsc){	int num_nodes = 0;	native_variant_data_t *native_data = NULL;	if(rsc->variant == pe_native) {		native_data = (native_variant_data_t *)rsc->variant_opaque;	} else {		crm_err("Resource %s was not a \"native\" variant",			rsc->id);		return 0;	}	if(native_data->color) {		return num_allowed_nodes4color(native_data->color);			} else if(rsc->candidate_colors) {		/* TODO: sort colors first */		color_t *color = g_list_nth_data(rsc->candidate_colors, 0);		return num_allowed_nodes4color(color);	} else {		slist_iter(			this_node, node_t, native_data->allowed_nodes, lpc,			if(this_node->weight < 0) {				continue;			}			num_nodes++;			);	}		return num_nodes;}int num_allowed_nodes4color(color_t *color) {	int num_nodes = 0;	if(color->details->pending == FALSE) {		if(color->details->chosen_node) {			return 1;		}		return 0;	}		slist_iter(		this_node, node_t, color->details->candidate_nodes, lpc,		if(this_node->weight < 0) {			continue;		}		num_nodes++;		);	return num_nodes;}void native_color(resource_t *rsc, GListPtr *colors){	color_t *new_color = NULL;	native_variant_data_t *native_data = NULL;	get_native_variant_data(native_data, rsc);		if( native_choose_color(rsc) ) {		crm_verbose("Colored resource %s with color %d",			    rsc->id, native_data->color->id);			} else {		if(native_data->allowed_nodes != NULL) {			/* filter out nodes with a negative weight */			filter_nodes(rsc);			new_color = create_color(				colors, rsc, native_data->allowed_nodes);			native_assign_color(rsc, new_color);		}				if(new_color == NULL) {			crm_err("Could not color resource %s", rsc->id);			print_resource("ERROR: No color", rsc, FALSE);			native_assign_color(rsc, no_color);		}	}	rsc->provisional = FALSE;	}void native_create_actions(resource_t *rsc){	action_t *start_op = NULL;	gboolean can_start = FALSE;	node_t *chosen = NULL;	native_variant_data_t *native_data = NULL;	get_native_variant_data(native_data, rsc);	if(native_data->color != NULL) {		chosen = native_data->color->details->chosen_node;	}		if(chosen != NULL) {		can_start = TRUE;	}		if(can_start && g_list_length(native_data->running_on) == 0) {		/* create start action */		crm_info("Start resource %s (%s)",			 rsc->id,			 safe_val3(NULL, chosen, details, uname));		start_op = action_new(rsc, start_rsc, chosen);			} else if(g_list_length(native_data->running_on) > 1) {		crm_info("Attempting recovery of resource %s",			 rsc->id);				if(rsc->recovery_type == recovery_stop_start		   || rsc->recovery_type == recovery_stop_only) {			slist_iter(				node, node_t,				native_data->running_on, lpc,								crm_info("Stop  resource %s (%s)",					 rsc->id,					 safe_val3(NULL, node, details, uname));				action_new(rsc, stop_rsc, node);				);		}				if(rsc->recovery_type == recovery_stop_start && can_start) {			crm_info("Start resource %s (%s)",				 rsc->id,				 safe_val3(NULL, chosen, details, uname));			start_op = action_new(				rsc, start_rsc, chosen);		}			} else {		crm_debug("Stop and possible restart of %s", rsc->id);				slist_iter(			node, node_t, native_data->running_on, lpc,										if(chosen != NULL && safe_str_eq(				   node->details->id,				   chosen->details->id)) {				/* restart */				crm_info("Leave resource %s alone (%s)", rsc->id,					 safe_val3(NULL, chosen, details, uname));								/* in case the actions already exist */				slist_iter(					action, action_t, rsc->actions, lpc2,										if(action->task == start_rsc					   || action->task == stop_rsc){						action->optional = TRUE;					}					);								continue;			} else if(chosen != NULL) {				/* move */				crm_info("Move  resource %s (%s -> %s)", rsc->id,					 safe_val3(NULL, node, details, uname),					 safe_val3(NULL, chosen, details, uname));				action_new(rsc, stop_rsc, node);				action_new(rsc, start_rsc, chosen);			} else {				crm_info("Stop  resource %s (%s)", rsc->id,					 safe_val3(NULL, node, details, uname));				action_new(rsc, stop_rsc, node);			}						);		}	slist_iter(		action, action_t, rsc->actions, lpc,		if(action->extra_attrs == NULL) {			action->extra_attrs = create_xml_node(NULL, "extra");		}		crm_xml_devel(rsc->extra_attrs, "copying in extra attributes");		copy_in_properties(action->extra_attrs, rsc->extra_attrs);		);}void native_internal_constraints(resource_t *rsc, GListPtr *ordering_constraints){	order_new(rsc, stop_rsc, NULL, rsc, start_rsc, NULL,		  pecs_startstop, ordering_constraints);}void native_rsc_dependancy_lh(rsc_dependancy_t *constraint){	resource_t *rsc = constraint->rsc_lh;		if(rsc == NULL) {		crm_err("rsc_lh was NULL for %s", constraint->id);		return;	} else if(constraint->rsc_rh == NULL) {		crm_err("rsc_rh was NULL for %s", constraint->id);		return;			} else {		crm_devel("Processing constraints from %s", rsc->id);	}		constraint->rsc_rh->fns->rsc_dependancy_rh(rsc, constraint);		}void native_rsc_dependancy_rh(resource_t *rsc, rsc_dependancy_t *constraint){	gboolean do_check = FALSE;	gboolean update_lh = FALSE;	gboolean update_rh = FALSE;		resource_t *rsc_lh = rsc;	resource_t *rsc_rh = constraint->rsc_rh;	native_variant_data_t *native_data_lh = NULL;	native_variant_data_t *native_data_rh = NULL;	get_native_variant_data(native_data_lh, rsc_lh);	get_native_variant_data(native_data_rh, rsc_rh);		crm_verbose("Processing RH of constraint %s", constraint->id);	crm_devel_action(print_resource("LHS", rsc_lh, TRUE));	crm_devel_action(print_resource("RHS", rsc_rh, TRUE));		if(constraint->strength == pecs_ignore		|| constraint->strength == pecs_startstop){		crm_devel("Skipping constraint type %d", constraint->strength);		return;	}		if(rsc_lh->provisional && rsc_rh->provisional) {		if(constraint->strength == pecs_must) {			/* update effective_priorities */			native_rsc_dependancy_rh_must(				rsc_lh, update_lh,rsc_rh, update_rh);		} else {			/* nothing */			crm_devel(				"Skipping constraint, both sides provisional");		}		return;	} else if( (!rsc_lh->provisional) && (!rsc_rh->provisional)		   && (!native_data_lh->color->details->pending)		   && (!native_data_rh->color->details->pending) ) {		/* error check */		do_check = TRUE;		if(rsc_lh->effective_priority < rsc_rh->effective_priority) {			update_lh = TRUE;					} else if(rsc_lh->effective_priority			  > rsc_rh->effective_priority) {			update_rh = TRUE;		} else {			update_lh = TRUE;			update_rh = TRUE;		}	} else if(rsc_lh->provisional == FALSE		  && native_data_lh->color->details->pending == FALSE) {		/* update _us_    : postproc color version */		update_rh = TRUE;	} else if(rsc_rh->provisional == FALSE		  && native_data_rh->color->details->pending == FALSE) {		/* update _them_  : postproc color alt version */		update_lh = TRUE;	} else if(rsc_lh->provisional == FALSE) {		/* update _us_    : preproc version */		update_rh = TRUE;	} else if(rsc_rh->provisional == FALSE) {		/* update _them_  : postproc version */		update_lh = TRUE;	} else {		crm_warn("Un-expected combination of inputs");		return;	}		if(update_lh) {		crm_devel("Updating LHS");	}	if(update_rh) {		crm_devel("Updating RHS");	}			if(do_check) {		if(native_constraint_violated(			   rsc_lh, rsc_rh, constraint) == FALSE) {			crm_devel("Constraint satisfied");			return;		}		/* else constraint cant be satisified */		crm_warn("Constraint %s could not be satisfied",			 constraint->id);				if(update_lh) {			crm_warn("Marking resource %s unrunnable as a result",				 rsc_lh->id);			rsc_lh->runnable = FALSE;		}		if(update_rh) {			crm_warn("Marking resource %s unrunnable as a result",				 rsc_rh->id);			rsc_rh->runnable = FALSE;		}			}	if(constraint->strength == pecs_must) {		native_rsc_dependancy_rh_must(			rsc_lh, update_lh,rsc_rh, update_rh);		return;			} else if(constraint->strength != pecs_must_not) {		/* unknown type */		crm_err("Unknown constraint type %d", constraint->strength);		return;	}	native_rsc_dependancy_rh_mustnot(rsc_lh, update_lh,rsc_rh, update_rh);}void native_rsc_order_lh(resource_t *lh_rsc, order_constraint_t *order){	GListPtr lh_actions = NULL;	action_t *lh_action = order->lh_action;	crm_verbose("Processing LH of ordering constraint %d", order->id);	switch(order->lh_action_task) {		case start_rsc:		case started_rsc:		case stop_rsc:		case stopped_rsc:			break;		default:			crm_err("Task \"%s\" from ordering %d isnt a resource action",				task2text(order->lh_action_task), order->id);			return;	}	if(lh_action != NULL) {		lh_actions = g_list_append(NULL, lh_action);	} else if(lh_action == NULL && lh_rsc != NULL) {		if(order->strength == pecs_must) {			crm_devel("No LH-Side (%s/%s) found for constraint..."				  " creating",				  lh_rsc->id, task2text(order->lh_action_task));			action_new(lh_rsc, order->lh_action_task, NULL);		}					lh_actions = find_actions(			lh_rsc->actions, order->lh_action_task, NULL);		if(lh_actions == NULL) {			crm_devel("No LH-Side (%s/%s) found for constraint",				  lh_rsc->id, task2text(order->lh_action_task));			crm_devel("RH-Side was: (%s/%s)",				  order->rh_rsc?order->rh_rsc->id:order->rh_action?order->rh_action->rsc->id:"<NULL>",				  task2text(order->rh_action_task));			return;		}	} else {		crm_warn("No LH-Side (%s) specified for constraint",			 task2text(order->lh_action_task));		crm_devel("RH-Side was: (%s/%s)",			  order->rh_rsc?order->rh_rsc->id:order->rh_action?order->rh_action->rsc->id:"<NULL>",			  task2text(order->rh_action_task));		return;	}	slist_iter(		lh_action_iter, action_t, lh_actions, lpc,		resource_t *rh_rsc = order->rh_rsc;		if(rh_rsc == NULL && order->rh_action) {			rh_rsc = order->rh_action->rsc;		}				if(rh_rsc) {			rh_rsc->fns->rsc_order_rh(				lh_action_iter, rh_rsc, order);		} else if(order->rh_action) {			order_actions(lh_action_iter, order->rh_action, order); 		}		);	pe_free_shallow_adv(lh_actions, FALSE);}void native_rsc_order_rh(	action_t *lh_action, resource_t *rsc, order_constraint_t *order){	GListPtr rh_actions = NULL;	action_t *rh_action = order->rh_action;	crm_verbose("Processing RH of ordering constraint %d", order->id);	switch(order->rh_action_task) {		case start_rsc:		case started_rsc:		case stop_rsc:		case stopped_rsc:			break;		default:			crm_err("Task \"%s\" from ordering %d isnt a resource action",				task2text(order->rh_action_task), order->id);			return;	}		if(rh_action != NULL) {		rh_actions = g_list_append(NULL, rh_action);	} else if(rh_action == NULL && rsc != NULL) {		rh_actions = find_actions(			rsc->actions, order->rh_action_task, NULL);		if(rh_actions == NULL) {			crm_devel("No RH-Side (%s/%s) found for constraint..."				  " ignoring",				  rsc->id, task2text(order->rh_action_task));			crm_devel("LH-Side was: (%s/%s)",				  order->lh_rsc?order->lh_rsc->id:order->lh_action?order->lh_action->rsc->id:"<NULL>",				  task2text(order->lh_action_task));			return;		}				}  else if(rh_action == NULL) {		crm_devel("No RH-Side (%s) specified for constraint..."			  " ignoring", task2text(order->rh_action_task));

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?