pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
pe_health.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2024 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>
14#include "pe_status_private.h"
15
23void
64
65struct health_sum {
66 const pcmk_node_t *node; // Node that health score is being summed for
67 int sum; // Sum of health scores checked so far
68};
69
79static void
80add_node_health_value(gpointer key, gpointer value, gpointer user_data)
81{
82 if (pcmk__starts_with((const char *) key, "#health")) {
83 struct health_sum *health_sum = user_data;
84 int score = 0;
85 int rc = pcmk_parse_score((const char *) value, &score, 0);
86
87 if (rc != pcmk_rc_ok) {
88 crm_warn("Ignoring %s for %s because '%s' is not a valid value: %s",
89 (const char *) key, pcmk__node_name(health_sum->node),
90 (const char *) value, pcmk_rc_str(rc));
91 return;
92 }
93
94 health_sum->sum = pcmk__add_scores(score, health_sum->sum);
95 crm_trace("Combined '%s' into node health score (now %s)",
96 (const char *) value, pcmk_readable_score(health_sum->sum));
97 }
98}
99
109int
110pe__sum_node_health_scores(const pcmk_node_t *node, int base_health)
111{
112 struct health_sum health_sum = { node, base_health, };
113
114 pcmk__assert(node != NULL);
115 g_hash_table_foreach(node->priv->attrs, add_node_health_value,
116 &health_sum);
117 return health_sum.sum;
118}
119
129int
131{
132 GHashTableIter iter;
133 const char *name = NULL;
134 const char *value = NULL;
135 enum pcmk__health_strategy strategy;
136 int score = 0;
137 int rc = 1;
138
139 pcmk__assert(node != NULL);
140
141 strategy = pe__health_strategy(node->priv->scheduler);
142 if (strategy == pcmk__health_strategy_none) {
143 return rc;
144 }
145
146 g_hash_table_iter_init(&iter, node->priv->attrs);
147 while (g_hash_table_iter_next(&iter, (gpointer *) &name,
148 (gpointer *) &value)) {
149 if (pcmk__starts_with(name, "#health")) {
150 int parse_rc = pcmk_rc_ok;
151
152 /* It's possible that pcmk__score_red equals pcmk__score_yellow,
153 * or pcmk__score_yellow equals pcmk__score_green, so check the
154 * textual value first to be able to distinguish those.
155 */
156 if (pcmk__str_eq(value, PCMK_VALUE_RED, pcmk__str_casei)) {
157 return -1;
158 } else if (pcmk__str_eq(value, PCMK_VALUE_YELLOW,
160 rc = 0;
161 continue;
162 }
163
164 parse_rc = pcmk_parse_score(value, &score, 0);
165 if (parse_rc != pcmk_rc_ok) {
166 crm_warn("Ignoring %s for %s "
167 "because '%s' is not a valid value: %s",
168 name, pcmk__node_name(node), value,
169 pcmk_rc_str(parse_rc));
170 continue;
171 }
172
173 // The value is an integer, so compare numerically
174 if (score <= pcmk__score_red) {
175 return -1;
176 } else if ((score <= pcmk__score_yellow)
178 rc = 0;
179 }
180 }
181 }
182 return rc;
183}
const char * name
Definition cib.c:26
int pcmk__score_yellow
Definition scores.c:18
int pcmk__score_green
Definition scores.c:17
int pcmk__score_red
Definition scores.c:16
pcmk__health_strategy
@ pcmk__health_strategy_only_green
@ pcmk__health_strategy_none
@ pcmk__health_strategy_no_red
int pcmk__health_score(const char *option, const pcmk_scheduler_t *scheduler)
Definition health.c:82
#define crm_warn(fmt, args...)
Definition logging.h:360
#define crm_debug(fmt, args...)
Definition logging.h:368
#define crm_trace(fmt, args...)
Definition logging.h:370
pcmk_scheduler_t * scheduler
#define PCMK_OPT_NODE_HEALTH_YELLOW
Definition options.h:53
#define PCMK_OPT_NODE_HEALTH_RED
Definition options.h:51
#define PCMK_OPT_NODE_HEALTH_GREEN
Definition options.h:50
#define PCMK_VALUE_YELLOW
Definition options.h:225
#define PCMK_VALUE_GREEN
Definition options.h:159
#define PCMK_VALUE_RED
Definition options.h:201
int pe__node_health(pcmk_node_t *node)
Definition pe_health.c:130
int pe__sum_node_health_scores(const pcmk_node_t *node, int base_health)
Definition pe_health.c:110
void pe__unpack_node_health_scores(pcmk_scheduler_t *scheduler)
Definition pe_health.c:24
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition results.c:617
@ pcmk_rc_ok
Definition results.h:159
#define pcmk__assert(expr)
int pcmk_parse_score(const char *score_s, int *score, int default_score)
Parse an integer score from a string.
Definition scores.c:34
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
Definition scores.c:102
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
Definition scores.h:26
int pcmk__add_scores(int score1, int score2)
Definition scores.c:159
Cluster status and scheduling.
bool pcmk__starts_with(const char *str, const char *prefix)
Check whether a string starts with a certain sequence.
Definition strings.c:558
@ pcmk__str_casei
pcmk_scheduler_t * scheduler
pcmk__node_private_t * priv
Definition nodes.h:85