Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4624665
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/include/crm/common/util.h b/include/crm/common/util.h
index 82c8485869..139003ed18 100644
--- a/include/crm/common/util.h
+++ b/include/crm/common/util.h
@@ -1,155 +1,154 @@
/*
* 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/include/crm/common/util_compat.h b/include/crm/common/util_compat.h
index 73ba41722b..8bf0af3810 100644
--- a/include/crm/common/util_compat.h
+++ b/include/crm/common/util_compat.h
@@ -1,158 +1,161 @@
/*
* 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 Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#ifndef PCMK__CRM_COMMON_UTIL_COMPAT__H
# define PCMK__CRM_COMMON_UTIL_COMPAT__H
# include <glib.h>
# include <crm/common/util.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Deprecated Pacemaker utilities
* \ingroup core
* \deprecated Do not include this header directly. The utilities in this
* header, and the header itself, will be removed in a future
* release.
*/
//! \deprecated Use crm_parse_interval_spec() instead
#define crm_get_interval crm_parse_interval_spec
//! \deprecated Use !pcmk_is_set() or !pcmk_all_flags_set() instead
static inline gboolean
is_not_set(long long word, long long bit)
{
return ((word & bit) == 0);
}
//! \deprecated Use pcmk_is_set() or pcmk_all_flags_set() instead
static inline gboolean
is_set(long long word, long long bit)
{
return ((word & bit) == bit);
}
//! \deprecated Use pcmk_any_flags_set() instead
static inline gboolean
is_set_any(long long word, long long bit)
{
return ((word & bit) != 0);
}
//! \deprecated Use strcmp() or strcasecmp() instead
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case);
//! \deprecated Use strcmp() instead
gboolean safe_str_neq(const char *a, const char *b);
//! \deprecated Use strcasecmp() instead
#define safe_str_eq(a, b) crm_str_eq(a, b, FALSE)
//! \deprecated Use snprintf() instead
char *crm_itoa_stack(int an_int, char *buf, size_t len);
//! \deprecated Use sscanf() instead
int pcmk_scan_nvpair(const char *input, char **name, char **value);
//! \deprecated Use a standard printf()-style function instead
char *pcmk_format_nvpair(const char *name, const char *value,
const char *units);
//! \deprecated Use a standard printf()-style function instead
char *pcmk_format_named_time(const char *name, time_t epoch_time);
//! \deprecated Use strtoll() instead
long long crm_parse_ll(const char *text, const char *default_text);
//! \deprecated Use strtoll() instead
int crm_parse_int(const char *text, const char *default_text);
//! \deprecated Use strtoll() instead
# define crm_atoi(text, default_text) crm_parse_int(text, default_text)
//! \deprecated Use g_str_hash() instead
guint g_str_hash_traditional(gconstpointer v);
//! \deprecated Use g_str_hash() instead
#define crm_str_hash g_str_hash_traditional
//! \deprecated Do not use Pacemaker for generic string comparison
gboolean crm_strcase_equal(gconstpointer a, gconstpointer b);
//! \deprecated Do not use Pacemaker for generic string manipulation
guint crm_strcase_hash(gconstpointer v);
//! \deprecated Use g_hash_table_new_full() instead
static inline GHashTable *
crm_str_table_new(void)
{
return g_hash_table_new_full(crm_str_hash, g_str_equal, free, free);
}
//! \deprecated Use g_hash_table_new_full() instead
static inline GHashTable *
crm_strcase_table_new(void)
{
return g_hash_table_new_full(crm_strcase_hash, crm_strcase_equal,
free, free);
}
//! \deprecated Do not use Pacemaker for generic hash table manipulation
GHashTable *crm_str_table_dup(GHashTable *old_table);
//! \deprecated Use g_hash_able_size() instead
static inline guint
crm_hash_table_size(GHashTable *hashtable)
{
if (hashtable == NULL) {
return 0;
}
return g_hash_table_size(hashtable);
}
//! \deprecated Don't use Pacemaker for string manipulation
char *crm_strip_trailing_newline(char *str);
//! \deprecated Don't use Pacemaker for string manipulation
int pcmk_numeric_strcasecmp(const char *s1, const char *s2);
//! \deprecated Don't use Pacemaker for string manipulation
static inline char *
crm_itoa(int an_int)
{
return crm_strdup_printf("%d", an_int);
}
//! \deprecated Don't use Pacemaker for string manipulation
static inline char *
crm_ftoa(double a_float)
{
return crm_strdup_printf("%f", a_float);
}
//! \deprecated Don't use Pacemaker for string manipulation
static inline char *
crm_ttoa(time_t epoch_time)
{
return crm_strdup_printf("%lld", (long long) epoch_time);
}
//! \deprecated Do not use Pacemaker libraries for generic I/O
void crm_build_path(const char *path_c, mode_t mode);
+//! \deprecated Use pcmk_readable_score() instead
+char *score2char(int score);
+
#ifdef __cplusplus
}
#endif
#endif // PCMK__CRM_COMMON_UTIL_COMPAT__H
diff --git a/lib/common/scores.c b/lib/common/scores.c
index 311ea3e63b..ecd24dc82d 100644
--- a/lib/common/scores.c
+++ b/lib/common/scores.c
@@ -1,216 +1,211 @@
/*
* 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);
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 = strdup(pcmk_readable_score(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;
}
+
+// Deprecated functions kept only for backward API compatibility
+// LCOV_EXCL_START
+
+#include <crm/common/util_compat.h>
+
+char *
+score2char(int score)
+{
+ char *result = strdup(pcmk_readable_score(score));
+
+ CRM_ASSERT(result != NULL);
+ return result;
+}
+
+// LCOV_EXCL_STOP
+// End deprecated API
diff --git a/lib/common/tests/scores/Makefile.am b/lib/common/tests/scores/Makefile.am
index 2cc938cfd4..850d63fce6 100644
--- a/lib/common/tests/scores/Makefile.am
+++ b/lib/common/tests/scores/Makefile.am
@@ -1,25 +1,24 @@
#
# Copyright 2020-2022 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.
#
AM_CPPFLAGS = -I$(top_srcdir)/include \
-I$(top_builddir)/include \
-I$(top_srcdir)/lib/common
LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la
AM_LDFLAGS = $(LDFLAGS_WRAP)
include $(top_srcdir)/mk/tap.mk
# Add "_test" to the end of all test program names to simplify .gitignore.
check_PROGRAMS = \
char2score_test \
pcmk__add_scores_test \
- score2char_stack_test \
- score2char_test
+ score2char_stack_test
TESTS = $(check_PROGRAMS)
diff --git a/lib/common/tests/scores/score2char_test.c b/lib/common/tests/scores/score2char_test.c
deleted file mode 100644
index 98bbd8d1eb..0000000000
--- a/lib/common/tests/scores/score2char_test.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 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>
-
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-static void
-outside_limits(void **state)
-{
- char *a = NULL;
-
- a = score2char(CRM_SCORE_INFINITY * 2);
- assert_string_equal(a, CRM_INFINITY_S);
- free(a);
-
- a = score2char(-CRM_SCORE_INFINITY * 2);
- assert_string_equal(a, CRM_MINUS_INFINITY_S);
- free(a);
-}
-
-static void
-inside_limits(void **state)
-{
- char *a = NULL;
-
- a = score2char(1024);
- assert_string_equal(a, "1024");
- free(a);
-
- a = score2char(0);
- assert_string_equal(a, "0");
- free(a);
-
- a = score2char(-1024);
- assert_string_equal(a, "-1024");
- free(a);
-}
-
-int main(int argc, char **argv)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(outside_limits),
- cmocka_unit_test(inside_limits),
- };
-
- cmocka_set_message_output(CM_OUTPUT_TAP);
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jul 8, 6:40 PM (2 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1984058
Default Alt Text
(18 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment