Coverage Report

Created: 2025-12-31 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pacemaker/include/crm/common/nodes_internal.h
Line
Count
Source
1
/*
2
 * Copyright 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
#ifndef PCMK__CRM_COMMON_NODES_INTERNAL__H
11
#define PCMK__CRM_COMMON_NODES_INTERNAL__H
12
13
#include <stdio.h>      // NULL
14
#include <stdbool.h>    // bool
15
#include <stdint.h>     // uint32_t, UINT32_C()
16
17
#include <glib.h>       // gpointer, GList, GHashTable
18
#include <crm/common/nodes.h>
19
20
#ifdef __cplusplus
21
extern "C" {
22
#endif
23
24
/*
25
 * Special node attributes
26
 */
27
28
#define PCMK__NODE_ATTR_SHUTDOWN            "shutdown"
29
30
/* @COMPAT Deprecated since 2.1.8. Use a location constraint with
31
 * PCMK_XA_RSC_PATTERN=".*" and PCMK_XA_RESOURCE_DISCOVERY="never" instead of
32
 * PCMK__NODE_ATTR_RESOURCE_DISCOVERY_ENABLED="false".
33
 */
34
#define PCMK__NODE_ATTR_RESOURCE_DISCOVERY_ENABLED  "resource-discovery-enabled"
35
36
enum pcmk__node_variant { // Possible node types
37
    pcmk__node_variant_cluster  = 1,    // Cluster layer node
38
    pcmk__node_variant_remote   = 2,    // Pacemaker Remote node
39
};
40
41
enum pcmk__node_flags {
42
    pcmk__node_none             = UINT32_C(0),
43
44
    // Whether node is in standby mode
45
    pcmk__node_standby          = (UINT32_C(1) << 0),
46
47
    // Whether node is in standby mode due to PCMK_META_ON_FAIL
48
    pcmk__node_fail_standby     = (UINT32_C(1) << 1),
49
50
    // Whether node has ever joined cluster (and thus has node state in CIB)
51
    pcmk__node_seen             = (UINT32_C(1) << 2),
52
53
    // Whether expected join state is member
54
    pcmk__node_expected_up      = (UINT32_C(1) << 3),
55
56
    // Whether probes are allowed on node
57
    pcmk__node_probes_allowed   = (UINT32_C(1) << 4),
58
59
    /* Whether this either is a guest node whose guest resource must be
60
     * recovered or a remote node that must be fenced
61
     */
62
    pcmk__node_remote_reset     = (UINT32_C(1) << 5),
63
64
    /* Whether this is a Pacemaker Remote node that was fenced since it was last
65
     * connected by the cluster
66
     */
67
    pcmk__node_remote_fenced    = (UINT32_C(1) << 6),
68
69
    /*
70
     * Whether this is a Pacemaker Remote node previously marked in its
71
     * node state as being in maintenance mode
72
     */
73
    pcmk__node_remote_maint     = (UINT32_C(1) << 7),
74
75
    // Whether node history has been unpacked
76
    pcmk__node_unpacked         = (UINT32_C(1) << 8),
77
};
78
79
// When to probe a resource on a node (as specified in location constraints)
80
enum pcmk__probe_mode {
81
    pcmk__probe_always       = 0,   // Always probe resource on node
82
    pcmk__probe_never        = 1,   // Never probe resource on node
83
    pcmk__probe_exclusive    = 2,   // Probe only on designated nodes
84
};
85
86
/* Per-node data used in resource assignment
87
 *
88
 * @COMPAT When we can make the pcmk_node_t implementation internal, move these
89
 * there and drop this struct.
90
 */
91
struct pcmk__node_assignment {
92
    int score;      // Node's score for relevant resource
93
    int count;      // Counter reused by assignment and promotion code
94
    enum pcmk__probe_mode probe_mode;   // When to probe resource on this node
95
};
96
97
/* Implementation of pcmk__node_private_t (pcmk_node_t objects are shallow
98
 * copies, so all pcmk_node_t objects for the same node will share the same
99
 * private data)
100
 */
