pacemaker  3.0.0-d8340737c4
Scalable High-Availability cluster resource manager
scores.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 <stdio.h> // snprintf(), NULL
13 #include <string.h> // strcpy(), strdup()
14 #include <sys/types.h> // size_t
15 
19 
33 int
34 pcmk_parse_score(const char *score_s, int *score, int default_score)
35 {
36  int rc = pcmk_rc_ok;
37  int local_score = 0;
38 
39  // Ensure default score is in bounds
40  default_score = QB_MIN(default_score, PCMK_SCORE_INFINITY);
41  default_score = QB_MAX(default_score, -PCMK_SCORE_INFINITY);
42  local_score = default_score;
43 
44  if (score_s == NULL) {
45 
46  } else if (pcmk_str_is_minus_infinity(score_s)) {
47  local_score = -PCMK_SCORE_INFINITY;
48 
49  } else if (pcmk_str_is_infinity(score_s)) {
50  local_score = PCMK_SCORE_INFINITY;
51 
52  } else if (pcmk__str_eq(score_s, PCMK_VALUE_RED, pcmk__str_casei)) {
53  local_score = pcmk__score_red;
54 
55  } else if (pcmk__str_eq(score_s, PCMK_VALUE_YELLOW, pcmk__str_casei)) {
56  local_score = pcmk__score_yellow;
57 
58  } else if (pcmk__str_eq(score_s, PCMK_VALUE_GREEN, pcmk__str_casei)) {
59  local_score = pcmk__score_green;
60 
61  } else {
62  long long score_ll = 0LL;
63 
64  rc = pcmk__scan_ll(score_s, &score_ll, default_score);
65  if (rc == ERANGE) {
66  rc = pcmk_rc_ok;
67  }
68  if (rc != pcmk_rc_ok) {
69  local_score = default_score;
70 
71  } else if (score_ll > PCMK_SCORE_INFINITY) {
72  local_score = PCMK_SCORE_INFINITY;
73 
74  } else if (score_ll < -PCMK_SCORE_INFINITY) {
75  local_score = -PCMK_SCORE_INFINITY;
76 
77  } else {
78  local_score = (int) score_ll;
79  }
80  }
81 
82  if (score != NULL) {
83  *score = local_score;
84  }
85  return rc;
86 }
87 
101 const char *
103 {
104  // The longest possible result is "-INFINITY"
105  static char score_s[sizeof(PCMK_VALUE_MINUS_INFINITY)];
106 
107  if (score >= PCMK_SCORE_INFINITY) {
108  strcpy(score_s, PCMK_VALUE_INFINITY);
109 
110  } else if (score <= -PCMK_SCORE_INFINITY) {
111  strcpy(score_s, PCMK_VALUE_MINUS_INFINITY);
112 
113  } else {
114  // Range is limited to +/-1000000, so no chance of overflow
115  snprintf(score_s, sizeof(score_s), "%d", score);
116  }
117 
118  return score_s;
119 }
120 
129 bool
130 pcmk_str_is_infinity(const char *s) {
132  NULL);
133 }
134 
143 bool
145  return pcmk__str_eq(s, PCMK_VALUE_MINUS_INFINITY, pcmk__str_none);
146 }
147 
158 int
159 pcmk__add_scores(int score1, int score2)
160 {
161  /* As long as PCMK_SCORE_INFINITY is less than half of the maximum integer,
162  * we can ignore the possibility of integer overflow.
163  */
164  int result = score1 + score2;
165 
166  // First handle the cases where one or both is infinite
167  if ((score1 <= -PCMK_SCORE_INFINITY) || (score2 <= -PCMK_SCORE_INFINITY)) {
168  return -PCMK_SCORE_INFINITY;
169  }
170  if ((score1 >= PCMK_SCORE_INFINITY) || (score2 >= PCMK_SCORE_INFINITY)) {
171  return PCMK_SCORE_INFINITY;
172  }
173 
174  // Bound result to infinity.
175  if (result >= PCMK_SCORE_INFINITY) {
176  return PCMK_SCORE_INFINITY;
177  }
178  if (result <= -PCMK_SCORE_INFINITY) {
179  return -PCMK_SCORE_INFINITY;
180  }
181 
182  return result;
183 }
184 
185 // Deprecated functions kept only for backward API compatibility
186 // LCOV_EXCL_START
187 
189 
190 int
191 char2score(const char *score)
192 {
193  int result = 0;
194 
195  (void) pcmk_parse_score(score, &result, 0);
196  return result;
197 }
198 
199 // LCOV_EXCL_STOP
200 // End deprecated API
#define PCMK_VALUE_GREEN
Definition: options.h:158
bool pcmk_str_is_minus_infinity(const char *s)
Definition: scores.c:144
#define PCMK_VALUE_MINUS_INFINITY
Definition: options.h:174
bool pcmk_str_is_infinity(const char *s)
Definition: scores.c:130
#define PCMK_VALUE_INFINITY
Definition: options.h:164
int pcmk__add_scores(int score1, int score2)
Definition: scores.c:159
int pcmk__score_yellow
Definition: scores.c:18
int char2score(const char *score)
Definition: scores.c:191
#define PCMK_VALUE_PLUS_INFINITY
Definition: options.h:194
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
Definition: strings.c:92
#define PCMK_VALUE_RED
Definition: options.h:200
int pcmk_parse_score(const char *score_s, int *score, int default_score)
Parse an integer score from a string.
Definition: scores.c:34
int pcmk__score_red
Definition: scores.c:16
int pcmk__score_green
Definition: scores.c:17
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
Definition: scores.c:102
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:1051
pcmk__action_result_t result
Definition: pcmk_fence.c:37
#define PCMK_VALUE_YELLOW
Definition: options.h:224
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
Definition: scores.h:26