File: ipc.h

package info (click to toggle)
pacemaker 3.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 68,576 kB
  • sloc: xml: 160,564; ansic: 143,744; python: 5,670; sh: 2,969; makefile: 2,426
file content (220 lines) | stat: -rw-r--r-- 8,486 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*
 * Copyright 2004-2025 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_IPC__H
#define PCMK__CRM_COMMON_IPC__H

#include <stdint.h>
#include <sys/uio.h>
#include <qb/qbipcc.h>
#include <crm/common/xml.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * \file
 * \brief IPC interface to Pacemaker daemons
 *
 * \ingroup core
 */

/*
 * The library supports two methods of creating IPC connections. The older code
 * allows connecting to any arbitrary IPC name. The newer code only allows
 * connecting to one of the Pacemaker daemons.
 *
 * As daemons are converted to use the new model, the old functions should be
 * considered deprecated for use with those daemons. Once all daemons are
 * converted, the old functions should be officially deprecated as public API
 * and eventually made internal API.
 */

/*
 * Pacemaker daemon IPC
 */

/* @COMPAT This is also used internally for cluster message types, but it's not
 * worth the hassle of redefining this public API just to change the name.
 */
//! Available IPC interfaces
enum pcmk_ipc_server {
    pcmk_ipc_unknown,       //!< Unknown or invalid
    pcmk_ipc_attrd,         //!< Attribute manager
    pcmk_ipc_based,         //!< CIB manager
    pcmk_ipc_controld,      //!< Controller
    pcmk_ipc_execd,         //!< Executor
    pcmk_ipc_fenced,        //!< Fencer
    pcmk_ipc_pacemakerd,    //!< Launcher
    pcmk_ipc_schedulerd,    //!< Scheduler
};

// NOTE: sbd (as of at least 1.5.2) uses this enum
//! Possible event types that an IPC event callback can be called for
enum pcmk_ipc_event {
    pcmk_ipc_event_connect,     //!< Result of asynchronous connection attempt

    // NOTE: sbd (as of at least 1.5.2) uses this value
    pcmk_ipc_event_disconnect,  //!< Termination of IPC connection

    // NOTE: sbd (as of at least 1.5.2) uses this value
    pcmk_ipc_event_reply,       //!< Daemon's reply to client IPC request

    pcmk_ipc_event_notify,      //!< Notification from daemon
};

//! How IPC replies should be dispatched
enum pcmk_ipc_dispatch {
    pcmk_ipc_dispatch_main, //!< Attach IPC to GMainLoop for dispatch
    pcmk_ipc_dispatch_poll, //!< Caller will poll and dispatch IPC
    pcmk_ipc_dispatch_sync, //!< Sending a command will wait for any reply
};

// NOTE: sbd (as of at least 1.5.2) uses this
//! Client connection to Pacemaker IPC
typedef struct pcmk_ipc_api_s pcmk_ipc_api_t;

/*!
 * \brief Callback function type for Pacemaker daemon IPC APIs
 *
 * \param[in,out] api         IPC API connection
 * \param[in]     event_type  The type of event that occurred
 * \param[in]     status      Event status
 * \param[in,out] event_data  Event-specific data
 * \param[in,out] user_data   Caller data provided when callback was registered
 *
 * \note For connection and disconnection events, event_data may be NULL (for
 *       local IPC) or the name of the connected node (for remote IPC, for
 *       daemons that support that). For reply and notify events, event_data is
 *       defined by the specific daemon API.
 */
typedef void (*pcmk_ipc_callback_t)(pcmk_ipc_api_t *api,
                                    enum pcmk_ipc_event event_type,
                                    crm_exit_t status,
                                    void *event_data, void *user_data);

// NOTE: sbd (as of at least 1.5.2) uses this
int pcmk_new_ipc_api(pcmk_ipc_api_t **api, enum pcmk_ipc_server server);

// NOTE: sbd (as of at least 1.5.2) uses this
void pcmk_free_ipc_api(pcmk_ipc_api_t *api);

// NOTE: sbd (as of at least 1.5.2) uses this
int pcmk_connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type);

void pcmk_disconnect_ipc(pcmk_ipc_api_t *api);

int pcmk_poll_ipc(const pcmk_ipc_api_t *api, int timeout_ms);

void pcmk_dispatch_ipc(pcmk_ipc_api_t *api);

// NOTE: sbd (as of at least 1.5.2) uses this
void pcmk_register_ipc_callback(pcmk_ipc_api_t *api, pcmk_ipc_callback_t cb,
                                void *user_data);

const char *pcmk_ipc_name(const pcmk_ipc_api_t *api, bool for_log);

bool pcmk_ipc_is_connected(pcmk_ipc_api_t *api);

int pcmk_ipc_purge_node(pcmk_ipc_api_t *api, const char *node_name,
                        uint32_t nodeid);


/*
 * Generic IPC API (to eventually be deprecated as public API and made internal)
 */

enum crm_ipc_flags
{
    crm_ipc_flags_none              = UINT32_C(0),
    //! \deprecated Since 3.0.1
    crm_ipc_compressed              = (UINT32_C(1) << 0),
    //! _ALL_ replies to proxied connections need to be sent as events
    crm_ipc_proxied                 = (UINT32_C(1) << 8),
    //! A response is expected in reply
    crm_ipc_client_response         = (UINT32_C(1) << 9),

    // These are options for Pacemaker's internal use only (pcmk__ipc_send_*())

    //! Send an Event instead of a Response
    crm_ipc_server_event            = (UINT32_C(1) << 16),
    //! Free the iovec after sending
    crm_ipc_server_free             = (UINT32_C(1) << 17),
    //! All replies to proxied connections are sent as events.  This flag
    //! preserves whether the events should be treated as an Event or a Response
    crm_ipc_proxied_relay_response  = (UINT32_C(1) << 18),
    //! This is a multi-part IPC message
    crm_ipc_multipart               = (UINT32_C(1) << 19),
    //! This is the end of a multi-part IPC message
    crm_ipc_multipart_end           = (UINT32_C(1) << 20),
};

typedef struct crm_ipc_s crm_ipc_t;

crm_ipc_t *crm_ipc_new(const char *name, size_t max_size);
void crm_ipc_close(crm_ipc_t * client);
void crm_ipc_destroy(crm_ipc_t * client);
void pcmk_free_ipc_event(struct iovec *event);

int crm_ipc_send(crm_ipc_t *client, const xmlNode *message,
                 enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply);

int crm_ipc_get_fd(crm_ipc_t * client);
bool crm_ipc_connected(crm_ipc_t * client);
int crm_ipc_ready(crm_ipc_t * client);
long crm_ipc_read(crm_ipc_t * client);
const char *crm_ipc_buffer(crm_ipc_t * client);
uint32_t crm_ipc_buffer_flags(crm_ipc_t * client);
const char *crm_ipc_name(crm_ipc_t * client);
unsigned int crm_ipc_default_buffer_size(void);

/*!
 * \brief Check the authenticity of the IPC socket peer process (legacy)
 *
 * If everything goes well, peer's authenticity is verified by the means
 * of comparing against provided referential UID and GID (either satisfies),
 * and the result of this check can be deduced from the return value.
 * As an exception, detected UID of 0 ("root") satisfies arbitrary
 * provided referential daemon's credentials.
 *
 * \param[in]  sock    IPC related, connected Unix socket to check peer of
 * \param[in]  refuid  referential UID to check against
 * \param[in]  refgid  referential GID to check against
 * \param[out] gotpid  to optionally store obtained PID of the peer
 *                     (not available on FreeBSD, special value of 1
 *                     used instead, and the caller is required to
 *                     special case this value respectively)
 * \param[out] gotuid  to optionally store obtained UID of the peer
 * \param[out] gotgid  to optionally store obtained GID of the peer
 *
 * \return 0 if IPC related socket's peer is not authentic given the
 *         referential credentials (see above), 1 if it is,
 *         negative value on error (generally expressing -errno unless
 *         it was zero even on nonhappy path, -pcmk_err_generic is
 *         returned then; no message is directly emitted)
 *
 * \note While this function is tolerant on what constitutes authorized
 *       IPC daemon process (its effective user matches UID=0 or \p refuid,
 *       or at least its group matches \p refgid), either or both (in case
 *       of UID=0) mismatches on the expected credentials of such peer
 *       process \e shall be investigated at the caller when value of 1
 *       gets returned there, since higher-than-expected privileges in
 *       respect to the expected/intended credentials possibly violate
 *       the least privilege principle and may pose an additional risk
 *       (i.e. such accidental inconsistency shall be eventually fixed).
 */
int crm_ipc_is_authentic_process(int sock, uid_t refuid, gid_t refgid,
                                 pid_t *gotpid, uid_t *gotuid, gid_t *gotgid);

#ifdef __cplusplus
}
#endif

#endif