101
struct pcmk__node_private {
102
    /* Node's XML ID in the CIB (the cluster layer ID for cluster nodes,
103
     * the node name for Pacemaker Remote nodes)
104
     */
105
    const char *id;
106
107
    /*
108
     * Sum of priorities of all resources active on node and on any guest nodes
109
     * connected to this node, with +1 for promoted instances (used to compare
110
     * nodes for PCMK_OPT_PRIORITY_FENCING_DELAY)
111
     */
112
    int priority;
113
114
    const char *name;                   // Node name in cluster
115
    enum pcmk__node_variant variant;    // Node variant
116
    uint32_t flags;                     // Group of enum pcmk__node_flags
117
    GHashTable *attrs;                  // Node attributes
118
    GHashTable *utilization;            // Node utilization attributes
119
    int num_resources;                  // Number of active resources on node
120
    GList *assigned_resources;          // List of resources assigned to node
121
    GHashTable *digest_cache;           // Cache of calculated resource digests
122
    pcmk_resource_t *remote;            // Pacemaker Remote connection (if any)
123
    pcmk_scheduler_t *scheduler;        // Scheduler data that node is part of
124
};
125
126
void pcmk__free_node_copy(void *data);
127
pcmk_node_t *pcmk__find_node_in_list(const GList *nodes, const char *node_name);
128
129
/*!
130
 * \internal
131
 * \brief Set node flags
132
 *
133
 * \param[in,out] node          Node to set flags for
134
 * \param[in]     flags_to_set  Group of enum pcmk_node_flags to set
135
 */
136
#define pcmk__set_node_flags(node, flags_to_set) do {                   \
137
        (node)->priv->flags = pcmk__set_flags_as(__func__, __LINE__,    \
138
            LOG_TRACE, "Node", pcmk__node_name(node),                   \
139
            (node)->priv->flags, (flags_to_set), #flags_to_set);        \
140
    } while (0)
141
142
/*!
143
 * \internal
144
 * \brief Clear node flags
145
 *
146
 * \param[in,out] node            Node to clear flags for
147
 * \param[in]     flags_to_clear  Group of enum pcmk_node_flags to clear
148
 */
149
#define pcmk__clear_node_flags(node, flags_to_clear) do {                   \
150
        (node)->priv->flags = pcmk__clear_flags_as(__func__, __LINE__,      \
151
            LOG_TRACE, "Node", pcmk__node_name(node),                       \
152
            (node)->priv->flags, (flags_to_clear), #flags_to_clear);        \
153
    } while (0)
154
155
void pcmk__free_node(gpointer user_data);
156
157
/*!
158
 * \internal
159
 * \brief Return a string suitable for logging as a node name
160
 *
161
 * \param[in] node  Node to return a node name string for
162
 *
163
 * \return Node name if available, otherwise node ID if available,
164
 *         otherwise "unspecified node" if node is NULL or "unidentified node"
165
 *         if node has neither a name nor ID.
166
 */
