Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/lib/pacemaker/pcmk_sched_nodes.c b/lib/pacemaker/pcmk_sched_nodes.c
index ca0196212b..f1a91664b2 100644
--- a/lib/pacemaker/pcmk_sched_nodes.c
+++ b/lib/pacemaker/pcmk_sched_nodes.c
@@ -1,219 +1,238 @@
/*
* Copyright 2004-2021 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU General Public License version 2
* or later (GPLv2+) WITHOUT ANY WARRANTY.
*/
#include <crm_internal.h>
#include <crm/msg_xml.h>
#include <crm/lrmd.h> // lrmd_event_data_t
#include <crm/common/xml_internal.h>
#include <pacemaker-internal.h>
#include <pacemaker.h>
#include "libpacemaker_private.h"
/*!
* \internal
* \brief Check whether a node is available to run resources
*
* \param[in] node Node to check
*
* \return true if node is online and not shutting down, unclean, or in standby
* or maintenance mode, otherwise false
*/
bool
pcmk__node_available(const pe_node_t *node)
{
// @TODO Should we add (node->weight >= 0)?
return (node != NULL) && (node->details != NULL) && node->details->online
&& !node->details->shutdown && !node->details->unclean
&& !node->details->standby && !node->details->maintenance;
}
/*!
* \internal
* \brief Copy a hash table of node objects
*
* \param[in] nodes Hash table to copy
*
* \return New copy of nodes (or NULL if nodes is NULL)
*/
GHashTable *
pcmk__copy_node_table(GHashTable *nodes)
{
GHashTable *new_table = NULL;
GHashTableIter iter;
pe_node_t *node = NULL;
if (nodes == NULL) {
return NULL;
}
new_table = pcmk__strkey_table(NULL, free);
g_hash_table_iter_init(&iter, nodes);
while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) {
pe_node_t *new_node = pe__copy_node(node);
g_hash_table_insert(new_table, (gpointer) new_node->details->id,
new_node);
}
return new_table;
}
/*!
* \internal
* \brief Copy a list of node objects
*
* \param[in] list List to copy
* \param[in] reset Set copies' scores to 0
*
* \return New list of shallow copies of nodes in original list
*/
GList *
pcmk__copy_node_list(const GList *list, bool reset)
{
GList *result = NULL;
for (const GList *gIter = list; gIter != NULL; gIter = gIter->next) {
pe_node_t *new_node = NULL;
pe_node_t *this_node = (pe_node_t *) gIter->data;
new_node = pe__copy_node(this_node);
if (reset) {
new_node->weight = 0;
}
result = g_list_prepend(result, new_node);
}
return result;
}
struct node_weight_s {
pe_node_t *active;
pe_working_set_t *data_set;
};
-/* return -1 if 'a' is more preferred
- * return 1 if 'b' is more preferred
+/*!
+ * \internal
+ * \brief Compare two nodes for allocation desirability
+ *
+ * Given two nodes, check which one is more preferred by allocation criteria
+ * such as node weight and utilization.
+ *
+ * \param[in] a First node to compare
+ * \param[in] b Second node to compare
+ * \param[in] data Sort data (as struct node_weight_s *)
+ *
+ * \return -1 if \p a is preferred, +1 if \p b is preferred, or 0 if they are
+ * equally preferred
*/
-
static gint
-sort_node_weight(gconstpointer a, gconstpointer b, gpointer data)
+compare_nodes(gconstpointer a, gconstpointer b, gpointer data)
{
- const pe_node_t *node1 = (const pe_node_t *)a;
- const pe_node_t *node2 = (const pe_node_t *)b;
+ const pe_node_t *node1 = (const pe_node_t *) a;
+ const pe_node_t *node2 = (const pe_node_t *) b;
struct node_weight_s *nw = data;
int node1_weight = 0;
int node2_weight = 0;
int result = 0;
if (a == NULL) {
return 1;
}
if (b == NULL) {
return -1;
}
- node1_weight = node1->weight;
- node2_weight = node2->weight;
+ // Compare node weights
- if (!pcmk__node_available(node1)) {
- node1_weight = -INFINITY;
- }
- if (!pcmk__node_available(node2)) {
- node2_weight = -INFINITY;
- }
+ node1_weight = pcmk__node_available(node1)? node1->weight : -INFINITY;
+ node2_weight = pcmk__node_available(node2)? node2->weight : -INFINITY;
if (node1_weight > node2_weight) {
crm_trace("%s (%d) > %s (%d) : weight",
- node1->details->uname, node1_weight, node2->details->uname, node2_weight);
+ node1->details->uname, node1_weight, node2->details->uname,
+ node2_weight);
return -1;
}
if (node1_weight < node2_weight) {
crm_trace("%s (%d) < %s (%d) : weight",
- node1->details->uname, node1_weight, node2->details->uname, node2_weight);
+ node1->details->uname, node1_weight, node2->details->uname,
+ node2_weight);
return 1;
}
crm_trace("%s (%d) == %s (%d) : weight",
- node1->details->uname, node1_weight, node2->details->uname, node2_weight);
+ node1->details->uname, node1_weight, node2->details->uname,
+ node2_weight);
+
+ // If appropriate, compare node utilization
- if (pcmk__str_eq(nw->data_set->placement_strategy, "minimal", pcmk__str_casei)) {
+ if (pcmk__str_eq(nw->data_set->placement_strategy, "minimal",
+ pcmk__str_casei)) {
goto equal;
}
- if (pcmk__str_eq(nw->data_set->placement_strategy, "balanced", pcmk__str_casei)) {
+ if (pcmk__str_eq(nw->data_set->placement_strategy, "balanced",
+ pcmk__str_casei)) {
result = compare_capacity(node1, node2);
if (result < 0) {
crm_trace("%s > %s : capacity (%d)",
node1->details->uname, node2->details->uname, result);
return -1;
} else if (result > 0) {
crm_trace("%s < %s : capacity (%d)",
node1->details->uname, node2->details->uname, result);
return 1;
}
}
- /* now try to balance resources across the cluster */
+ // Compare number of allocated resources
+
if (node1->details->num_resources < node2->details->num_resources) {
crm_trace("%s (%d) > %s (%d) : resources",
node1->details->uname, node1->details->num_resources,
node2->details->uname, node2->details->num_resources);
return -1;
} else if (node1->details->num_resources > node2->details->num_resources) {
crm_trace("%s (%d) < %s (%d) : resources",
node1->details->uname, node1->details->num_resources,
node2->details->uname, node2->details->num_resources);
return 1;
}
- if (nw->active && nw->active->details == node1->details) {
- crm_trace("%s (%d) > %s (%d) : active",
- node1->details->uname, node1->details->num_resources,
- node2->details->uname, node2->details->num_resources);
- return -1;
- } else if (nw->active && nw->active->details == node2->details) {
- crm_trace("%s (%d) < %s (%d) : active",
- node1->details->uname, node1->details->num_resources,
- node2->details->uname, node2->details->num_resources);
- return 1;
+ // Check whether one node is already running desired resource
+
+ if (nw->active != NULL) {
+ if (nw->active->details == node1->details) {
+ crm_trace("%s (%d) > %s (%d) : active",
+ node1->details->uname, node1->details->num_resources,
+ node2->details->uname, node2->details->num_resources);
+ return -1;
+ } else if (nw->active->details == node2->details) {
+ crm_trace("%s (%d) < %s (%d) : active",
+ node1->details->uname, node1->details->num_resources,
+ node2->details->uname, node2->details->num_resources);
+ return 1;
+ }
}
- equal:
+
+ // If all else is equal, prefer node with lowest-sorting name
+equal:
crm_trace("%s = %s", node1->details->uname, node2->details->uname);
return strcmp(node1->details->uname, node2->details->uname);
}
GList *
sort_nodes_by_weight(GList *nodes, pe_node_t *active_node,
pe_working_set_t *data_set)
{
struct node_weight_s nw = { active_node, data_set };
- return g_list_sort_with_data(nodes, sort_node_weight, &nw);
+ return g_list_sort_with_data(nodes, compare_nodes, &nw);
}
gboolean
can_run_any(GHashTable * nodes)
{
GHashTableIter iter;
pe_node_t *node = NULL;
if (nodes == NULL) {
return FALSE;
}
g_hash_table_iter_init(&iter, nodes);
while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
if (pcmk__node_available(node) && (node->weight >= 0)) {
return TRUE;
}
}
return FALSE;
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:28 PM (12 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1984369
Default Alt Text
(8 KB)

Event Timeline