root/lib/pengine/pe_health.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pe__unpack_node_health_scores
  2. add_node_health_value
  3. pe__sum_node_health_scores
  4. pe__node_health

   1 /*
   2  * Copyright 2004-2023 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU Lesser General Public License
   7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <crm/pengine/status.h>
  13 #include <crm/pengine/internal.h>
  14 #include "pe_status_private.h"
  15 
  16 /*!
  17  * \internal
  18  * \brief Set the node health values to use for "red", "yellow", and "green"
  19  *
  20  * \param[in,out] scheduler  Scheduler data
  21  */
  22 void
  23 pe__unpack_node_health_scores(pcmk_scheduler_t *scheduler)
     /* [previous][next][first][last][top][bottom][index][help] */
  24 {
  25     switch (pe__health_strategy(scheduler)) {
  26         case pcmk__health_strategy_none:
  27             pcmk__score_red = 0;
  28             pcmk__score_yellow = 0;
  29             pcmk__score_green = 0;
  30             break;
  31 
  32         case pcmk__health_strategy_no_red:
  33             pcmk__score_red = -INFINITY;
  34             pcmk__score_yellow = 0;
  35             pcmk__score_green = 0;
  36             break;
  37 
  38         case pcmk__health_strategy_only_green:
  39             pcmk__score_red = -INFINITY;
  40             pcmk__score_yellow = -INFINITY;
  41             pcmk__score_green = 0;
  42             break;
  43 
  44         default: // progressive or custom
  45             pcmk__score_red = pe__health_score(PCMK__OPT_NODE_HEALTH_RED,
  46                                                scheduler);
  47             pcmk__score_green = pe__health_score(PCMK__OPT_NODE_HEALTH_GREEN,
  48                                                  scheduler);
  49             pcmk__score_yellow = pe__health_score(PCMK__OPT_NODE_HEALTH_YELLOW,
  50                                                   scheduler);
  51             break;
  52     }
  53 
  54     if ((pcmk__score_red != 0) || (pcmk__score_yellow != 0)
  55         || (pcmk__score_green != 0)) {
  56         crm_debug("Values of node health scores: "
  57                   PCMK__VALUE_RED "=%d "
  58                   PCMK__VALUE_YELLOW "=%d "
  59                   PCMK__VALUE_GREEN "=%d",
  60                   pcmk__score_red, pcmk__score_yellow, pcmk__score_green);
  61     }
  62 }
  63 
  64 /*!
  65  * \internal
  66  * \brief Add node attribute value to an integer, if it is a health attribute
  67  *
  68  * \param[in]     key        Name of node attribute
  69  * \param[in]     value      String value of node attribute
  70  * \param[in,out] user_data  Address of integer to which \p value should be
  71  *                           added if \p key is a node health attribute
  72  */
  73 static void
  74 add_node_health_value(gpointer key, gpointer value, gpointer user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
  75 {
  76     if (pcmk__starts_with((const char *) key, "#health")) {
  77         int score = char2score((const char *) value);
  78         int *health = (int *) user_data;
  79 
  80         *health = pcmk__add_scores(score, *health);
  81         crm_trace("Combined '%s' into node health score (now %s)",
  82                   (const char *) value, pcmk_readable_score(*health));
  83     }
  84 }
  85 
  86 /*!
  87  * \internal
  88  * \brief Sum a node's health attribute scores
  89  *
  90  * \param[in] node         Node whose health attributes should be added
  91  * \param[in] base_health  Add this number to the total
  92  *
  93  * \return Sum of all health attribute scores of \p node plus \p base_health
  94  */
  95 int
  96 pe__sum_node_health_scores(const pcmk_node_t *node, int base_health)
     /* [previous][next][first][last][top][bottom][index][help] */
  97 {
  98     CRM_ASSERT(node != NULL);
  99     g_hash_table_foreach(node->details->attrs, add_node_health_value,
 100                          &base_health);
 101     return base_health;
 102 }
 103 
 104 /*!
 105  * \internal
 106  * \brief Check the general health status for a node
 107  *
 108  * \param[in,out] node  Node to check
 109  *
 110  * \return  A negative value if any health attribute for \p node is red,
 111  *          otherwise 0 if any attribute is yellow, otherwise a positive value.
 112  */
 113 int
 114 pe__node_health(pcmk_node_t *node)
     /* [previous][next][first][last][top][bottom][index][help] */
 115 {
 116     GHashTableIter iter;
 117     const char *name = NULL;
 118     const char *value = NULL;
 119     enum pcmk__health_strategy strategy;
 120     int score = 0;
 121     int rc = 1;
 122 
 123     CRM_ASSERT(node != NULL);
 124 
 125     strategy = pe__health_strategy(node->details->data_set);
 126     if (strategy == pcmk__health_strategy_none) {
 127         return rc;
 128     }
 129 
 130     g_hash_table_iter_init(&iter, node->details->attrs);
 131     while (g_hash_table_iter_next(&iter, (gpointer *) &name,
 132                                   (gpointer *) &value)) {
 133         if (pcmk__starts_with(name, "#health")) {
 134             /* It's possible that pcmk__score_red equals pcmk__score_yellow,
 135              * or pcmk__score_yellow equals pcmk__score_green, so check the
 136              * textual value first to be able to distinguish those.
 137              */
 138             if (pcmk__str_eq(value, PCMK__VALUE_RED, pcmk__str_casei)) {
 139                 return -1;
 140             } else if (pcmk__str_eq(value, PCMK__VALUE_YELLOW,
 141                                     pcmk__str_casei)) {
 142                 rc = 0;
 143                 continue;
 144             }
 145 
 146             // The value is an integer, so compare numerically
 147             score = char2score(value);
 148             if (score <= pcmk__score_red) {
 149                 return -1;
 150             } else if ((score <= pcmk__score_yellow)
 151                        && (pcmk__score_yellow != pcmk__score_green)) {
 152                 rc = 0;
 153             }
 154         }
 155     }
 156     return rc;
 157 }

/* [previous][next][first][last][top][bottom][index][help] */