12 #if defined(HAVE_UCRED) || defined(HAVE_SOCKPEERCRED) 18 # include <sys/socket.h> 19 #elif defined(HAVE_GETPEERUCRED) 24 #include <sys/types.h> 34 static int is_ipc_provider_expected(qb_ipcc_connection_t *qb_ipc,
int sock,
35 uid_t refuid, gid_t refgid, pid_t *gotpid,
36 uid_t *gotuid, gid_t *gotgid);
62 (*api)->server = server;
78 (*api)->ipc_size_max = 512 * 1024;
98 (*api)->ipc_size_max = 5 * 1024 * 1024;
101 if ((*api)->cmds == NULL) {
108 (*api)->ipc_size_max);
109 if ((*api)->ipc == NULL) {
116 if ((*api)->cmds->new_data != NULL) {
117 if ((*api)->cmds->new_data(*api) !=
pcmk_rc_ok) {
130 if ((api != NULL) && (api->
cmds != NULL)) {
153 if ((api != NULL) && (api->
cb != NULL)) {
154 api->
cb(api, event_type, status, event_data, api->
user_data);
167 ipc_post_disconnect(gpointer user_data)
194 free_daemon_specific_data(api);
195 crm_trace(
"Freeing IPC API object after disconnect");
208 bool free_on_disconnect =
false;
215 if (api->
ipc != NULL) {
230 if (!free_on_disconnect) {
231 free_daemon_specific_data(api);
250 return for_log?
"Pacemaker" : NULL;
257 return for_log?
"CIB manager" : NULL ;
263 return for_log?
"executor" : NULL ;
266 return for_log?
"fencer" : NULL ;
275 return for_log?
"Pacemaker" : NULL;
335 if (buffer == NULL) {
336 crm_warn(
"Empty message received from %s IPC",
343 crm_warn(
"Malformed message received from %s IPC",
348 more = call_api_dispatch(api, msg);
371 dispatch_ipc_source_data(
const char *buffer, ssize_t length, gpointer user_data)
376 dispatch_ipc_data(buffer, api);
402 struct pollfd pollfd = { 0, };
410 crm_debug(
"Could not obtain file descriptor for %s IPC: %s",
415 pollfd.events = POLLIN;
416 rc = poll(&pollfd, 1, timeout_ms);
421 return (errno == EAGAIN)? ENOMEM : errno;
422 }
else if (rc == 0) {
458 .
dispatch = dispatch_ipc_source_data,
459 .destroy = ipc_post_disconnect,
467 crm_debug(
"Connected to %s IPC (attached to main loop)",
484 crm_debug(
"Connected to %s IPC (without main loop)",
506 if ((api == NULL) || (attempts < 1)) {
510 if (api->
ipc == NULL) {
512 if (api->
ipc == NULL) {
524 crm_debug(
"Attempting connection to %s (up to %d time%s)",
526 for (
int remaining = attempts - 1; remaining >= 0; --remaining) {
527 switch (dispatch_type) {
529 rc = connect_with_main_loop(api);
534 rc = connect_without_main_loop(api);
538 if ((remaining == 0) || ((rc != EAGAIN) && (rc != EALREADY))) {
544 crm_debug(
"Re-attempting connection to %s (%d attempt%s remaining)",
576 crm_err(
"Connection to %s failed: %s",
596 if ((api == NULL) || (api->
ipc == NULL)) {
626 ipc_post_disconnect(api);
671 xmlNode *reply = NULL;
674 if ((api == NULL) || (api->
ipc == NULL) || (request == NULL)) {
681 && (api->
cmds != NULL)
692 }
else if (rc == 0) {
698 bool more = call_api_dispatch(api, reply);
707 }
else if (rc == -ENOMSG || rc ==
pcmk_ok) {
717 }
else if (rc == EINPROGRESS) {
750 create_purge_node_request(
const pcmk_ipc_api_t *api,
const char *node_name,
753 xmlNode *request = NULL;
800 xmlNode *request = NULL;
805 if ((node_name == NULL) && (nodeid == 0)) {
809 request = create_purge_node_request(api, node_name, nodeid);
810 if (request == NULL) {
816 crm_debug(
"%s peer cache purge of node %s[%lu]: rc=%d",
817 pcmk_ipc_name(api,
true), node_name, (
unsigned long) nodeid, rc);
827 unsigned int max_buf_size;
828 unsigned int buf_size;
833 qb_ipcc_connection_t *ipc;
855 if (client == NULL) {
856 crm_err(
"Could not create IPC connection: %s", strerror(errno));
860 client->server_name = strdup(
name);
861 if (client->server_name == NULL) {
862 crm_err(
"Could not create %s IPC connection: %s",
863 name, strerror(errno));
868 client->buffer = malloc(client->buf_size);
869 if (client->buffer == NULL) {
870 crm_err(
"Could not create %s IPC connection: %s",
871 name, strerror(errno));
872 free(client->server_name);
878 client->max_buf_size = client->buf_size;
881 client->pfd.events = POLLIN;
882 client->pfd.revents = 0;
909 ipc->need_reply = FALSE;
910 ipc->ipc = qb_ipcc_connect(ipc->server_name, ipc->buf_size);
911 if (ipc->ipc == NULL) {
915 rc = qb_ipcc_fd_get(ipc->ipc, &ipc->pfd.fd);
928 rc = is_ipc_provider_expected(ipc->ipc, ipc->pfd.fd, cl_uid, cl_gid,
929 &found_pid, &found_uid, &found_gid);
932 crm_info(
"%s IPC provider authentication failed: process %lld has " 933 "uid %lld (expected %lld) and gid %lld (expected %lld)",
936 (
long long) found_uid, (
long long) cl_uid,
937 (
long long) found_gid, (
long long) cl_gid);
943 ipc->max_buf_size = qb_ipcc_get_buffer_size(ipc->ipc);
944 if (ipc->max_buf_size > ipc->buf_size) {
946 ipc->buffer = calloc(ipc->max_buf_size,
sizeof(
char));
947 if (ipc->buffer == NULL) {
952 ipc->buf_size = ipc->max_buf_size;
975 if ((client != NULL) && (client->ipc == NULL)) {
976 errno = (rc > 0)? rc : ENOTCONN;
977 crm_debug(
"Could not establish %s IPC connection: %s (%d)",
980 crm_err(
"%s IPC provider authentication failed",
981 (client == NULL)?
"Pacemaker" : client->server_name);
982 errno = ECONNABORTED;
985 "Could not verify authenticity of %s IPC provider",
986 (client == NULL)?
"Pacemaker" : client->server_name);
997 qb_ipcc_connection_t *ipc = client->ipc;
1000 qb_ipcc_disconnect(ipc);
1009 if (client->ipc && qb_ipcc_is_connected(client->ipc)) {
1010 crm_notice(
"Destroying active %s IPC connection",
1011 client->server_name);
1022 crm_trace(
"Destroying inactive %s IPC connection",
1023 client->server_name);
1025 free(client->buffer);
1026 free(client->server_name);
1043 if ((ipc == NULL) || (fd == NULL)) {
1046 if ((ipc->ipc == NULL) || (ipc->pfd.fd < 0)) {
1059 crm_err(
"Could not obtain file descriptor for %s IPC",
1060 ((client == NULL)?
"unspecified" : client->server_name));
1072 if (client == NULL) {
1076 }
else if (client->ipc == NULL) {
1080 }
else if (client->pfd.fd < 0) {
1085 rc = qb_ipcc_is_connected(client->ipc);
1087 client->pfd.fd = -EINVAL;
1110 client->pfd.revents = 0;
1111 rc = poll(&(client->pfd), 1, 0);
1112 return (rc < 0)? -errno : rc;
1125 unsigned int new_buf_size = QB_MAX((
sizeof(
pcmk__ipc_header_t) + size_u), client->max_buf_size);
1128 crm_trace(
"Decompressing message data %u bytes into %u bytes",
1155 free(client->buffer);
1156 client->buf_size = new_buf_size;
1157 client->buffer = uncompressed;
1173 client->buffer[0] = 0;
1174 client->msg_size = qb_ipcc_event_recv(client->ipc, client->buffer,
1175 client->buf_size, 0);
1176 if (client->msg_size >= 0) {
1177 int rc = crm_ipc_decompress(client);
1188 crm_trace(
"Received %s IPC event %d size=%u rc=%d text='%.100s'",
1189 client->server_name, header->
qb.id, header->
qb.size,
1194 crm_trace(
"No message received from %s IPC: %s",
1197 if (client->msg_size == -EAGAIN) {
1203 crm_err(
"Connection to %s IPC failed", client->server_name);
1226 if (client->buffer == NULL) {
1231 return header->
flags;
1238 return client->server_name;
1243 internal_ipc_get_reply(
crm_ipc_t *client,
int request_id,
int ms_timeout,
1246 time_t
timeout = time(NULL) + 1 + (ms_timeout / 1000);
1250 crm_trace(
"Waiting on reply to %s IPC message %d",
1251 client->server_name, request_id);
1254 *bytes = qb_ipcc_recv(client->ipc, client->buffer, client->buf_size, 1000);
1258 rc = crm_ipc_decompress(client);
1264 if (hdr->
qb.id == request_id) {
1267 }
else if (hdr->
qb.id < request_id) {
1270 crm_err(
"Discarding old reply %d (need %d)", hdr->
qb.id, request_id);
1276 crm_err(
"Discarding newer reply %d (need %d)", hdr->
qb.id, request_id);
1281 crm_err(
"%s IPC provider disconnected while waiting for message %d",
1282 client->server_name, request_id);
1286 }
while (time(NULL) <
timeout);
1315 static uint32_t
id = 0;
1316 static int factor = 8;
1319 if (client == NULL) {
1320 crm_notice(
"Can't send IPC request without connection (bug?): %.100s",
1326 crm_notice(
"Can't send %s IPC requests: Connection closed",
1327 client->server_name);
1331 if (ms_timeout == 0) {
1335 if (client->need_reply) {
1336 qb_rc = qb_ipcc_recv(client->ipc, client->buffer, client->buf_size, ms_timeout);
1338 crm_warn(
"Sending %s IPC disabled until pending reply received",
1339 client->server_name);
1343 crm_notice(
"Sending %s IPC re-enabled after pending reply received",
1344 client->server_name);
1345 client->need_reply = FALSE;
1358 header = iov[0].iov_base;
1367 if(factor < 10 && (client->max_buf_size / 10) < (bytes / factor)) {
1368 crm_notice(
"Compressed message exceeds %d0%% of configured IPC " 1369 "limit (%u bytes); consider setting PCMK_ipc_buffer to " 1371 factor, client->max_buf_size, 2 * client->max_buf_size);
1376 crm_trace(
"Sending %s IPC request %d of %u bytes using %dms timeout",
1377 client->server_name, header->
qb.id, header->
qb.size, ms_timeout);
1381 time_t
timeout = time(NULL) + 1 + (ms_timeout / 1000);
1391 qb_rc = qb_ipcc_sendv(client->ipc, iov, 2);
1392 }
while ((qb_rc == -EAGAIN) && (time(NULL) <
timeout));
1399 crm_trace(
"Not waiting for reply to %s IPC request %d",
1400 client->server_name, header->
qb.id);
1404 rc = internal_ipc_get_reply(client, header->
qb.id, ms_timeout, &bytes);
1412 client->need_reply = TRUE;
1419 qb_rc = qb_ipcc_sendv_recv(client->ipc, iov, 2, client->buffer,
1420 client->buf_size, -1);
1428 crm_trace(
"Received %d-byte reply %d to %s IPC %d: %.100s",
1429 rc, hdr->
qb.id, client->server_name, header->
qb.id,
1437 crm_trace(
"No reply to %s IPC %d: rc=%d",
1438 client->server_name, header->
qb.id, rc);
1443 crm_notice(
"Couldn't send %s IPC request %d: Connection closed " 1444 CRM_XS " rc=%d", client->server_name, header->
qb.id, rc);
1446 }
else if (rc == -ETIMEDOUT) {
1447 crm_warn(
"%s IPC request %d failed: %s after %dms " CRM_XS " rc=%d",
1452 }
else if (rc <= 0) {
1454 client->server_name, header->
qb.id,
1480 is_ipc_provider_expected(qb_ipcc_connection_t *qb_ipc,
int sock,
1481 uid_t refuid, gid_t refgid,
1482 pid_t *gotpid, uid_t *gotuid, gid_t *gotgid)
1484 int rc = EOPNOTSUPP;
1485 pid_t found_pid = 0;
1486 uid_t found_uid = 0;
1487 gid_t found_gid = 0;
1489 #ifdef HAVE_QB_IPCC_AUTH_GET 1490 if (qb_ipc != NULL) {
1491 rc = qb_ipcc_auth_get(qb_ipc, &found_pid, &found_uid, &found_gid);
1502 socklen_t ucred_len =
sizeof(ucred);
1504 if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len) < 0) {
1506 }
else if (ucred_len !=
sizeof(ucred)) {
1509 found_pid = ucred.pid;
1510 found_uid = ucred.uid;
1511 found_gid = ucred.gid;
1517 #ifdef HAVE_SOCKPEERCRED 1519 struct sockpeercred sockpeercred;
1520 socklen_t sockpeercred_len =
sizeof(sockpeercred);
1522 if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED,
1523 &sockpeercred, &sockpeercred_len) < 0) {
1525 }
else if (sockpeercred_len !=
sizeof(sockpeercred)) {
1528 found_pid = sockpeercred.pid;
1529 found_uid = sockpeercred.uid;
1530 found_gid = sockpeercred.gid;
1536 #ifdef HAVE_GETPEEREID // For example, FreeBSD 1537 if (getpeereid(sock, &found_uid, &found_gid) < 0) {
1545 #ifdef HAVE_GETPEERUCRED 1547 ucred_t *ucred = NULL;
1549 if (getpeerucred(sock, &ucred) < 0) {
1552 found_pid = ucred_getpid(ucred);
1553 found_uid = ucred_geteuid(ucred);
1554 found_gid = ucred_getegid(ucred);
1564 if (gotpid != NULL) {
1565 *gotpid = found_pid;
1567 if (gotuid != NULL) {
1568 *gotuid = found_uid;
1570 if (gotgid != NULL) {
1571 *gotgid = found_gid;
1573 if ((found_uid != 0) && (found_uid != refuid) && (found_gid != refgid)) {
1581 pid_t *gotpid, uid_t *gotuid, gid_t *gotgid)
1583 int ret = is_ipc_provider_expected(NULL, sock, refuid, refgid,
1584 gotpid, gotuid, gotgid);
1598 gid_t refgid, pid_t *gotpid)
1600 static char last_asked_name[PATH_MAX / 2] =
"";
1605 pid_t found_pid = 0; uid_t found_uid = 0; gid_t found_gid = 0;
1606 qb_ipcc_connection_t *c;
1607 #ifdef HAVE_QB_IPCC_CONNECT_ASYNC 1608 struct pollfd pollfd = { 0, };
1611 c = qb_ipcc_connect_async(
name, 0,
1614 c = qb_ipcc_connect(
name, 0);
1617 crm_info(
"Could not connect to %s IPC: %s",
name, strerror(errno));
1621 #ifdef HAVE_QB_IPCC_CONNECT_ASYNC 1622 pollfd.events = POLLIN;
1624 poll_rc = poll(&pollfd, 1, 2000);
1625 }
while ((poll_rc == -1) && (errno == EINTR));
1632 if (qb_ipcc_connect_continue(c) != 0) {
1634 (poll_rc == 0)?
"timeout":strerror(errno));
1641 qb_rc = qb_ipcc_fd_get(c, &fd);
1644 crm_err(
"Could not get fd from %s IPC: %s " CRM_XS " rc=%d",
1649 auth_rc = is_ipc_provider_expected(c, fd, refuid, refgid,
1650 &found_pid, &found_uid, &found_gid);
1652 crm_err(
"Daemon (IPC %s) effectively blocked with unauthorized" 1653 " process %lld (uid: %lld, gid: %lld)",
1655 (
long long) found_uid, (
long long) found_gid);
1662 crm_err(
"Could not get peer credentials from %s IPC: %s " 1667 if (gotpid != NULL) {
1668 *gotpid = found_pid;
1672 if ((found_uid != refuid || found_gid != refgid)
1673 && strncmp(last_asked_name,
name,
sizeof(last_asked_name))) {
1674 if ((found_uid == 0) && (refuid != 0)) {
1675 crm_warn(
"Daemon (IPC %s) runs as root, whereas the expected" 1676 " credentials are %lld:%lld, hazard of violating" 1677 " the least privilege principle",
1678 name, (
long long) refuid, (
long long) refgid);
1680 crm_notice(
"Daemon (IPC %s) runs as %lld:%lld, whereas the" 1681 " expected credentials are %lld:%lld, which may" 1682 " mean a different set of privileges than expected",
1683 name, (
long long) found_uid, (
long long) found_gid,
1684 (
long long) refuid, (
long long) refgid);
1686 memccpy(last_asked_name,
name,
'\0',
sizeof(last_asked_name));
1691 qb_ipcc_disconnect(c);
#define CRM_CHECK(expr, failure_action)
int pcmk__ipc_fd(crm_ipc_t *ipc, int *fd)
#define crm_notice(fmt, args...)
const char * pcmk_strerror(int rc)
enum pcmk_ipc_dispatch dispatch_type
#define PCMK__ATTRD_CMD_PEER_REMOVE
int pcmk__send_ipc_request(pcmk_ipc_api_t *api, const xmlNode *request)
int pcmk_rc2legacy(int rc)
long crm_ipc_read(crm_ipc_t *client)
#define PCMK__VALUE_ATTRD
void pcmk_free_ipc_api(pcmk_ipc_api_t *api)
Free the contents of an IPC API object.
G_GNUC_INTERNAL pcmk__ipc_methods_t * pcmk__schedulerd_api_methods(void)
G_GNUC_INTERNAL pcmk__ipc_methods_t * pcmk__pacemakerd_api_methods(void)
const char * crm_ipc_buffer(crm_ipc_t *client)
int pcmk_ipc_purge_node(pcmk_ipc_api_t *api, const char *node_name, uint32_t nodeid)
Ask a Pacemaker daemon to purge a node from its peer cache.
struct mainloop_io_s mainloop_io_t
#define PCMK__SPECIAL_PID_AS_0(p)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
int pcmk_new_ipc_api(pcmk_ipc_api_t **api, enum pcmk_ipc_server server)
Create a new object for using Pacemaker daemon IPC.
#define PCMK__SPECIAL_PID
void pcmk__xe_set_bool_attr(xmlNodePtr node, const char *name, bool value)
int pcmk__ipc_prepare_iov(uint32_t request, const xmlNode *message, uint32_t max_send_size, struct iovec **result, ssize_t *bytes)
enum crm_exit_e crm_exit_t
void crm_ipc_destroy(crm_ipc_t *client)
int pcmk_poll_ipc(const pcmk_ipc_api_t *api, int timeout_ms)
Check whether an IPC connection has data available (without main loop)
#define CRM_LOG_ASSERT(expr)
int pcmk_daemon_user(uid_t *uid, gid_t *gid)
Get user and group IDs of pacemaker daemon user.
struct pcmk__ipc_header_s pcmk__ipc_header_t
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
int crm_ipc_get_fd(crm_ipc_t *client)
int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid, gid_t refgid, pid_t *gotpid)
Caller will poll and dispatch IPC.
#define crm_warn(fmt, args...)
pcmk_ipc_server
Available IPC interfaces.
void pcmk__sleep_ms(unsigned int ms)
#define crm_debug(fmt, args...)
bool crm_ipc_connect(crm_ipc_t *client)
Establish an IPC connection to a Pacemaker component.
crm_ipc_t * crm_ipc_new(const char *name, size_t max_size)
Create a new (legacy) object for using Pacemaker daemon IPC.
struct crm_ipc_s crm_ipc_t
void pcmk_register_ipc_callback(pcmk_ipc_api_t *api, pcmk_ipc_callback_t cb, void *user_data)
Register a callback for IPC API events.
G_GNUC_INTERNAL pcmk__ipc_methods_t * pcmk__attrd_api_methods(void)
#define crm_trace(fmt, args...)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
void pcmk__call_ipc_callback(pcmk_ipc_api_t *api, enum pcmk_ipc_event event_type, crm_exit_t status, void *event_data)
uint32_t crm_ipc_buffer_flags(crm_ipc_t *client)
#define CRM_SYSTEM_PENGINE
#define pcmk__clear_ipc_flags(ipc_flags, ipc_name, flags_to_clear)
Wrappers for and extensions to libxml2.
void pcmk_disconnect_ipc(pcmk_ipc_api_t *api)
Disconnect an IPC API instance.
G_GNUC_INTERNAL bool pcmk__valid_ipc_header(const pcmk__ipc_header_t *header)
const char * pcmk_ipc_name(const pcmk_ipc_api_t *api, bool for_log)
Get the IPC name used with an IPC API connection.
void crm_ipc_close(crm_ipc_t *client)
void mainloop_del_ipc_client(mainloop_io_t *client)
int pcmk_legacy2rc(int legacy_rc)
void free_xml(xmlNode *child)
void pcmk_free_ipc_event(struct iovec *event)
Free an I/O vector created by pcmk__ipc_prepare_iov()
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)
Callback function type for Pacemaker daemon IPC APIs.
int(* post_connect)(pcmk_ipc_api_t *api)
int pcmk__add_mainloop_ipc(crm_ipc_t *ipc, int priority, void *userdata, const struct ipc_client_callbacks *callbacks, mainloop_io_t **source)
Connect to IPC and add it as a main loop source.
xmlNode * pcmk__xml_parse(const char *input)
void crm_write_blackbox(int nsig, const struct qb_log_callsite *callsite)
G_GNUC_INTERNAL unsigned int pcmk__ipc_buffer_size(unsigned int max)
int pcmk__connect_generic_ipc(crm_ipc_t *ipc)
const char * crm_xml_add_ll(xmlNode *node, const char *name, long long value)
Create an XML attribute with specified name and long long int value.
#define CRM_OP_RM_NODE_CACHE
pcmk_ipc_dispatch
How IPC replies should be dispatched.
int pcmk__bzlib2rc(int bz2)
Map a bz2 return code to the most similar Pacemaker return code.
pcmk_ipc_event
Possible event types that an IPC event callback can be called for.
bool crm_ipc_connected(crm_ipc_t *client)
Attach IPC to GMainLoop for dispatch.
Termination of IPC connection.
mainloop_io_t * mainloop_io
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
bool(* dispatch)(pcmk_ipc_api_t *api, xmlNode *msg)
bool(* reply_expected)(pcmk_ipc_api_t *api, const xmlNode *request)
#define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set)
#define crm_err(fmt, args...)
Sending a command will wait for any reply.
void pcmk_dispatch_ipc(pcmk_ipc_api_t *api)
Dispatch available messages on an IPC connection (without main loop)
#define crm_log_xml_notice(xml, text)
Lost connection to something.
int crm_ipc_ready(crm_ipc_t *client)
Check whether an IPC connection is ready to be read.
void(* free_data)(void *api_data)
#define pcmk__plural_s(i)
bool pcmk_ipc_is_connected(pcmk_ipc_api_t *api)
Check whether an IPC API connection is active.
IPC interface to Pacemaker daemons.
int pcmk__connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type, int attempts)
int pcmk_connect_ipc(pcmk_ipc_api_t *api, enum pcmk_ipc_dispatch dispatch_type)
Connect to a Pacemaker daemon via IPC.
#define crm_log_xml_trace(xml, text)
G_GNUC_INTERNAL pcmk__ipc_methods_t * pcmk__controld_api_methods(void)
pcmk__ipc_methods_t * cmds
int crm_ipc_send(crm_ipc_t *client, const xmlNode *message, enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply)
Send an IPC XML message.
void pcmk__xe_add_node(xmlNode *xml, const char *node, int nodeid)
void(* post_disconnect)(pcmk_ipc_api_t *api)
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
enum pcmk_ipc_server server
#define pcmk__assert_alloc(nmemb, size)
#define create_request(task, xml_data, host_to, sys_to, sys_from, uuid_from)
#define crm_info(fmt, args...)
int(* dispatch)(const char *buffer, ssize_t length, gpointer userdata)
Dispatch function for an IPC connection used as mainloop source.
int crm_ipc_is_authentic_process(int sock, uid_t refuid, gid_t refgid, pid_t *gotpid, uid_t *gotuid, gid_t *gotgid)
Check the authenticity of the IPC socket peer process (legacy)
const char * crm_ipc_name(crm_ipc_t *client)