167
static inline const char *
168
pcmk__node_name(const pcmk_node_t *node)
169
0
{
170
0
    if (node == NULL) {
171
0
        return "unspecified node";
172
173
0
    } else if (node->priv->name != NULL) {
174
0
        return node->priv->name;
175
176
0
    } else if (node->priv->id != NULL) {
177
0
        return node->priv->id;
178
179
0
    } else {
180
0
        return "unidentified node";
181
0
    }
182
0
}
Unexecuted instantiation: results.c:pcmk__node_name
Unexecuted instantiation: scores.c:pcmk__node_name
Unexecuted instantiation: strings.c:pcmk__node_name
Unexecuted instantiation: utils.c:pcmk__node_name
Unexecuted instantiation: iso8601.c:pcmk__node_name
Unexecuted instantiation: logging.c:pcmk__node_name
Unexecuted instantiation: mainloop.c:pcmk__node_name
Unexecuted instantiation: options.c:pcmk__node_name
Unexecuted instantiation: output.c:pcmk__node_name
Unexecuted instantiation: output_log.c:pcmk__node_name
Unexecuted instantiation: output_text.c:pcmk__node_name
Unexecuted instantiation: output_xml.c:pcmk__node_name
Unexecuted instantiation: patchset_display.c:pcmk__node_name
Unexecuted instantiation: schemas.c:pcmk__node_name
Unexecuted instantiation: xml.c:pcmk__node_name
Unexecuted instantiation: xml_attr.c:pcmk__node_name
Unexecuted instantiation: xml_comment.c:pcmk__node_name
Unexecuted instantiation: xml_display.c:pcmk__node_name
Unexecuted instantiation: xml_element.c:pcmk__node_name
Unexecuted instantiation: xml_idref.c:pcmk__node_name
Unexecuted instantiation: xml_io.c:pcmk__node_name
Unexecuted instantiation: xpath.c:pcmk__node_name
Unexecuted instantiation: acl.c:pcmk__node_name
Unexecuted instantiation: actions.c:pcmk__node_name
Unexecuted instantiation: agents.c:pcmk__node_name
Unexecuted instantiation: cmdline.c:pcmk__node_name
Unexecuted instantiation: digest.c:pcmk__node_name
Unexecuted instantiation: health.c:pcmk__node_name
Unexecuted instantiation: io.c:pcmk__node_name
Unexecuted instantiation: ipc_client.c:pcmk__node_name
Unexecuted instantiation: ipc_common.c:pcmk__node_name
Unexecuted instantiation: ipc_controld.c:pcmk__node_name
Unexecuted instantiation: ipc_pacemakerd.c:pcmk__node_name
Unexecuted instantiation: ipc_schedulerd.c:pcmk__node_name
Unexecuted instantiation: ipc_server.c:pcmk__node_name
Unexecuted instantiation: messages.c:pcmk__node_name
Unexecuted instantiation: nodes.c:pcmk__node_name
Unexecuted instantiation: nvpair.c:pcmk__node_name
Unexecuted instantiation: options_display.c:pcmk__node_name
Unexecuted instantiation: patchset.c:pcmk__node_name
Unexecuted instantiation: procfs.c:pcmk__node_name
Unexecuted instantiation: rules.c:pcmk__node_name
Unexecuted instantiation: servers.c:pcmk__node_name
Unexecuted instantiation: cib.c:pcmk__node_name
Unexecuted instantiation: ipc_attrd.c:pcmk__node_name
Unexecuted instantiation: pid.c:pcmk__node_name
Unexecuted instantiation: attrs.c:pcmk__node_name
Unexecuted instantiation: strings_fuzzer.c:pcmk__node_name
Unexecuted instantiation: cib_file_fuzzer.c:pcmk__node_name
Unexecuted instantiation: cib_client.c:pcmk__node_name
Unexecuted instantiation: cib_file.c:pcmk__node_name
Unexecuted instantiation: cib_native.c:pcmk__node_name
Unexecuted instantiation: cib_ops.c:pcmk__node_name
Unexecuted instantiation: cib_remote.c:pcmk__node_name
Unexecuted instantiation: cib_utils.c:pcmk__node_name
Unexecuted instantiation: remote.c:pcmk__node_name
Unexecuted instantiation: tls.c:pcmk__node_name
Unexecuted instantiation: watchdog.c:pcmk__node_name
183
184
/*!
185
 * \internal
186
 * \brief Check whether two node objects refer to the same node
187
 *
188
 * \param[in] node1  First node object to compare
189
 * \param[in] node2  Second node object to compare
190
 *
191
 * \return true if \p node1 and \p node2 refer to the same node
192
 */
