Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4624603
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/include/crm/common/util.h b/include/crm/common/util.h
index cb2461713f..82c8485869 100644
--- a/include/crm/common/util.h
+++ b/include/crm/common/util.h
@@ -1,154 +1,155 @@
/*
* Copyright 2004-2022 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#ifndef PCMK__CRM_COMMON_UTIL__H
# define PCMK__CRM_COMMON_UTIL__H
# include <sys/types.h> // gid_t, mode_t, size_t, time_t, uid_t
# include <stdlib.h>
# include <stdbool.h>
# include <stdint.h> // uint32_t
# include <limits.h>
# include <signal.h>
# include <glib.h>
# include <libxml/tree.h>
# include <crm/lrmd.h>
# include <crm/common/acl.h>
# include <crm/common/agents.h>
# include <crm/common/results.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Utility functions
* \ingroup core
*/
# define ONLINESTATUS "online" // Status of an online client
# define OFFLINESTATUS "offline" // Status of an offline client
/* public node attribute functions (from attrd_client.c) */
char *pcmk_promotion_score_name(const char *rsc_id);
/* public Pacemaker Remote functions (from remote.c) */
int crm_default_remote_port(void);
/* public score-related functions (from scores.c) */
+const char *pcmk_readable_score(int score);
int char2score(const char *score);
char *score2char(int score);
char *score2char_stack(int score, char *buf, size_t len);
int pcmk__add_scores(int score1, int score2);
/* public string functions (from strings.c) */
gboolean crm_is_true(const char *s);
int crm_str_to_boolean(const char *s, int *ret);
long long crm_get_msec(const char *input);
char * crm_strip_trailing_newline(char *str);
char *crm_strdup_printf(char const *format, ...) G_GNUC_PRINTF(1, 2);
guint crm_parse_interval_spec(const char *input);
/* public operation functions (from operations.c) */
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type,
guint *interval_ms);
gboolean decode_transition_key(const char *key, char **uuid, int *transition_id,
int *action_id, int *target_rc);
gboolean decode_transition_magic(const char *magic, char **uuid,
int *transition_id, int *action_id,
int *op_status, int *op_rc, int *target_rc);
int rsc_op_expected_rc(lrmd_event_data_t *event);
gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc);
bool crm_op_needs_metadata(const char *rsc_class, const char *op);
xmlNode *crm_create_op_xml(xmlNode *parent, const char *prefix,
const char *task, const char *interval_spec,
const char *timeout);
#define CRM_DEFAULT_OP_TIMEOUT_S "20s"
bool pcmk_is_probe(const char *task, guint interval);
bool pcmk_xe_is_probe(xmlNode *xml_op);
bool pcmk_xe_mask_probe_failure(xmlNode *xml_op);
int compare_version(const char *version1, const char *version2);
/* coverity[+kill] */
void crm_abort(const char *file, const char *function, int line,
const char *condition, gboolean do_core, gboolean do_fork);
/*!
* \brief Check whether any of specified flags are set in a flag group
*
* \param[in] flag_group The flag group being examined
* \param[in] flags_to_check Which flags in flag_group should be checked
*
* \return true if \p flags_to_check is nonzero and any of its flags are set in
* \p flag_group, or false otherwise
*/
static inline bool
pcmk_any_flags_set(uint64_t flag_group, uint64_t flags_to_check)
{
return (flag_group & flags_to_check) != 0;
}
/*!
* \brief Check whether all of specified flags are set in a flag group
*
* \param[in] flag_group The flag group being examined
* \param[in] flags_to_check Which flags in flag_group should be checked
*
* \return true if \p flags_to_check is zero or all of its flags are set in
* \p flag_group, or false otherwise
*/
static inline bool
pcmk_all_flags_set(uint64_t flag_group, uint64_t flags_to_check)
{
return (flag_group & flags_to_check) == flags_to_check;
}
/*!
* \brief Convenience alias for pcmk_all_flags_set(), to check single flag
*/
#define pcmk_is_set(g, f) pcmk_all_flags_set((g), (f))
char *crm_meta_name(const char *field);
const char *crm_meta_value(GHashTable * hash, const char *field);
char *crm_md5sum(const char *buffer);
char *crm_generate_uuid(void);
// This belongs in ipc.h but is here for backward compatibility
bool crm_is_daemon_name(const char *name);
int crm_user_lookup(const char *name, uid_t * uid, gid_t * gid);
int pcmk_daemon_user(uid_t *uid, gid_t *gid);
#ifdef HAVE_GNUTLS_GNUTLS_H
void crm_gnutls_global_init(void);
#endif
char *pcmk_hostname(void);
bool pcmk_str_is_infinity(const char *s);
bool pcmk_str_is_minus_infinity(const char *s);
#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
#include <crm/common/util_compat.h>
#endif
#ifdef __cplusplus
}
#endif
#endif
diff --git a/lib/common/scores.c b/lib/common/scores.c
index a0cf264ab3..311ea3e63b 100644
--- a/lib/common/scores.c
+++ b/lib/common/scores.c
@@ -1,200 +1,216 @@
/*
* Copyright 2004-2022 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#include <crm_internal.h>
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <stdio.h> // snprintf(), NULL
#include <string.h> // strcpy(), strdup()
#include <sys/types.h> // size_t
int pcmk__score_red = 0;
int pcmk__score_green = 0;
int pcmk__score_yellow = 0;
/*!
* \brief Get the integer value of a score string
*
* Given a string representation of a score, return the integer equivalent.
* This accepts infinity strings as well as red, yellow, and green, and
* bounds the result to +/-INFINITY.
*
* \param[in] score Score as string
*
* \return Integer value corresponding to \p score
*/
int
char2score(const char *score)
{
if (score == NULL) {
return 0;
} else if (pcmk_str_is_minus_infinity(score)) {
return -CRM_SCORE_INFINITY;
} else if (pcmk_str_is_infinity(score)) {
return CRM_SCORE_INFINITY;
} else if (pcmk__str_eq(score, PCMK__VALUE_RED, pcmk__str_casei)) {
return pcmk__score_red;
} else if (pcmk__str_eq(score, PCMK__VALUE_YELLOW, pcmk__str_casei)) {
return pcmk__score_yellow;
} else if (pcmk__str_eq(score, PCMK__VALUE_GREEN, pcmk__str_casei)) {
return pcmk__score_green;
} else {
long long score_ll;
pcmk__scan_ll(score, &score_ll, 0LL);
if (score_ll > CRM_SCORE_INFINITY) {
return CRM_SCORE_INFINITY;
} else if (score_ll < -CRM_SCORE_INFINITY) {
return -CRM_SCORE_INFINITY;
} else {
return (int) score_ll;
}
}
}
+/*!
+ * \brief Return a displayable static string for a score value
+ *
+ * Given a score value, return a pointer to a static string representation of
+ * the score suitable for log messages, output, etc.
+ *
+ * \param[in] score Score to display
+ *
+ * \return Pointer to static memory containing string representation of \p score
+ * \note Subsequent calls to this function will overwrite the returned value, so
+ * it should be used only in a local context such as a printf()-style
+ * statement.
+ */
+const char *
+pcmk_readable_score(int score)
+{
+ // The longest possible result is "-INFINITY"
+ static char score_s[sizeof(CRM_MINUS_INFINITY_S)];
+
+ if (score >= CRM_SCORE_INFINITY) {
+ strcpy(score_s, CRM_INFINITY_S);
+
+ } else if (score <= -CRM_SCORE_INFINITY) {
+ strcpy(score_s, CRM_MINUS_INFINITY_S);
+
+ } else {
+ // Range is limited to +/-1000000, so no chance of overflow
+ snprintf(score_s, sizeof(score_s), "%d", score);
+ }
+
+ return score_s;
+}
+
/*!
* \brief Convert an integer score to a string, using a provided buffer
*
* Store the string equivalent of a given integer score in a given string
* buffer, using "INFINITY" and "-INFINITY" when appropriate.
*
* \param[in] score Integer score to convert
* \param[out] buf Where to store string representation of \p score
* \param[in] len Size of \p buf (in bytes)
*
* \return \p buf (or NULL if \p len is too small)
*/
char *
score2char_stack(int score, char *buf, size_t len)
{
CRM_CHECK((buf != NULL) && (len >= sizeof(CRM_MINUS_INFINITY_S)),
return NULL);
-
- if (score >= CRM_SCORE_INFINITY) {
- strcpy(buf, CRM_INFINITY_S);
- } else if (score <= -CRM_SCORE_INFINITY) {
- strcpy(buf, CRM_MINUS_INFINITY_S);
- } else {
- snprintf(buf, len, "%d", score);
- }
+ strcpy(buf, pcmk_readable_score(score));
return buf;
}
/*!
* \brief Return the string equivalent of an integer score
*
* Return the string equivalent of a given integer score, using "INFINITY" and
* "-INFINITY" when appropriate.
*
* \param[in] score Integer score to convert
*
* \return Newly allocated string equivalent of \p score
* \note The caller is responsible for freeing the return value. This function
* asserts on memory errors, so the return value can be assumed to be
* non-NULL.
*/
char *
score2char(int score)
{
- char *result = NULL;
+ char *result = strdup(pcmk_readable_score(score));
- if (score >= CRM_SCORE_INFINITY) {
- result = strdup(CRM_INFINITY_S);
- CRM_ASSERT(result != NULL);
-
- } else if (score <= -CRM_SCORE_INFINITY) {
- result = strdup(CRM_MINUS_INFINITY_S);
- CRM_ASSERT(result != NULL);
-
- } else {
- result = pcmk__itoa(score);
- }
+ CRM_ASSERT(result != NULL);
return result;
}
/*!
* \internal
* \brief Add two scores, bounding to +/-INFINITY
*
* \param[in] score1 First score to add
* \param[in] score2 Second score to add
*/
int
pcmk__add_scores(int score1, int score2)
{
int result = score1 + score2;
// First handle the cases where one or both is infinite
if (score1 <= -CRM_SCORE_INFINITY) {
if (score2 <= -CRM_SCORE_INFINITY) {
crm_trace("-INFINITY + -INFINITY = -INFINITY");
} else if (score2 >= CRM_SCORE_INFINITY) {
crm_trace("-INFINITY + +INFINITY = -INFINITY");
} else {
crm_trace("-INFINITY + %d = -INFINITY", score2);
}
return -CRM_SCORE_INFINITY;
} else if (score2 <= -CRM_SCORE_INFINITY) {
if (score1 >= CRM_SCORE_INFINITY) {
crm_trace("+INFINITY + -INFINITY = -INFINITY");
} else {
crm_trace("%d + -INFINITY = -INFINITY", score1);
}
return -CRM_SCORE_INFINITY;
} else if (score1 >= CRM_SCORE_INFINITY) {
if (score2 >= CRM_SCORE_INFINITY) {
crm_trace("+INFINITY + +INFINITY = +INFINITY");
} else {
crm_trace("+INFINITY + %d = +INFINITY", score2);
}
return CRM_SCORE_INFINITY;
} else if (score2 >= CRM_SCORE_INFINITY) {
crm_trace("%d + +INFINITY = +INFINITY", score1);
return CRM_SCORE_INFINITY;
}
/* As long as CRM_SCORE_INFINITY is less than half of the maximum integer,
* we can ignore the possibility of integer overflow
*/
// Bound result to infinity
if (result >= CRM_SCORE_INFINITY) {
crm_trace("%d + %d = +INFINITY", score1, score2);
return CRM_SCORE_INFINITY;
} else if (result <= -CRM_SCORE_INFINITY) {
crm_trace("%d + %d = -INFINITY", score1, score2);
return -CRM_SCORE_INFINITY;
}
crm_trace("%d + %d = %d", score1, score2, result);
return result;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:37 PM (5 h, 40 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1995311
Default Alt Text
(11 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment