Coverage Report

Created: 2026-03-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pacemaker/lib/common/servers.c
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
#include <crm_internal.h>
11
12
#include <stdio.h>      // NULL
13
14
#include <crm/crm.h>
15
16
/* Each Pacemaker subdaemon offers an IPC interface, and most exchange cluster
17
 * messages as well. Particular names need to be used for logging, connecting
18
 * IPC, and IPC/cluster message types.
19
 *
20
 * This array is indexed by enum pcmk_ipc_server and gathers all those names for
21
 * easier mapping. Most members are lists with the first value listed being the
22
 * "main" one returned if another value is mapped to it.
23
 *
24
 * @COMPAT Ideally, we'd use a single string (such as the server's
25
 * crm_system_name) as the sole IPC name and sole message type for each server,
26
 * making most of this unnecessary. However, backward compatiblity with older
27
 * nodes involved in a rolling upgrade or Pacemaker Remote connection would
28
 * be a nightmare: we'd have to add duplicate message attributes, struct
29
 * members, and libqb IPC server endpoints for both the old and new names, and
30
 * could drop the old names only after we no longer supported connections with
31
 * older nodes.
32
 */
33
static struct {
34
    const char *log_name;         // Readable server name for use in logs
35
    const char *system_names[2];  // crm_system_name values (subdaemon names)
36
    const char *ipc_names[3];     // libqb IPC names used to contact server
37
    const char *message_types[3]; // IPC/cluster message types sent to server
38
} server_info[] = {
39
    [pcmk_ipc_unknown] = {
40
        NULL,
41
        { NULL, NULL, },
42
        { NULL, NULL, NULL, },
43
        { NULL, NULL, NULL, },
44
    },
45
46
    [pcmk_ipc_attrd] = {
47
        "attribute manager",
48
        { PCMK__SERVER_ATTRD, NULL, },
49
        { PCMK__VALUE_ATTRD, NULL, NULL, },
50
        { PCMK__VALUE_ATTRD, NULL, NULL, },
51
    },
52
53
    [pcmk_ipc_based] = {
54
        "CIB manager",
55
        { PCMK__SERVER_BASED, NULL, },
56
        { PCMK__SERVER_BASED_RW, PCMK__SERVER_BASED_RO,
57
          PCMK__SERVER_BASED_SHM, },
58
        { CRM_SYSTEM_CIB, NULL, NULL, },
59
    },
60
61
    [pcmk_ipc_controld] = {
62
        "controller",
63
        { PCMK__SERVER_CONTROLD, NULL, },
64
        { PCMK__VALUE_CRMD, NULL, NULL, },
65
        { PCMK__VALUE_CRMD, CRM_SYSTEM_DC, CRM_SYSTEM_TENGINE, },
66
    },
67
68
    [pcmk_ipc_execd] = {
69
        "executor",
70
        { PCMK__SERVER_EXECD, PCMK__SERVER_REMOTED, },
71
        { PCMK__VALUE_LRMD, NULL, NULL, },
72
        { PCMK__VALUE_LRMD, NULL, NULL, },
73
    },
74
75
    [pcmk_ipc_fenced] = {
76
        "fencer",
77
        { PCMK__SERVER_FENCED, NULL, },
78
        { PCMK__VALUE_STONITH_NG, NULL, NULL, },
79
        { PCMK__VALUE_STONITH_NG, NULL, NULL, },
80
    },
81
82
    [pcmk_ipc_pacemakerd] = {
83
        "launcher",
84
        { PCMK__SERVER_PACEMAKERD, NULL, },
85
        { CRM_SYSTEM_MCP, NULL, NULL, },
86
        { CRM_SYSTEM_MCP, NULL, NULL, },
87
    },
88
89
    [pcmk_ipc_schedulerd] = {
90
        "scheduler",
91
        { PCMK__SERVER_SCHEDULERD, NULL, },
92
        { CRM_SYSTEM_PENGINE, NULL, NULL, },
93
        { CRM_SYSTEM_PENGINE, NULL, NULL, },
94
    },
95
};
96
97
/*!
98
 * \internal
99
 * \brief Return server's (primary) system name
100
 *
101
 * \param[in] server  Server to get system name for
102
 *
103
 * \return System name for server (or NULL if invalid)
104
 * \note If \p server is an \c enum pcmk_ipc_server value other than
105
 *       \c pcmk_ipc_unknown, the return value is guaranteed to be non-NULL.
106
 */
107
const char *
108
pcmk__server_name(enum pcmk_ipc_server server)
109
0
{
110
0
    CRM_CHECK((server > 0) && (server < PCMK__NELEM(server_info)),
111
0
              return NULL);
112
0
    return server_info[server].system_names[0];
113
0
}
114
115
/*!
116
 * \internal
117
 * \brief Return a readable description of server for logging
118
 *
119
 * \param[in] server  Server to get log name for
120
 *
121
 * \return Log name for server (or NULL if invalid)
122
 * \note If \p server is an \c enum pcmk_ipc_server value other than
123
 *       \c pcmk_ipc_unknown, the return value is guaranteed to be non-NULL.
124
 */
125
const char *
126
pcmk__server_log_name(enum pcmk_ipc_server server)
127
0
{
128
0
    CRM_CHECK((server > 0) && (server < PCMK__NELEM(server_info)),
129
0
              return NULL);
130
0
    return server_info[server].log_name;
131
0
}
132
133
/*!
134
 * \internal
135
 * \brief Return the (primary) IPC endpoint name for a server
136
 *
137
 * \param[in] server  Server to get IPC endpoint for
138
 *
139
 * \return IPC endpoint for server (or NULL if invalid)
140
 * \note If \p server is an \c enum pcmk_ipc_server value other than
141
 *       \c pcmk_ipc_unknown, the return value is guaranteed to be non-NULL.
142
 */
143
const char *
144
pcmk__server_ipc_name(enum pcmk_ipc_server server)
145
0
{
146
0
    CRM_CHECK((server > 0) && (server < PCMK__NELEM(server_info)),
147
0
              return NULL);
148
0
    return server_info[server].ipc_names[0];
149
0
}
150
151
/*!
152
 * \internal
153
 * \brief Return the (primary) message type for a server
154
 *
155
 * \param[in] server  Server to get message type for
156
 *
157
 * \return Message type for server (or NULL if invalid)
158
 * \note If \p server is an \c enum pcmk_ipc_server value other than
159
 *       \c pcmk_ipc_unknown, the return value is guaranteed to be non-NULL.
160
 */
161
const char *
162
pcmk__server_message_type(enum pcmk_ipc_server server)
163
0
{
164
0
    CRM_CHECK((server > 0) && (server < PCMK__NELEM(server_info)),
165
0
              return NULL);
166
0
    return server_info[server].message_types[0];
167
0
}
168
169
/*!
170
 * \internal
171
 * \brief Get the server corresponding to a name
172
 *
173
 * \param[in] text  A system name, IPC endpoint name, or message type
174
 *
175
 * \return Server corresponding to \p text
176
 */
177
enum pcmk_ipc_server
178
pcmk__parse_server(const char *text)
179
0
{
180
0
    if (text == NULL) {
181
0
        return pcmk_ipc_unknown;
182
0
    }
183
0
    for (enum pcmk_ipc_server server = pcmk_ipc_attrd;
184
0
         server <= pcmk_ipc_schedulerd; ++server) {
185
186
0
        int name;
187
188
0
        for (name = 0;
189
0
             (name < 2) && (server_info[server].system_names[name] != NULL);
190
0
             ++name) {
191
0
            if (strcmp(text, server_info[server].system_names[name]) == 0) {
192
0
                return server;
193
0
            }
194
0
        }
195
0
        for (name = 0;
196
0
             (name < 3) && (server_info[server].ipc_names[name] != NULL);
197
0
             ++name) {
198
0
            if (strcmp(text, server_info[server].ipc_names[name]) == 0) {
199
0
                return server;
200
0
            }
201
0
        }
202
0
        for (name = 0;
203
0
             (name < 3) && (server_info[server].message_types[name] != NULL);
204
0
             ++name) {
205
0
            if (strcmp(text, server_info[server].message_types[name]) == 0) {
206
0
                return server;
207
0
            }
208
0
        }
209
0
    }
210
0
    return pcmk_ipc_unknown;
211
0
}