193
static inline bool
194
pcmk__same_node(const pcmk_node_t *node1, const pcmk_node_t *node2)
195
0
{
196
0
    return (node1 != NULL) && (node2 != NULL)
197
0
           && (node1->priv == node2->priv);
198
0
}
Unexecuted instantiation: results.c:pcmk__same_node
Unexecuted instantiation: scores.c:pcmk__same_node
Unexecuted instantiation: strings.c:pcmk__same_node
Unexecuted instantiation: utils.c:pcmk__same_node
Unexecuted instantiation: iso8601.c:pcmk__same_node
Unexecuted instantiation: logging.c:pcmk__same_node
Unexecuted instantiation: mainloop.c:pcmk__same_node
Unexecuted instantiation: options.c:pcmk__same_node
Unexecuted instantiation: output.c:pcmk__same_node
Unexecuted instantiation: output_log.c:pcmk__same_node
Unexecuted instantiation: output_text.c:pcmk__same_node
Unexecuted instantiation: output_xml.c:pcmk__same_node
Unexecuted instantiation: patchset_display.c:pcmk__same_node
Unexecuted instantiation: schemas.c:pcmk__same_node
Unexecuted instantiation: xml.c:pcmk__same_node
Unexecuted instantiation: xml_attr.c:pcmk__same_node
Unexecuted instantiation: xml_comment.c:pcmk__same_node
Unexecuted instantiation: xml_display.c:pcmk__same_node
Unexecuted instantiation: xml_element.c:pcmk__same_node
Unexecuted instantiation: xml_idref.c:pcmk__same_node
Unexecuted instantiation: xml_io.c:pcmk__same_node
Unexecuted instantiation: xpath.c:pcmk__same_node
Unexecuted instantiation: acl.c:pcmk__same_node
Unexecuted instantiation: actions.c:pcmk__same_node
Unexecuted instantiation: agents.c:pcmk__same_node
Unexecuted instantiation: cmdline.c:pcmk__same_node
Unexecuted instantiation: digest.c:pcmk__same_node
Unexecuted instantiation: health.c:pcmk__same_node
Unexecuted instantiation: io.c:pcmk__same_node
Unexecuted instantiation: ipc_client.c:pcmk__same_node
Unexecuted instantiation: ipc_common.c:pcmk__same_node
Unexecuted instantiation: ipc_controld.c:pcmk__same_node
Unexecuted instantiation: ipc_pacemakerd.c:pcmk__same_node
Unexecuted instantiation: ipc_schedulerd.c:pcmk__same_node
Unexecuted instantiation: ipc_server.c:pcmk__same_node
Unexecuted instantiation: messages.c:pcmk__same_node
Unexecuted instantiation: nodes.c:pcmk__same_node
Unexecuted instantiation: nvpair.c:pcmk__same_node
Unexecuted instantiation: options_display.c:pcmk__same_node
Unexecuted instantiation: patchset.c:pcmk__same_node
Unexecuted instantiation: procfs.c:pcmk__same_node
Unexecuted instantiation: rules.c:pcmk__same_node
Unexecuted instantiation: servers.c:pcmk__same_node
Unexecuted instantiation: cib.c:pcmk__same_node
Unexecuted instantiation: ipc_attrd.c:pcmk__same_node
Unexecuted instantiation: pid.c:pcmk__same_node
Unexecuted instantiation: attrs.c:pcmk__same_node
Unexecuted instantiation: strings_fuzzer.c:pcmk__same_node
Unexecuted instantiation: cib_file_fuzzer.c:pcmk__same_node
Unexecuted instantiation: cib_client.c:pcmk__same_node
Unexecuted instantiation: cib_file.c:pcmk__same_node
Unexecuted instantiation: cib_native.c:pcmk__same_node
Unexecuted instantiation: cib_ops.c:pcmk__same_node
Unexecuted instantiation: cib_remote.c:pcmk__same_node
Unexecuted instantiation: cib_utils.c:pcmk__same_node
Unexecuted instantiation: remote.c:pcmk__same_node
Unexecuted instantiation: tls.c:pcmk__same_node
Unexecuted instantiation: watchdog.c:pcmk__same_node
199
200
#ifdef __cplusplus
201
}
202
#endif
203
204
#endif  // PCMK__CRM_COMMON_NODES_INTERNAL__H