diff -Nur -x '*.swp' pacemaker.orig/pengine/constraints.c pacemaker.mark/pengine/constraints.c --- pacemaker.orig/pengine/constraints.c 2009-04-08 02:49:50.000000000 -0500 +++ pacemaker.mark/pengine/constraints.c 2009-04-23 15:42:40.000000000 -0500 @@ -253,6 +253,58 @@ return TRUE; } +void calculate_system_health (gpointer gKey, gpointer gValue, gpointer user_data); + +void +calculate_system_health (gpointer gKey, gpointer gValue, gpointer user_data) +{ + const char *key = (const char *)gKey; + const char *value = (const char *)gValue; + int *system_health = (int *)user_data; + char *health_value_end = NULL; + long int health_value = 0; + int health_valid_valid = 0; + + if (!key || !value || !system_health) { + return; + } + + errno = 0; + health_value = strtol (value, &health_value_end, 10); + if ( (errno == 0) + && (*health_value_end == '\0') + && (health_value >= INT_MIN && health_value <= INT_MAX) + ) { + health_valid_valid = 1; + } + + if (0 == strncmp (key, "#health", 7)) { + gboolean invalid = FALSE; + + if (safe_str_eq (value, "green")) { + /* Add 200 to the total health */ + *system_health = merge_weights(200, *system_health); + } else if (safe_str_eq (value, "yellow")) { + /* Add 0 to the total health */ + *system_health = merge_weights(0, *system_health); + } else if (safe_str_eq (value, "red")) { + /* Force -inf */ + *system_health = -INFINITY; + } else if (health_valid_valid) { + /* Add specified value to the total health */ + *system_health = merge_weights((int)health_value, *system_health); + } else { + /* Error! */ + crm_err ("Unknown health key (%s), value (%s)", key, value); + invalid = TRUE; + } + + if (!invalid) { + crm_debug_2 ("health key (%s), value (%s)", key, value); + } + } +} + gboolean unpack_rsc_location(xmlNode * xml_obj, pe_working_set_t *data_set) { @@ -458,6 +510,38 @@ } ); ); + + /* Add the system health value to all nodes in the match list. + * If a node is not in the match list and it has a non-zero health, + * then add it to the match list. + */ + slist_iter( + node, node_t, data_set->nodes, lpc, + + int system_health = 0; + + /* Search through the node hash table for system health entries. */ + g_hash_table_foreach ( + node->details->attrs, + calculate_system_health, + (gpointer)&system_health); + + crm_debug_2("node %s has a total system health value of %d", + node->details->uname, + system_health); + + if(system_health != 0) { + node_t *local = pe_find_node_id( + match_L, node->details->id); + + if(!local) { + local = node_copy(node); + match_L = g_list_append(match_L, local); + } + + local->weight = merge_weights(local->weight, system_health); + } + ); location_rule->node_list_rh = match_L; if(location_rule->node_list_rh == NULL) {