12 #if defined(US_AUTH_PEERCRED_UCRED) || defined(US_AUTH_PEERCRED_SOCKPEERCRED) 13 # ifdef US_AUTH_PEERCRED_UCRED 18 # include <sys/socket.h> 19 #elif defined(US_AUTH_GETPEERUCRED) 23 #include <sys/param.h> 26 #include <sys/types.h> 42 #define PCMK_IPC_VERSION 1 45 #define PCMK_IPC_DEFAULT_QUEUE_MAX 500 47 struct crm_ipc_response_header {
48 struct qb_ipc_response_header qb;
55 static int hdr_offset = 0;
56 static unsigned int ipc_buffer_max = 0;
57 static unsigned int pick_ipc_buffer(
unsigned int max);
62 if (hdr_offset == 0) {
63 hdr_offset =
sizeof(
struct crm_ipc_response_header);
65 if (ipc_buffer_max == 0) {
66 ipc_buffer_max = pick_ipc_buffer(0);
73 return pick_ipc_buffer(0);
77 generateReference(
const char *custom1,
const char *custom2)
79 static uint ref_counter = 0;
80 const char *local_cust1 = custom1;
81 const char *local_cust2 = custom2;
82 int reference_len = 4;
83 char *since_epoch = NULL;
88 if (local_cust1 == NULL) {
89 local_cust1 =
"_empty_";
91 reference_len += strlen(local_cust1);
93 if (local_cust2 == NULL) {
94 local_cust2 =
"_empty_";
96 reference_len += strlen(local_cust2);
98 since_epoch = calloc(1, reference_len);
100 if (since_epoch != NULL) {
101 sprintf(since_epoch,
"%s-%s-%lu-%u",
102 local_cust1, local_cust2, (
unsigned long)time(NULL), ref_counter++);
110 const char *host_to,
const char *sys_to,
111 const char *sys_from,
const char *uuid_from,
const char *origin)
113 char *true_from = NULL;
114 xmlNode *request = NULL;
115 char *reference = generateReference(task, sys_from);
117 if (uuid_from != NULL) {
119 }
else if (sys_from != NULL) {
120 true_from = strdup(sys_from);
122 crm_err(
"No sys from specified");
137 if (host_to != NULL && strlen(host_to) > 0) {
141 if (msg_data != NULL) {
154 create_reply_adv(xmlNode * original_request, xmlNode * xml_response_data,
const char *origin)
156 xmlNode *reply = NULL;
166 crm_err(
"Cannot create new_message, no message type in original message");
171 crm_err(
"Cannot create new_message, original message was not a request");
177 crm_err(
"Cannot create new_message, malloc failed");
193 if (host_from != NULL && strlen(host_from) > 0) {
197 if (xml_response_data != NULL) {
230 while (g_hash_table_iter_next(&iter, &key, (gpointer *) & client)) {
231 if (strcmp(client->id,
id) == 0) {
237 crm_trace(
"No client found with id=%s",
id);
246 }
else if (c->
name == NULL && c->
id == NULL) {
248 }
else if (c->
name == NULL) {
271 crm_err(
"Exiting with %d active connections", active);
280 qb_ipcs_connection_t *c = NULL;
282 if (service == NULL) {
286 c = qb_ipcs_connection_first_get(service);
289 qb_ipcs_connection_t *last = c;
291 c = qb_ipcs_connection_next_get(service, last);
295 qb_ipcs_disconnect(last);
296 qb_ipcs_connection_unref(last);
311 client_from_connection(qb_ipcs_connection_t *c,
void *key, uid_t uid_client)
315 if (client == NULL) {
323 if (client->
user == NULL) {
324 client->
user = strdup(
"#unprivileged");
326 crm_err(
"Unable to enforce ACLs for user ID %d, assuming unprivileged",
339 if (client->
id == NULL) {
340 crm_err(
"Could not generate UUID for client");
362 crm_client_t *client = client_from_connection(NULL, key, 0);
371 static gid_t uid_cluster = 0;
372 static gid_t gid_cluster = 0;
378 if (uid_cluster == 0) {
380 static bool need_log = TRUE;
383 crm_warn(
"Could not find user and group IDs for user %s",
390 if (uid_client != 0) {
391 crm_trace(
"Giving access to group %u", gid_cluster);
393 qb_ipcs_connection_auth_set(c, -1, gid_cluster, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
399 client = client_from_connection(c, NULL, uid_client);
400 if (client == NULL) {
404 if ((uid_client == 0) || (uid_client == uid_cluster)) {
409 crm_debug(
"Connecting %p for uid=%d gid=%d pid=%u id=%s", c, uid_client, gid_client, client->
pid, client->
id);
423 crm_trace(
"Destroying %p/%p (%d remaining)",
428 crm_trace(
"Destroying remote connection %p (%d remaining)",
443 free(event[0].iov_base);
444 free(event[1].iov_base);
475 if ((errno == 0) && (qmax_int > 0)) {
486 struct qb_ipcs_connection_stats stats;
488 stats.client_pid = 0;
489 qb_ipcs_connection_stats_get(c, &stats, 0);
490 return stats.client_pid;
497 char *uncompressed = NULL;
498 char *text = ((
char *)data) +
sizeof(
struct crm_ipc_response_header);
499 struct crm_ipc_response_header *header =
data;
502 *
id = ((
struct qb_ipc_response_header *)data)->id;
505 *flags = header->flags;
516 crm_err(
"Filtering incompatible v%d IPC message, we only support versions <= %d",
521 if (header->size_compressed) {
523 unsigned int size_u = 1 + header->size_uncompressed;
524 uncompressed = calloc(1, size_u);
526 crm_trace(
"Decompressing message data %u bytes into %u bytes",
527 header->size_compressed, size_u);
529 rc = BZ2_bzBuffToBuffDecompress(uncompressed, &size_u, text, header->size_compressed, 1, 0);
539 CRM_ASSERT(text[header->size_uncompressed - 1] == 0);
551 crm_ipcs_flush_events_cb(gpointer
data)
568 delay_next_flush(
crm_client_t *c,
unsigned int queue_len)
571 guint delay = (queue_len < 40)? (1000 + 100 * queue_len) : 5000;
573 c->
event_timer = g_timeout_add(delay, crm_ipcs_flush_events_cb, c);
580 unsigned int sent = 0;
581 unsigned int queue_len = 0;
594 struct crm_ipc_response_header *header = NULL;
597 rc = qb_ipcs_event_sendv(c->
ipcs, event, 2);
603 header =
event[0].iov_base;
604 if (header->size_compressed) {
605 crm_trace(
"Event %d to %p[%d] (%lld compressed bytes) sent",
606 header->qb.id, c->
ipcs, c->
pid, (
long long) rc);
608 crm_trace(
"Event %d to %p[%d] (%lld bytes) sent: %.120s",
609 header->qb.id, c->
ipcs, c->
pid, (
long long) rc,
610 (
char *) (event[1].iov_base));
614 free(event[0].iov_base);
615 free(event[1].iov_base);
620 if (sent > 0 || queue_len) {
621 crm_trace(
"Sent %d events (%d remaining) for %p[%d]: %s (%lld)",
622 sent, queue_len, c->
ipcs, c->
pid,
633 if ((c->
queue_backlog <= 1) || (queue_len < c->queue_backlog)) {
635 crm_warn(
"Client with process ID %u has a backlog of %u messages " 638 crm_err(
"Evicting client with process ID %u due to backlog of %u messages " 641 qb_ipcs_disconnect(c->
ipcs);
647 delay_next_flush(c, queue_len);
660 static unsigned int biggest = 0;
662 unsigned int total = 0;
663 char *compressed = NULL;
665 struct crm_ipc_response_header *header = calloc(1,
sizeof(
struct crm_ipc_response_header));
671 if (max_send_size == 0) {
672 max_send_size = ipc_buffer_max;
678 iov = calloc(2,
sizeof(
struct iovec));
681 iov[0].iov_len = hdr_offset;
682 iov[0].iov_base = header;
685 header->size_uncompressed = 1 + strlen(buffer);
686 total = iov[0].iov_len + header->size_uncompressed;
688 if (total < max_send_size) {
689 iov[1].iov_base = buffer;
690 iov[1].iov_len = header->size_uncompressed;
693 unsigned int new_size = 0;
696 (buffer, header->size_uncompressed, max_send_size, &compressed, &new_size)) {
699 header->size_compressed = new_size;
701 iov[1].iov_len = header->size_compressed;
702 iov[1].iov_base = compressed;
706 biggest = QB_MAX(header->size_compressed, biggest);
709 ssize_t rc = -EMSGSIZE;
712 biggest = QB_MAX(header->size_uncompressed, biggest);
715 (
"Could not compress the message (%u bytes) into less than the configured ipc limit (%u bytes). " 716 "Set PCMK_ipc_buffer to a higher value (%u bytes suggested)",
717 header->size_uncompressed, max_send_size, 4 * biggest);
728 header->qb.size = iov[0].iov_len + iov[1].iov_len;
729 header->qb.id = (
int32_t)request;
733 return header->qb.size;
741 struct crm_ipc_response_header *header = iov[0].iov_base;
753 header->flags |=
flags;
755 header->qb.id =
id++;
762 struct iovec *iov_copy = calloc(2,
sizeof(
struct iovec));
765 iov_copy[0].iov_len = iov[0].iov_len;
766 iov_copy[0].iov_base = malloc(iov[0].iov_len);
767 memcpy(iov_copy[0].iov_base, iov[0].iov_base, iov[0].iov_len);
769 iov_copy[1].iov_len = iov[1].iov_len;
770 iov_copy[1].iov_base = malloc(iov[1].iov_len);
771 memcpy(iov_copy[1].iov_base, iov[1].iov_base, iov[1].iov_len);
779 rc = qb_ipcs_response_sendv(c->
ipcs, iov, 2);
780 if (rc < header->qb.size) {
781 crm_notice(
"Response %d to %p[%d] (%u bytes) failed: %s (%d)",
785 crm_trace(
"Response %d sent, %lld bytes to %p[%d]",
786 header->qb.id, (
long long) rc, c->
ipcs, c->
pid);
790 free(iov[0].iov_base);
791 free(iov[1].iov_base);
796 if (flags & crm_ipc_server_event) {
802 if (rc == -EPIPE || rc == -ENOTCONN) {
813 struct iovec *iov = NULL;
817 return -EDESTADDRREQ;
827 crm_notice(
"Message to %p[%d] failed: %s (%d)",
852 #define MIN_MSG_SIZE 12336 853 #define MAX_MSG_SIZE 128*1024 859 unsigned int max_buf_size;
861 unsigned int buf_size;
868 qb_ipcc_connection_t *ipc;
873 pick_ipc_buffer(
unsigned int max)
875 static unsigned int global_max = 0;
877 if (global_max == 0) {
878 const char *env = getenv(
"PCMK_ipc_buffer");
890 return QB_MAX(max, global_max);
900 client->name = strdup(name);
901 client->buf_size = pick_ipc_buffer(max_size);
902 client->buffer = malloc(client->buf_size);
905 client->max_buf_size = client->buf_size;
908 client->pfd.events = POLLIN;
909 client->pfd.revents = 0;
926 static uid_t cl_uid = 0;
927 static gid_t cl_gid = 0;
928 pid_t found_pid = 0; uid_t found_uid = 0; gid_t found_gid = 0;
931 client->need_reply = FALSE;
932 client->ipc = qb_ipcc_connect(client->name, client->buf_size);
934 if (client->ipc == NULL) {
940 if (client->pfd.fd < 0) {
948 if (!cl_uid && !cl_gid
958 &found_pid, &found_uid,
960 crm_err(
"Daemon (IPC %s) is not authentic:" 961 " process %lld (uid: %lld, gid: %lld)",
963 (
long long) found_uid, (
long long) found_gid);
965 errno = ECONNABORTED;
970 crm_perror(LOG_ERR,
"Could not verify authenticity of daemon (IPC %s)",
977 qb_ipcc_context_set(client->ipc, client);
979 #ifdef HAVE_IPCS_GET_BUFFER_SIZE 980 client->max_buf_size = qb_ipcc_get_buffer_size(client->ipc);
981 if (client->max_buf_size > client->buf_size) {
982 free(client->buffer);
983 client->buffer = calloc(1, client->max_buf_size);
984 client->buf_size = client->max_buf_size;
995 crm_trace(
"Disconnecting %s IPC connection %p (%p)", client->name, client, client->ipc);
998 qb_ipcc_connection_t *ipc = client->ipc;
1001 qb_ipcc_disconnect(ipc);
1010 if (client->ipc && qb_ipcc_is_connected(client->ipc)) {
1011 crm_notice(
"Destroying an active IPC connection to %s", client->name);
1022 crm_trace(
"Destroying IPC connection to %s: %p", client->name, client);
1023 free(client->buffer);
1034 if (client && client->ipc && (qb_ipcc_fd_get(client->ipc, &fd) == 0)) {
1038 crm_perror(LOG_ERR,
"Could not obtain file IPC descriptor for %s",
1039 (client? client->name :
"unspecified client"));
1048 if (client == NULL) {
1052 }
else if (client->ipc == NULL) {
1056 }
else if (client->pfd.fd < 0) {
1061 rc = qb_ipcc_is_connected(client->ipc);
1063 client->pfd.fd = -EINVAL;
1086 client->pfd.revents = 0;
1087 rc = poll(&(client->pfd), 1, 0);
1088 return (rc < 0)? -errno : rc;
1094 struct crm_ipc_response_header *header = (
struct crm_ipc_response_header *)(
void*)client->buffer;
1096 if (header->size_compressed) {
1098 unsigned int size_u = 1 + header->size_uncompressed;
1100 unsigned int new_buf_size = QB_MAX((hdr_offset + size_u), client->max_buf_size);
1101 char *uncompressed = calloc(1, new_buf_size);
1103 crm_trace(
"Decompressing message data %u bytes into %u bytes",
1104 header->size_compressed, size_u);
1106 rc = BZ2_bzBuffToBuffDecompress(uncompressed + hdr_offset, &size_u,
1107 client->buffer + hdr_offset, header->size_compressed, 1, 0);
1123 CRM_ASSERT(size_u == header->size_uncompressed);
1125 memcpy(uncompressed, client->buffer, hdr_offset);
1126 header = (
struct crm_ipc_response_header *)(
void*)uncompressed;
1128 free(client->buffer);
1129 client->buf_size = new_buf_size;
1130 client->buffer = uncompressed;
1133 CRM_ASSERT(client->buffer[hdr_offset + header->size_uncompressed - 1] == 0);
1140 struct crm_ipc_response_header *header = NULL;
1148 client->buffer[0] = 0;
1149 client->msg_size = qb_ipcc_event_recv(client->ipc, client->buffer,
1150 client->buf_size, 0);
1151 if (client->msg_size >= 0) {
1152 int rc = crm_ipc_decompress(client);
1158 header = (
struct crm_ipc_response_header *)(
void*)client->buffer;
1160 crm_err(
"Filtering incompatible v%d IPC message, we only support versions <= %d",
1165 crm_trace(
"Received %s event %d, size=%u, rc=%d, text: %.100s",
1166 client->name, header->qb.id, header->qb.size, client->msg_size,
1167 client->buffer + hdr_offset);
1174 crm_err(
"Connection to %s failed", client->name);
1179 return header->size_uncompressed;
1188 return client->buffer +
sizeof(
struct crm_ipc_response_header);
1194 struct crm_ipc_response_header *header = NULL;
1197 if (client->buffer == NULL) {
1201 header = (
struct crm_ipc_response_header *)(
void*)client->buffer;
1202 return header->flags;
1209 return client->name;
1213 internal_ipc_send_recv(
crm_ipc_t * client,
const void *iov)
1218 rc = qb_ipcc_sendv_recv(client->ipc, iov, 2, client->buffer, client->buf_size, -1);
1225 internal_ipc_send_request(
crm_ipc_t * client,
const void *iov,
int ms_timeout)
1228 time_t timeout = time(NULL) + 1 + (ms_timeout / 1000);
1231 rc = qb_ipcc_sendv(client->ipc, iov, 2);
1238 internal_ipc_get_reply(
crm_ipc_t * client,
int request_id,
int ms_timeout)
1240 time_t timeout = time(NULL) + 1 + (ms_timeout / 1000);
1246 crm_trace(
"client %s waiting on reply to msg id %d", client->name, request_id);
1249 rc = qb_ipcc_recv(client->ipc, client->buffer, client->buf_size, 1000);
1251 struct crm_ipc_response_header *hdr = NULL;
1253 int rc = crm_ipc_decompress(client);
1259 hdr = (
struct crm_ipc_response_header *)(
void*)client->buffer;
1260 if (hdr->qb.id == request_id) {
1263 }
else if (hdr->qb.id < request_id) {
1266 crm_err(
"Discarding old reply %d (need %d)", hdr->qb.id, request_id);
1272 crm_err(
"Discarding newer reply %d (need %d)", hdr->qb.id, request_id);
1277 crm_err(
"Server disconnected client %s while waiting for msg id %d", client->name,
1282 }
while (time(NULL) < timeout);
1294 static int factor = 8;
1295 struct crm_ipc_response_header *header;
1299 if (client == NULL) {
1305 crm_notice(
"Connection to %s closed", client->name);
1309 if (ms_timeout == 0) {
1313 if (client->need_reply) {
1314 crm_trace(
"Trying again to obtain pending reply from %s", client->name);
1315 rc = qb_ipcc_recv(client->ipc, client->buffer, client->buf_size, ms_timeout);
1317 crm_warn(
"Sending to %s (%p) is disabled until pending reply is received", client->name,
1322 crm_notice(
"Lost reply from %s (%p) finally arrived, sending re-enabled", client->name,
1324 client->need_reply = FALSE;
1335 header = iov[0].iov_base;
1336 header->flags |=
flags;
1343 if(header->size_compressed) {
1344 if(factor < 10 && (client->max_buf_size / 10) < (rc / factor)) {
1345 crm_notice(
"Compressed message exceeds %d0%% of the configured ipc limit (%u bytes), " 1346 "consider setting PCMK_ipc_buffer to %u or higher",
1347 factor, client->max_buf_size, 2 * client->max_buf_size);
1352 crm_trace(
"Sending from client: %s request id: %d bytes: %u timeout:%d msg...",
1353 client->name, header->qb.id, header->qb.size, ms_timeout);
1357 rc = internal_ipc_send_request(client, iov, ms_timeout);
1360 crm_trace(
"Failed to send from client %s request %d with %u bytes...",
1361 client->name, header->qb.id, header->qb.size);
1365 crm_trace(
"Message sent, not waiting for reply to %d from %s to %u bytes...",
1366 header->qb.id, client->name, header->qb.size);
1371 rc = internal_ipc_get_reply(client, header->qb.id, ms_timeout);
1380 client->need_reply = TRUE;
1384 rc = internal_ipc_send_recv(client, iov);
1388 struct crm_ipc_response_header *hdr = (
struct crm_ipc_response_header *)(
void*)client->buffer;
1390 crm_trace(
"Received response %d, size=%u, rc=%ld, text: %.200s", hdr->qb.id, hdr->qb.size,
1398 crm_trace(
"Response not received: rc=%ld, errno=%d", rc, errno);
1405 }
else if (rc == -ETIMEDOUT) {
1406 crm_warn(
"Request %d to %s (%p) failed: %s (%ld) after %dms",
1407 header->qb.id, client->name, client->ipc,
pcmk_strerror(rc), rc, ms_timeout);
1410 }
else if (rc <= 0) {
1411 crm_warn(
"Request %d to %s (%p) failed: %s (%ld)",
1412 header->qb.id, client->name, client->ipc,
pcmk_strerror(rc), rc);
1416 free(iov[1].iov_base);
1423 pid_t *gotpid, uid_t *gotuid, gid_t *gotgid) {
1425 pid_t found_pid = 0; uid_t found_uid = 0; gid_t found_gid = 0;
1426 #if defined(US_AUTH_PEERCRED_UCRED) 1428 socklen_t ucred_len =
sizeof(ucred);
1430 if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED,
1432 && ucred_len ==
sizeof(ucred)) {
1433 found_pid = ucred.pid; found_uid = ucred.uid; found_gid = ucred.gid;
1435 #elif defined(US_AUTH_PEERCRED_SOCKPEERCRED) 1436 struct sockpeercred sockpeercred;
1437 socklen_t sockpeercred_len =
sizeof(sockpeercred);
1439 if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED,
1440 &sockpeercred, &sockpeercred_len)
1441 && sockpeercred_len ==
sizeof(sockpeercred_len)) {
1442 found_pid = sockpeercred.pid;
1443 found_uid = sockpeercred.uid; found_gid = sockpeercred.gid;
1445 #elif defined(US_AUTH_GETPEEREID) 1446 if (!getpeereid(sock, &found_uid, &found_gid)) {
1449 #elif defined(US_AUTH_GETPEERUCRED) 1451 if (!getpeerucred(sock, &ucred)) {
1453 found_pid = ucred_getpid(ucred);
1454 found_uid = ucred_geteuid(ucred); found_gid = ucred_getegid(ucred);
1462 # error "No way to authenticate a Unix socket peer" 1466 if (gotpid != NULL) {
1467 *gotpid = found_pid;
1469 if (gotuid != NULL) {
1470 *gotuid = found_uid;
1472 if (gotgid != NULL) {
1473 *gotgid = found_gid;
1475 ret = (found_uid == 0 || found_uid == refuid || found_gid == refgid);
1485 gid_t refgid, pid_t *gotpid) {
1486 static char last_asked_name[PATH_MAX / 2] =
"";
1488 pid_t found_pid = 0; uid_t found_uid = 0; gid_t found_gid = 0;
1489 qb_ipcc_connection_t *c;
1491 if ((c = qb_ipcc_connect(name, 0)) == NULL) {
1494 }
else if ((ret = qb_ipcc_fd_get(c, &fd))) {
1495 crm_err(
"Could not get fd from %s IPC: %s (%d)", name,
1500 &found_pid, &found_uid,
1503 crm_err(
"Could not get peer credentials from %s IPC", name);
1505 crm_err(
"Could not get peer credentials from %s IPC: %s (%d)",
1511 if (gotpid != NULL) {
1512 *gotpid = found_pid;
1516 crm_err(
"Daemon (IPC %s) effectively blocked with unauthorized" 1517 " process %lld (uid: %lld, gid: %lld)",
1519 (
long long) found_uid, (
long long) found_gid);
1521 }
else if ((found_uid != refuid || found_gid != refgid)
1522 && strncmp(last_asked_name, name,
sizeof(last_asked_name))) {
1523 if (!found_uid && refuid) {
1524 crm_warn(
"Daemon (IPC %s) runs as root, whereas the expected" 1525 " credentials are %lld:%lld, hazard of violating" 1526 " the least privilege principle",
1527 name, (
long long) refuid, (
long long) refgid);
1529 crm_notice(
"Daemon (IPC %s) runs as %lld:%lld, whereas the" 1530 " expected credentials are %lld:%lld, which may" 1531 " mean a different set of privileges than expected",
1532 name, (
long long) found_uid, (
long long) found_gid,
1533 (
long long) refuid, (
long long) refgid);
1535 memccpy(last_asked_name, name,
'\0',
sizeof(last_asked_name));
1540 qb_ipcc_disconnect(c);
1551 const char *client_name,
const char *major_version,
const char *minor_version)
1553 xmlNode *hello_node = NULL;
1554 xmlNode *hello = NULL;
1556 if (uuid == NULL || strlen(uuid) == 0
1557 || client_name == NULL || strlen(client_name) == 0
1558 || major_version == NULL || strlen(major_version) == 0
1559 || minor_version == NULL || strlen(minor_version) == 0) {
1560 crm_err(
"Missing fields, Hello message will not be valid.");
1565 crm_xml_add(hello_node,
"major_version", major_version);
1566 crm_xml_add(hello_node,
"minor_version", minor_version);
1567 crm_xml_add(hello_node,
"client_name", client_name);
#define CRM_CHECK(expr, failure_action)
const char * crm_ipc_buffer(crm_ipc_t *client)
void crm_write_blackbox(int nsig, struct qb_log_callsite *callsite)
void crm_ipc_close(crm_ipc_t *client)
#define crm_notice(fmt, args...)
char * crm_generate_uuid(void)
uint32_t crm_ipc_buffer_flags(crm_ipc_t *client)
int crm_ipc_send(crm_ipc_t *client, xmlNode *message, enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply)
const char * pcmk_strerror(int rc)
crm_client_t * crm_client_get(qb_ipcs_connection_t *c)
qb_ipcs_connection_t * ipcs
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
long long crm_int_helper(const char *text, char **end_text)
bool crm_set_client_queue_max(crm_client_t *client, const char *qmax)
Raise IPC eviction threshold for a client, if allowed.
crm_client_t * crm_client_get_by_id(const char *id)
xmlNode * create_reply_adv(xmlNode *original_request, xmlNode *xml_response_data, const char *origin)
#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.
bool crm_ipc_connect(crm_ipc_t *client)
Establish an IPC connection to a Pacemaker component.
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
#define PCMK__SPECIAL_PID
struct crm_remote_s * remote
int crm_user_lookup(const char *name, uid_t *uid, gid_t *gid)
#define CRM_LOG_ASSERT(expr)
void crm_client_destroy(crm_client_t *c)
int crm_ipc_get_fd(crm_ipc_t *client)
void crm_client_init(void)
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.
#define clear_bit(word, bit)
void crm_client_disconnect_all(qb_ipcs_service_t *service)
char * strerror(int errnum)
ssize_t crm_ipc_prepare(uint32_t request, xmlNode *message, struct iovec **result, uint32_t max_send_size)
ssize_t crm_ipcs_flush_events(crm_client_t *c)
xmlNode * string2xml(const char *input)
ssize_t crm_ipcs_sendv(crm_client_t *c, struct iovec *iov, enum crm_ipc_flags flags)
#define crm_warn(fmt, args...)
crm_client_t * crm_client_new(qb_ipcs_connection_t *c, uid_t uid_client, gid_t gid_client)
#define set_bit(word, bit)
#define crm_debug(fmt, args...)
struct crm_ipc_s crm_ipc_t
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
const char * crm_ipc_name(crm_ipc_t *client)
GHashTable * client_connections
unsigned int crm_ipc_default_buffer_size(void)
#define crm_trace(fmt, args...)
void crm_ipc_destroy(crm_ipc_t *client)
xmlNode * create_xml_node(xmlNode *parent, const char *name)
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
void free_xml(xmlNode *child)
void crm_ipcs_send_ack(crm_client_t *c, uint32_t request, uint32_t flags, const char *tag, const char *function, int line)
unsigned int queue_backlog
xmlNode * crm_ipcs_recv(crm_client_t *c, void *data, size_t size, uint32_t *id, uint32_t *flags)
crm_client_t * crm_client_alloc(void *key)
Allocate a new crm_client_t object and generate its ID.
bool crm_compress_string(const char *data, int length, int max, char **result, unsigned int *result_len)
ssize_t crm_ipcs_send(crm_client_t *c, uint32_t request, xmlNode *message, enum crm_ipc_flags flags)
#define PCMK_IPC_DEFAULT_QUEUE_MAX
int pcmk__ipc_is_authentic_process_active(const char *name, uid_t refuid, gid_t refgid, pid_t *gotpid)
#define crm_perror(level, fmt, args...)
Log a system error message.
xmlNode * create_hello_message(const char *uuid, const char *client_name, const char *major_version, const char *minor_version)
#define crm_err(fmt, args...)
const char * bz2_strerror(int rc)
#define crm_log_xml_notice(xml, text)
char * dump_xml_unformatted(xmlNode *msg)
int crm_ipc_ready(crm_ipc_t *client)
Check whether an IPC connection is ready to be read.
#define XML_ATTR_RESPONSE
long crm_ipc_read(crm_ipc_t *client)
Wrappers for and extensions to libqb IPC.
char * generate_hash_key(const char *crm_msg_reference, const char *sys)
int crm_ipcs_client_pid(qb_ipcs_connection_t *c)
#define crm_log_xml_trace(xml, text)
void crm_client_cleanup(void)
const char * crm_client_name(crm_client_t *c)
bool crm_ipc_connected(crm_ipc_t *client)
crm_ipc_t * crm_ipc_new(const char *name, size_t max_size)
xmlNode * create_request_adv(const char *task, xmlNode *msg_data, const char *host_to, const char *sys_to, const char *sys_from, const char *uuid_from, const char *origin)
#define create_request(task, xml_data, host_to, sys_to, sys_from, uuid_from)
#define crm_info(fmt, args...)
char * uid2username(uid_t uid)
enum crm_ais_msg_types type