📄 utils.c
字号:
/* $Id: utils.c,v 1.55 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 <portability.h>#include <crm/crm.h>#include <crm/cib.h>#include <crm/msg_xml.h>#include <crm/common/xml.h>#include <crm/common/util.h>#include <glib.h>#include <pengine.h>#include <pe_utils.h>int action_id = 1;void print_str_str(gpointer key, gpointer value, gpointer user_data);gboolean ghash_free_str_str(gpointer key, gpointer value, gpointer user_data);gboolean node_merge_weights(node_t *node, node_t *with);/* only for rsc_dependancy constraints */rsc_dependancy_t *invert_constraint(rsc_dependancy_t *constraint) { rsc_dependancy_t *inverted_con = NULL; crm_verbose("Inverting constraint"); if(constraint == NULL) { crm_err("Cannot invert NULL constraint"); return NULL; } crm_malloc(inverted_con, sizeof(rsc_dependancy_t)); if(inverted_con == NULL) { return NULL; } inverted_con->id = crm_strdup(constraint->id); inverted_con->strength = constraint->strength; /* swap the direction */ inverted_con->rsc_lh = constraint->rsc_rh; inverted_con->rsc_rh = constraint->rsc_lh; crm_devel_action( print_rsc_dependancy("Inverted constraint", inverted_con, FALSE)); return inverted_con;}/* are the contents of list1 and list2 equal * nodes with weight < 0 are ignored if filter == TRUE * * slow but linear * */gbooleannode_list_eq(GListPtr list1, GListPtr list2, gboolean filter){ node_t *other_node; GListPtr lhs = list1; GListPtr rhs = list2; slist_iter( node, node_t, lhs, lpc, if(node == NULL || (filter && node->weight < 0)) { continue; } other_node = (node_t*) pe_find_node(rhs, node->details->uname); if(other_node == NULL || other_node->weight < 0) { return FALSE; } ); lhs = list2; rhs = list1; slist_iter( node, node_t, lhs, lpc, if(node == NULL || (filter && node->weight < 0)) { continue; } other_node = (node_t*) pe_find_node(rhs, node->details->uname); if(other_node == NULL || other_node->weight < 0) { return FALSE; } ); return TRUE;}/* the intersection of list1 and list2 */GListPtrnode_list_and(GListPtr list1, GListPtr list2, gboolean filter){ GListPtr result = NULL; int lpc = 0; for(lpc = 0; lpc < g_list_length(list1); lpc++) { node_t *node = (node_t*)g_list_nth_data(list1, lpc); node_t *new_node = node_copy(node); node_t *other_node = pe_find_node(list2, node->details->uname); if(node_merge_weights(new_node, other_node) == FALSE) { crm_free(new_node); } else if(filter && new_node->weight < 0) { crm_free(new_node); } else { result = g_list_append(result, new_node); } } return result;}gbooleannode_merge_weights(node_t *node, node_t *with){ if(node == NULL || with == NULL) { return FALSE; } else if(node->weight < 0 || with->weight < 0) { node->weight = -1; } else if(node->weight < with->weight) { node->weight = with->weight; } return TRUE;}/* list1 - list2 */GListPtrnode_list_minus(GListPtr list1, GListPtr list2, gboolean filter){ GListPtr result = NULL; slist_iter( node, node_t, list1, lpc, node_t *other_node = pe_find_node(list2, node->details->uname); node_t *new_node = NULL; if(node == NULL || other_node != NULL || (filter && node->weight < 0)) { continue; } new_node = node_copy(node); result = g_list_append(result, new_node); ); crm_verbose("Minus result len: %d", g_list_length(result)); return result;}/* list1 + list2 - (intersection of list1 and list2) */GListPtrnode_list_xor(GListPtr list1, GListPtr list2, gboolean filter){ GListPtr result = NULL; slist_iter( node, node_t, list1, lpc, node_t *new_node = NULL; node_t *other_node = (node_t*) pe_find_node(list2, node->details->uname); if(node == NULL || other_node != NULL || (filter && node->weight < 0)) { continue; } new_node = node_copy(node); result = g_list_append(result, new_node); ); slist_iter( node, node_t, list2, lpc, node_t *new_node = NULL; node_t *other_node = (node_t*) pe_find_node(list1, node->details->uname); if(node == NULL || other_node != NULL || (filter && node->weight < 0)) { continue; } new_node = node_copy(node); result = g_list_append(result, new_node); ); crm_verbose("Xor result len: %d", g_list_length(result)); return result;}GListPtrnode_list_or(GListPtr list1, GListPtr list2, gboolean filter){ node_t *other_node = NULL; GListPtr result = NULL; result = node_list_dup(list1, filter); slist_iter( node, node_t, list2, lpc, if(node == NULL) { continue; } other_node = (node_t*)pe_find_node( result, node->details->uname); if(other_node != NULL) { node_merge_weights(other_node, node); if(filter && node->weight < 0) { /* TODO: remove and free other_node */ } } else if(filter && node->weight < 0) { } else { node_t *new_node = node_copy(node); result = g_list_append(result, new_node); } ); return result;}GListPtr node_list_dup(GListPtr list1, gboolean filter){ GListPtr result = NULL; slist_iter( this_node, node_t, list1, lpc, node_t *new_node = NULL; if(filter && this_node->weight < 0) { continue; } new_node = node_copy(this_node); if(new_node != NULL) { result = g_list_append(result, new_node); } ); return result;}node_t *node_copy(node_t *this_node) { node_t *new_node = NULL; CRM_DEV_ASSERT(this_node != NULL); if(this_node == NULL) { crm_err("Failed copy of <null> node."); return NULL; } crm_malloc(new_node, sizeof(node_t)); CRM_DEV_ASSERT(new_node != NULL); if(new_node == NULL) { return NULL; } crm_trace("Copying %p (%s) to %p", this_node, this_node->details->uname, new_node); new_node->weight = this_node->weight; new_node->fixed = this_node->fixed; new_node->details = this_node->details; return new_node;}static int color_id = 0;/* * Create a new color with the contents of "nodes" as the list of * possible nodes that resources with this color can be run on. * * Typically, when creating a color you will provide the node list from * the resource you will first assign the color to. * * If "colors" != NULL, it will be added to that list * If "resources" != NULL, it will be added to every provisional resource * in that list */color_t *create_color(GListPtr *colors, resource_t *resource, GListPtr node_list){ color_t *new_color = NULL; crm_trace("Creating color"); crm_malloc(new_color, sizeof(color_t)); if(new_color == NULL) { return NULL; } new_color->id = color_id++; new_color->local_weight = 1.0; crm_trace("Creating color details"); crm_malloc(new_color->details, sizeof(struct color_shared_s)); if(new_color->details == NULL) { crm_free(new_color); return NULL; } new_color->details->id = new_color->id; new_color->details->highest_priority = -1; new_color->details->chosen_node = NULL; new_color->details->candidate_nodes = NULL; new_color->details->allocated_resources = NULL; new_color->details->pending = TRUE; if(resource != NULL) { crm_trace("populating node list"); new_color->details->highest_priority = resource->priority; new_color->details->candidate_nodes = node_list_dup(node_list, TRUE); } crm_devel_action(print_color("Created color", new_color, TRUE)); if(colors != NULL) { *colors = g_list_append(*colors, new_color); } return new_color;}color_t *copy_color(color_t *a_color) { color_t *color_copy = NULL; if(a_color == NULL) { crm_err("Cannot copy NULL"); return NULL; } crm_malloc(color_copy, sizeof(color_t)); if(color_copy != NULL) { color_copy->id = a_color->id; color_copy->details = a_color->details; color_copy->local_weight = 1.0; } return color_copy;}resource_t *pe_find_resource(GListPtr rsc_list, const char *id){ int lpc = 0; resource_t *rsc = NULL; resource_t *child_rsc = NULL; crm_devel("Looking for %s in %d objects", id, g_list_length(rsc_list)); for(lpc = 0; lpc < g_list_length(rsc_list); lpc++) { rsc = g_list_nth_data(rsc_list, lpc); if(rsc != NULL && safe_str_eq(rsc->id, id)){ crm_devel("Found a match for %s", id); return rsc; } } for(lpc = 0; lpc < g_list_length(rsc_list); lpc++) { rsc = g_list_nth_data(rsc_list, lpc); child_rsc = rsc->fns->find_child(rsc, id); if(child_rsc != NULL) { crm_devel("Found a match for %s in %s", id, rsc->id); return child_rsc; } } /* error */ return NULL;}node_t *pe_find_node(GListPtr nodes, const char *uname){ int lpc = 0; node_t *node = NULL; for(lpc = 0; lpc < g_list_length(nodes); lpc++) { node = g_list_nth_data(nodes, lpc); if(node != NULL && safe_str_eq(node->details->uname, uname)) { return node; } } /* error */ return NULL;}node_t *pe_find_node_id(GListPtr nodes, const char *id){ int lpc = 0; node_t *node = NULL; for(lpc = 0; lpc < g_list_length(nodes); lpc++) { node = g_list_nth_data(nodes, lpc); if(safe_str_eq(node->details->id, id)) { return node; } } /* error */ return NULL;}gint gslist_color_compare(gconstpointer a, gconstpointer b);color_t *find_color(GListPtr candidate_colors, color_t *other_color){ GListPtr tmp = g_list_find_custom(candidate_colors, other_color, gslist_color_compare); if(tmp != NULL) { return (color_t *)tmp->data; } return NULL;}gint gslist_color_compare(gconstpointer a, gconstpointer b){ const color_t *color_a = (const color_t*)a; const color_t *color_b = (const color_t*)b;/* crm_trace("%d vs. %d", a?color_a->id:-2, b?color_b->id:-2); */ if(a == b) { return 0; } else if(a == NULL || b == NULL) { return 1; } else if(color_a->id == color_b->id) { return 0; } return 1;}gint sort_rsc_priority(gconstpointer a, gconstpointer b){ const resource_t *resource1 = (const resource_t*)a; const resource_t *resource2 = (const resource_t*)b; if(a == NULL) { return 1; } if(b == NULL) { return -1; } if(resource1->priority > resource2->priority) { return -1; } if(resource1->priority < resource2->priority) { return 1; } return 0;}gint sort_cons_strength(gconstpointer a, gconstpointer b){ const rsc_dependancy_t *rsc_constraint1 = (const rsc_dependancy_t*)a; const rsc_dependancy_t *rsc_constraint2 = (const rsc_dependancy_t*)b; if(a == NULL) { return 1; } if(b == NULL) { return -1; } if(rsc_constraint1->strength > rsc_constraint2->strength) { return 1; } if(rsc_constraint1->strength < rsc_constraint2->strength) { return -1; } return 0;}gint sort_color_weight(gconstpointer a, gconstpointer b){ const color_t *color1 = (const color_t*)a; const color_t *color2 = (const color_t*)b; if(a == NULL) { return 1; } if(b == NULL) { return -1; } if(color1->local_weight > color2->local_weight) { return -1; } if(color1->local_weight < color2->local_weight) { return 1; } return 0;}gint sort_node_weight(gconstpointer a, gconstpointer b){ const node_t *node1 = (const node_t*)a; const node_t *node2 = (const node_t*)b; if(a == NULL) { return 1; } if(b == NULL) { return -1; } if(node1->weight > node2->weight) { return -1; } if(node1->weight < node2->weight) { return 1; } return 0;}action_t *action_new(resource_t *rsc, enum action_tasks task, node_t *on_node){ action_t *action = NULL; GListPtr possible_matches = NULL; if(rsc != NULL) { possible_matches = find_actions(rsc->actions, task, on_node); } if(on_node != NULL && on_node->details->unclean) { crm_warn("Not creating action %s for %s because %s is unclean", task2text(task), rsc?rsc->id:"<NULL>", on_node->details->id); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -