31 #include <sys/types.h> 47 #ifdef HAVE_GNUTLS_GNUTLS_H 49 # include <gnutls/gnutls.h> 52 #include <sys/socket.h> 53 #include <netinet/in.h> 54 #include <netinet/ip.h> 55 #include <arpa/inet.h> 58 #define MAX_TLS_RECV_WAIT 10000 62 static int lrmd_api_disconnect(
lrmd_t * lrmd);
63 static int lrmd_api_is_connected(
lrmd_t * lrmd);
67 static void lrmd_internal_proxy_dispatch(
lrmd_t *lrmd, xmlNode *msg);
70 #ifdef HAVE_GNUTLS_GNUTLS_H 71 # define LRMD_CLIENT_HANDSHAKE_TIMEOUT 5000 72 gnutls_psk_client_credentials_t psk_cred_s;
73 int lrmd_tls_set_key(gnutls_datum_t * key);
74 static void lrmd_tls_disconnect(
lrmd_t * lrmd);
75 static int global_remote_msg_id = 0;
77 static void lrmd_tls_connection_destroy(gpointer userdata);
80 typedef struct lrmd_private_s {
91 char *remote_nodename;
92 #ifdef HAVE_GNUTLS_GNUTLS_H 95 gnutls_psk_client_credentials_t psk_cred_c;
105 int expected_late_replies;
106 GList *pending_notify;
113 void (*proxy_callback)(
lrmd_t *lrmd,
void *userdata, xmlNode *msg);
114 void *proxy_callback_userdata;
119 lrmd_list_add(
lrmd_list_t * head,
const char *value)
124 p->
val = strdup(value);
127 while (end && end->
next) {
146 char *val = (
char *)head->
val;
161 p->
key = strdup(key);
162 p->
value = strdup(value);
165 while (end && end->
next) {
210 if (rsc_id != NULL) {
211 event->rsc_id = strdup(rsc_id);
215 event->op_type = strdup(task);
218 event->interval = interval_ms;
234 copy->
rsc_id =
event->rsc_id ? strdup(event->
rsc_id) : NULL;
237 copy->
output =
event->output ? strdup(event->
output) : NULL;
253 free((
char *)event->
rsc_id);
256 free((
char *)event->
output);
260 g_hash_table_destroy(event->
params);
266 lrmd_dispatch_internal(
lrmd_t * lrmd, xmlNode * msg)
273 if (proxy_session != NULL) {
275 lrmd_internal_proxy_dispatch(lrmd, msg);
277 }
else if (!native->callback) {
279 crm_trace(
"notify event received but client has not set callback");
283 event.remote_nodename = native->remote_nodename;
320 crm_trace(
"op %s notify event received", type);
321 native->callback(&event);
324 g_hash_table_destroy(event.params);
330 lrmd_ipc_dispatch(
const char *buffer, ssize_t length, gpointer userdata)
337 if (!native->callback) {
343 rc = lrmd_dispatch_internal(lrmd, msg);
348 #ifdef HAVE_GNUTLS_GNUTLS_H 350 lrmd_free_xml(gpointer userdata)
356 lrmd_tls_connected(
lrmd_t * lrmd)
360 if (native->remote->tls_session) {
368 lrmd_tls_dispatch(gpointer userdata)
374 int disconnected = 0;
376 if (lrmd_tls_connected(lrmd) == FALSE) {
377 crm_trace(
"tls dispatch triggered after disconnect");
385 if (native->pending_notify) {
388 crm_trace(
"Processing pending notifies");
389 for (iter = native->pending_notify; iter; iter = iter->next) {
390 lrmd_dispatch_internal(lrmd, iter->data);
392 g_list_free_full(native->pending_notify, lrmd_free_xml);
393 native->pending_notify = NULL;
410 lrmd_dispatch_internal(lrmd, xml);
412 if (native->expected_late_replies > 0) {
413 native->expected_late_replies--;
418 crm_err(
"Got outdated reply %d", reply_id);
426 crm_info(
"Server disconnected while reading remote server msg.");
427 lrmd_tls_disconnect(lrmd);
440 switch (native->type) {
444 #ifdef HAVE_GNUTLS_GNUTLS_H 446 if (native->pending_notify) {
453 crm_err(
"Unsupported connection type: %d", native->type);
468 switch (private->type) {
474 lrmd_ipc_dispatch(msg, strlen(msg), lrmd);
478 #ifdef HAVE_GNUTLS_GNUTLS_H 480 lrmd_tls_dispatch(lrmd);
484 crm_err(
"Unsupported connection type: %d", private->type);
487 if (lrmd_api_is_connected(lrmd) == FALSE) {
496 lrmd_create_op(
const char *token,
const char *op, xmlNode *
data,
int timeout,
515 crm_trace(
"Created lrmd %s command with call options %.8lx (%d)",
516 op, (
long)options, options);
521 lrmd_ipc_connection_destroy(gpointer userdata)
526 crm_info(
"IPC connection destroyed");
530 native->source = NULL;
532 if (native->callback) {
535 event.remote_nodename = native->remote_nodename;
536 native->callback(&event);
540 #ifdef HAVE_GNUTLS_GNUTLS_H 542 lrmd_tls_connection_destroy(gpointer userdata)
547 crm_info(
"TLS connection destroyed");
549 if (native->remote->tls_session) {
550 gnutls_bye(*native->remote->tls_session, GNUTLS_SHUT_RDWR);
551 gnutls_deinit(*native->remote->tls_session);
552 gnutls_free(native->remote->tls_session);
554 if (native->psk_cred_c) {
555 gnutls_psk_free_client_credentials(native->psk_cred_c);
560 if (native->process_notify) {
562 native->process_notify = NULL;
564 if (native->pending_notify) {
565 g_list_free_full(native->pending_notify, lrmd_free_xml);
566 native->pending_notify = NULL;
569 free(native->remote->buffer);
570 native->remote->buffer = NULL;
573 native->psk_cred_c = NULL;
574 native->remote->tls_session = NULL;
577 if (native->callback) {
581 native->callback(&event);
595 lrmd_tls_recv_reply(
lrmd_t * lrmd,
int total_timeout,
int expected_reply_id,
int *disconnected)
599 time_t start = time(NULL);
600 const char *msg_type = NULL;
602 int remaining_timeout = 0;
615 if (remaining_timeout) {
616 remaining_timeout = total_timeout - ((time(NULL) - start) * 1000);
618 remaining_timeout = total_timeout;
620 if (remaining_timeout <= 0) {
621 crm_err(
"Never received the expected reply during the timeout period, disconnecting.");
622 *disconnected = TRUE;
629 crm_err(
"Unable to receive expected reply, disconnecting.");
630 *disconnected = TRUE;
632 }
else if (*disconnected) {
643 crm_err(
"Empty msg type received while waiting for reply");
649 native->pending_notify = g_list_append(native->pending_notify, xml);
650 if (native->process_notify) {
657 crm_err(
"Expected a reply, got %s", msg_type);
660 }
else if (reply_id != expected_reply_id) {
661 if (native->expected_late_replies > 0) {
662 native->expected_late_replies--;
664 crm_err(
"Got outdated reply, expected id %d got id %d", expected_reply_id, reply_id);
671 if (native->remote->buffer && native->process_notify) {
679 lrmd_tls_send(
lrmd_t * lrmd, xmlNode * msg)
684 global_remote_msg_id++;
685 if (global_remote_msg_id <= 0) {
686 global_remote_msg_id = 1;
691 crm_err(
"Remote lrmd send failed, disconnecting");
692 lrmd_tls_disconnect(lrmd);
699 lrmd_tls_send_recv(
lrmd_t * lrmd, xmlNode * msg,
int timeout, xmlNode ** reply)
702 int disconnected = 0;
705 if (lrmd_tls_connected(lrmd) == FALSE) {
709 rc = lrmd_tls_send(lrmd, msg);
714 xml = lrmd_tls_recv_reply(lrmd, timeout, global_remote_msg_id, &disconnected);
717 crm_err(
"Remote lrmd server disconnected while waiting for reply with id %d. ",
718 global_remote_msg_id);
719 lrmd_tls_disconnect(lrmd);
722 crm_err(
"Remote lrmd never received reply for request id %d. timeout: %dms ",
723 global_remote_msg_id, timeout);
738 lrmd_send_xml(
lrmd_t * lrmd, xmlNode * msg,
int timeout, xmlNode ** reply)
743 switch (native->type) {
747 #ifdef HAVE_GNUTLS_GNUTLS_H 749 rc = lrmd_tls_send_recv(lrmd, msg, timeout, reply);
753 crm_err(
"Unsupported connection type: %d", native->type);
760 lrmd_send_xml_no_reply(
lrmd_t * lrmd, xmlNode * msg)
765 switch (native->type) {
769 #ifdef HAVE_GNUTLS_GNUTLS_H 771 rc = lrmd_tls_send(lrmd, msg);
776 native->expected_late_replies++;
781 crm_err(
"Unsupported connection type: %d", native->type);
788 lrmd_api_is_connected(
lrmd_t * lrmd)
792 switch (native->type) {
796 #ifdef HAVE_GNUTLS_GNUTLS_H 798 return lrmd_tls_connected(lrmd);
802 crm_err(
"Unsupported connection type: %d", native->type);
825 lrmd_send_command(
lrmd_t *lrmd,
const char *op, xmlNode *data,
826 xmlNode **output_data,
int timeout,
831 xmlNode *op_msg = NULL;
832 xmlNode *op_reply = NULL;
834 if (!lrmd_api_is_connected(lrmd)) {
839 crm_err(
"No operation specified");
847 op_msg = lrmd_create_op(native->token, op, data, timeout, options);
849 if (op_msg == NULL) {
854 rc = lrmd_send_xml(lrmd, op_msg, timeout, &op_reply);
856 rc = lrmd_send_xml_no_reply(lrmd, op_msg);
861 crm_perror(LOG_ERR,
"Couldn't perform %s operation (timeout=%d): %d", op, timeout, rc);
865 }
else if(op_reply == NULL) {
880 *output_data = op_reply;
885 if (lrmd_api_is_connected(lrmd) == FALSE) {
895 lrmd_api_poke_connection(
lrmd_t * lrmd)
918 value = g_hash_table_lookup(hash,
"stonith-watchdog-timeout");
928 lrmd_handshake(
lrmd_t * lrmd,
const char *name)
932 xmlNode *reply = NULL;
941 if (native->proxy_callback) {
945 rc = lrmd_send_xml(lrmd, hello, -1, &reply);
948 crm_perror(LOG_DEBUG,
"Couldn't complete registration with the lrmd API: %d", rc);
950 }
else if (reply == NULL) {
951 crm_err(
"Did not receive registration reply");
961 crm_err(
"LRMD protocol mismatch client version %s, server version %s",
966 crm_err(
"Invalid registration message: %s", msg_type);
969 }
else if (tmp_ticket == NULL) {
970 crm_err(
"No registration token provided");
974 crm_trace(
"Obtained registration token: %s", tmp_ticket);
975 native->token = strdup(tmp_ticket);
976 native->peer_version = strdup(version?version:
"1.0");
985 lrmd_api_disconnect(lrmd);
991 lrmd_ipc_connect(
lrmd_t * lrmd,
int *fd)
998 .destroy = lrmd_ipc_connection_destroy
1008 }
else if (native->ipc) {
1009 crm_perror(LOG_ERR,
"Connection to local resource manager failed");
1017 if (native->ipc == NULL) {
1018 crm_debug(
"Could not connect to the LRMD API");
1025 #ifdef HAVE_GNUTLS_GNUTLS_H 1027 copy_gnutls_datum(gnutls_datum_t *dest, gnutls_datum_t *source)
1029 dest->data = gnutls_malloc(source->size);
1031 memcpy(dest->data, source->data, source->size);
1032 dest->size = source->size;
1036 clear_gnutls_datum(gnutls_datum_t *datum)
1038 gnutls_free(datum->data);
1043 #define KEY_READ_LEN 256 1046 set_key(gnutls_datum_t * key,
const char *location)
1049 size_t buf_len = KEY_READ_LEN;
1050 static gnutls_datum_t key_cache = { 0, };
1051 static time_t key_cache_updated = 0;
1053 if (location == NULL) {
1057 if (key_cache.data != NULL) {
1058 if ((time(NULL) - key_cache_updated) < 60) {
1059 copy_gnutls_datum(key, &key_cache);
1060 crm_debug(
"Using cached Pacemaker Remote key");
1063 clear_gnutls_datum(&key_cache);
1064 key_cache_updated = 0;
1065 crm_debug(
"Cleared Pacemaker Remote key cache");
1069 stream = fopen(location,
"r");
1074 key->data = gnutls_malloc(buf_len);
1076 while (!feof(stream)) {
1077 int next = fgetc(stream);
1080 if (!feof(stream)) {
1081 crm_err(
"Error reading Pacemaker Remote key; copy in memory may be corrupted");
1085 if (key->size == buf_len) {
1086 buf_len = key->size + KEY_READ_LEN;
1087 key->data = gnutls_realloc(key->data, buf_len);
1090 key->data[key->size++] = (
unsigned char) next;
1094 if (key->size == 0) {
1095 clear_gnutls_datum(key);
1099 if (key_cache.data == NULL) {
1100 copy_gnutls_datum(&key_cache, key);
1101 key_cache_updated = time(NULL);
1102 crm_debug(
"Cached Pacemaker Remote key");
1109 lrmd_tls_set_key(gnutls_datum_t * key)
1111 const char *specific_location = getenv(
"PCMK_authkey_location");
1113 if (set_key(key, specific_location) == 0) {
1114 crm_debug(
"Using custom authkey location %s", specific_location);
1117 }
else if (specific_location) {
1118 crm_err(
"No valid lrmd remote key found at %s, trying default location", specific_location);
1131 lrmd_gnutls_global_init(
void)
1133 static int gnutls_init = 0;
1136 crm_gnutls_global_init();
1143 report_async_connection_result(
lrmd_t * lrmd,
int rc)
1147 if (native->callback) {
1150 event.remote_nodename = native->remote_nodename;
1151 event.connection_rc = rc;
1152 native->callback(&event);
1156 #ifdef HAVE_GNUTLS_GNUTLS_H 1158 lrmd_tcp_connect_cb(
void *userdata,
int sock)
1165 .destroy = lrmd_tls_connection_destroy,
1168 gnutls_datum_t psk_key = { NULL, 0 };
1170 native->async_timer = 0;
1173 lrmd_tls_connection_destroy(lrmd);
1174 crm_info(
"Could not connect to remote LRMD at %s:%d",
1175 native->server, native->port);
1176 report_async_connection_result(lrmd, rc);
1184 native->sock = sock;
1186 rc = lrmd_tls_set_key(&psk_key);
1188 crm_warn(
"Could not set key for remote LRMD at %s:%d " CRM_XS " rc=%d",
1189 native->server, native->port, rc);
1190 lrmd_tls_connection_destroy(lrmd);
1191 report_async_connection_result(lrmd, rc);
1195 gnutls_psk_allocate_client_credentials(&native->psk_cred_c);
1197 gnutls_free(psk_key.data);
1199 native->remote->tls_session = pcmk__new_tls_session(sock, GNUTLS_CLIENT,
1201 native->psk_cred_c);
1202 if (native->remote->tls_session == NULL) {
1203 lrmd_tls_connection_destroy(lrmd);
1204 report_async_connection_result(lrmd, -EPROTO);
1208 if (crm_initiate_client_tls_handshake(native->remote, LRMD_CLIENT_HANDSHAKE_TIMEOUT) != 0) {
1209 crm_warn(
"Disconnecting after TLS handshake with remote LRMD %s:%d failed",
1210 native->server, native->port);
1211 gnutls_deinit(*native->remote->tls_session);
1212 gnutls_free(native->remote->tls_session);
1213 native->remote->tls_session = NULL;
1214 lrmd_tls_connection_destroy(lrmd);
1219 crm_info(
"TLS connection to remote LRMD %s:%d succeeded",
1220 native->server, native->port);
1226 mainloop_add_fd(name, G_PRIORITY_HIGH, native->sock, lrmd, &lrmd_tls_callbacks);
1228 rc = lrmd_handshake(lrmd, name);
1231 report_async_connection_result(lrmd, rc);
1236 lrmd_tls_connect_async(
lrmd_t * lrmd,
int timeout )
1242 lrmd_gnutls_global_init();
1244 &timer_id, lrmd, lrmd_tcp_connect_cb);
1248 native->sock = sock;
1249 native->async_timer = timer_id;
1254 lrmd_tls_connect(
lrmd_t * lrmd,
int *fd)
1258 .destroy = lrmd_tls_connection_destroy,
1264 gnutls_datum_t psk_key = { NULL, 0 };
1266 lrmd_gnutls_global_init();
1270 crm_warn(
"Could not establish remote lrmd connection to %s", native->server);
1271 lrmd_tls_connection_destroy(lrmd);
1275 native->sock = sock;
1277 rc = lrmd_tls_set_key(&psk_key);
1279 lrmd_tls_connection_destroy(lrmd);
1283 gnutls_psk_allocate_client_credentials(&native->psk_cred_c);
1285 gnutls_free(psk_key.data);
1287 native->remote->tls_session = pcmk__new_tls_session(sock, GNUTLS_CLIENT,
1289 native->psk_cred_c);
1290 if (native->remote->tls_session == NULL) {
1291 lrmd_tls_connection_destroy(lrmd);
1295 if (crm_initiate_client_tls_handshake(native->remote, LRMD_CLIENT_HANDSHAKE_TIMEOUT) != 0) {
1296 crm_err(
"Session creation for %s:%d failed", native->server, native->port);
1297 gnutls_deinit(*native->remote->tls_session);
1298 gnutls_free(native->remote->tls_session);
1299 native->remote->tls_session = NULL;
1300 lrmd_tls_connection_destroy(lrmd);
1304 crm_info(
"Remote lrmd client TLS connection established with server %s:%d", native->server,
1311 native->server, native->port);
1315 mainloop_add_fd(name, G_PRIORITY_HIGH, native->sock, lrmd, &lrmd_tls_callbacks);
1323 lrmd_api_connect(
lrmd_t * lrmd,
const char *name,
int *fd)
1328 switch (native->type) {
1330 rc = lrmd_ipc_connect(lrmd, fd);
1332 #ifdef HAVE_GNUTLS_GNUTLS_H 1333 case CRM_CLIENT_TLS:
1334 rc = lrmd_tls_connect(lrmd, fd);
1338 crm_err(
"Unsupported connection type: %d", native->type);
1342 rc = lrmd_handshake(lrmd, name);
1349 lrmd_api_connect_async(
lrmd_t * lrmd,
const char *name,
int timeout)
1354 if (!native->callback) {
1355 crm_err(
"Async connect not possible, no lrmd client callback set.");
1359 switch (native->type) {
1363 rc = lrmd_api_connect(lrmd, name, NULL);
1365 report_async_connection_result(lrmd, rc);
1368 #ifdef HAVE_GNUTLS_GNUTLS_H 1369 case CRM_CLIENT_TLS:
1370 rc = lrmd_tls_connect_async(lrmd, timeout);
1373 report_async_connection_result(lrmd, rc);
1378 crm_err(
"Unsupported connection type: %d", native->type);
1385 lrmd_ipc_disconnect(
lrmd_t * lrmd)
1389 if (native->source != NULL) {
1392 native->source = NULL;
1395 }
else if (native->ipc) {
1405 #ifdef HAVE_GNUTLS_GNUTLS_H 1407 lrmd_tls_disconnect(
lrmd_t * lrmd)
1411 if (native->remote->tls_session) {
1412 gnutls_bye(*native->remote->tls_session, GNUTLS_SHUT_RDWR);
1413 gnutls_deinit(*native->remote->tls_session);
1414 gnutls_free(native->remote->tls_session);
1415 native->remote->tls_session = 0;
1418 if (native->async_timer) {
1419 g_source_remove(native->async_timer);
1420 native->async_timer = 0;
1423 if (native->source != NULL) {
1426 native->source = NULL;
1428 }
else if (native->sock) {
1429 close(native->sock);
1433 if (native->pending_notify) {
1434 g_list_free_full(native->pending_notify, lrmd_free_xml);
1435 native->pending_notify = NULL;
1441 lrmd_api_disconnect(
lrmd_t * lrmd)
1445 crm_info(
"Disconnecting from %d lrmd service", native->type);
1446 switch (native->type) {
1448 lrmd_ipc_disconnect(lrmd);
1450 #ifdef HAVE_GNUTLS_GNUTLS_H 1451 case CRM_CLIENT_TLS:
1452 lrmd_tls_disconnect(lrmd);
1456 crm_err(
"Unsupported connection type: %d", native->type);
1459 free(native->token);
1460 native->token = NULL;
1462 free(native->peer_version);
1463 native->peer_version = NULL;
1468 lrmd_api_register_rsc(
lrmd_t * lrmd,
1474 xmlNode *data = NULL;
1476 if (!
class || !type || !rsc_id) {
1490 rc = lrmd_send_command(lrmd,
LRMD_OP_RSC_REG, data, NULL, 0, options, TRUE);
1512 const char *provider,
const char *type)
1518 rsc_info->
id = strdup(rsc_id);
1522 rsc_info->
class = strdup(standard);
1526 rsc_info->
provider = strdup(provider);
1530 rsc_info->
type = strdup(type);
1550 free(rsc_info->
type);
1551 free(rsc_info->
class);
1561 xmlNode *output = NULL;
1562 const char *
class = NULL;
1563 const char *provider = NULL;
1564 const char *type = NULL;
1568 lrmd_send_command(lrmd,
LRMD_OP_RSC_INFO, data, &output, 0, options, TRUE);
1579 if (!
class || !type) {
1598 native->callback = callback;
1606 native->proxy_callback = callback;
1607 native->proxy_callback_userdata = userdata;
1611 lrmd_internal_proxy_dispatch(
lrmd_t *lrmd, xmlNode *msg)
1615 if (native->proxy_callback) {
1617 native->proxy_callback(lrmd, native->proxy_callback_userdata, msg);
1630 return lrmd_send_xml_no_reply(lrmd, msg);
1634 stonith_get_metadata(
const char *provider,
const char *type,
char **output)
1641 stonith_api->
cmds->
free(stonith_api);
1643 if (*output == NULL) {
1650 lrmd_api_get_metadata(
lrmd_t *lrmd,
const char *standard,
const char *provider,
1651 const char *type,
char **output,
1655 output, options, NULL);
1659 lrmd_api_get_metadata_params(
lrmd_t *lrmd,
const char *standard,
1660 const char *provider,
const char *type,
1665 GHashTable *params_table = NULL;
1667 if (!standard || !type) {
1674 return stonith_get_metadata(provider, type, output);
1677 params_table = crm_str_table_new();
1679 g_hash_table_insert(params_table, strdup(param->key), strdup(param->value));
1687 if (action == NULL) {
1688 crm_err(
"Unable to retrieve meta-data for %s:%s:%s",
1689 standard, provider, type);
1694 crm_err(
"Failed to retrieve meta-data for %s:%s:%s",
1695 standard, provider, type);
1701 crm_err(
"Failed to receive meta-data for %s:%s:%s",
1702 standard, provider, type);
1714 lrmd_api_exec(
lrmd_t * lrmd,
const char *rsc_id,
const char *action,
const char *userdata,
int interval,
1732 for (tmp = params; tmp; tmp = tmp->
next) {
1736 rc = lrmd_send_command(lrmd,
LRMD_OP_RSC_EXEC, data, NULL, timeout, options, TRUE);
1745 lrmd_api_exec_alert(
lrmd_t *lrmd,
const char *alert_id,
const char *alert_path,
1758 for (tmp = params; tmp; tmp = tmp->
next) {
1771 lrmd_api_cancel(
lrmd_t * lrmd,
const char *rsc_id,
const char *action,
int interval)
1795 stonith_api->
cmds->
free(stonith_api);
1798 for (dIter = stonith_resources; dIter; dIter = dIter->
next) {
1801 *resources = lrmd_list_add(*resources, dIter->
value);
1810 lrmd_api_list_agents(
lrmd_t * lrmd,
lrmd_list_t ** resources,
const char *
class,
1811 const char *provider)
1816 rc += list_stonith_agents(resources);
1822 for (gIter = agents; gIter != NULL; gIter = gIter->next) {
1823 *resources = lrmd_list_add(*resources, (
const char *)gIter->data);
1826 g_list_free_full(agents, free);
1829 rc += list_stonith_agents(resources);
1834 crm_notice(
"No agents found for class %s",
class);
1835 rc = -EPROTONOSUPPORT;
1841 does_provider_have_agent(
const char *agent,
const char *provider,
const char *
class)
1844 GList *agents = NULL;
1848 for (gIter2 = agents; gIter2 != NULL; gIter2 = gIter2->next) {
1853 g_list_free_full(agents, free);
1859 lrmd_api_list_ocf_providers(
lrmd_t * lrmd,
const char *agent,
lrmd_list_t ** providers)
1862 char *provider = NULL;
1863 GList *ocf_providers = NULL;
1868 for (gIter = ocf_providers; gIter != NULL; gIter = gIter->next) {
1869 provider = gIter->data;
1870 if (!agent || does_provider_have_agent(agent, provider,
1872 *providers = lrmd_list_add(*providers, (
const char *)gIter->data);
1877 g_list_free_full(ocf_providers, free);
1885 GList *standards = NULL;
1890 for (gIter = standards; gIter != NULL; gIter = gIter->next) {
1891 *supported = lrmd_list_add(*supported, (
const char *)gIter->data);
1895 if (list_stonith_agents(NULL) > 0) {
1900 g_list_free_full(standards, free);
1910 new_lrmd = calloc(1,
sizeof(
lrmd_t));
1928 new_lrmd->
cmds->
exec = lrmd_api_exec;
1942 #ifdef HAVE_GNUTLS_GNUTLS_H 1946 if (!nodename && !server) {
1951 native->type = CRM_CLIENT_TLS;
1952 native->remote_nodename = nodename ? strdup(nodename) : strdup(server);
1953 native->server = server ? strdup(server) : strdup(nodename);
1954 native->port = port;
1955 if (native->port == 0) {
1961 crm_err(
"GNUTLS is not enabled for this build, remote LRMD client can not be created");
1978 #ifdef HAVE_GNUTLS_GNUTLS_H 1979 free(native->server);
1981 free(native->remote_nodename);
1982 free(native->remote);
1983 free(native->token);
1984 free(native->peer_version);
#define CRM_CHECK(expr, failure_action)
#define LRMD_OP_ALERT_EXEC
#define CRMD_METADATA_CALL_TIMEOUT
bool crm_ipc_connect(crm_ipc_t *client)
Establish an IPC connection to a Pacemaker component.
#define crm_notice(fmt, args...)
lrmd_event_data_t * lrmd_copy_event(lrmd_event_data_t *event)
gboolean safe_str_neq(const char *a, const char *b)
void services_action_free(svc_action_t *op)
mainloop_io_t * mainloop_add_fd(const char *name, int priority, int fd, void *userdata, struct mainloop_fd_callbacks *callbacks)
#define F_LRMD_IS_IPC_PROVIDER
int crm_remote_tcp_connect(const char *host, int port)
#define F_LRMD_IPC_SESSION
#define F_LRMD_RSC_EXEC_TIME
int(* list_agents)(stonith_t *stonith, int call_options, const char *namespace, stonith_key_value_t **devices, int timeout)
Retrieve a list of installed stonith agents.
#define F_LRMD_RSC_ACTION
#define LRMD_OP_RSC_CANCEL
int crm_ipc_get_fd(crm_ipc_t *client)
#define F_LRMD_RSC_OUTPUT
int(* connect_async)(lrmd_t *lrmd, const char *client_name, int timeout)
Establish an connection to lrmd, don't block while connecting.
void(* lrmd_event_callback)(lrmd_event_data_t *event)
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
svc_action_t * resources_action_create(const char *name, const char *standard, const char *provider, const char *agent, const char *action, int interval, int timeout, GHashTable *params, enum svc_action_flags flags)
Create a new resource action.
struct stonith_key_value_s * next
void lrmd_key_value_freeall(lrmd_key_value_t *head)
struct mainloop_io_s mainloop_io_t
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
void mainloop_set_trigger(crm_trigger_t *source)
#define DEFAULT_REMOTE_USERNAME
#define MAX_TLS_RECV_WAIT
int lrmd_internal_proxy_send(lrmd_t *lrmd, xmlNode *msg)
lrmd_rsc_info_t * lrmd_copy_rsc_info(lrmd_rsc_info_t *rsc_info)
#define F_LRMD_ALERT_PATH
long crm_ipc_read(crm_ipc_t *client)
gboolean mainloop_destroy_trigger(crm_trigger_t *source)
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
void hash2smartfield(gpointer key, gpointer value, gpointer user_data)
Add hash table entry to XML as (possibly legacy) name/value.
int(* cancel)(lrmd_t *lrmd, const char *rsc_id, const char *action, int interval)
Cancel a recurring command.
Wrappers for and extensions to glib mainloop.
#define F_LRMD_PROTOCOL_VERSION
lrmd_t * lrmd_remote_api_new(const char *nodename, const char *server, int port)
Create a new remote lrmd connection using tls backend.
stonith_t * stonith_api_new(void)
xmlNode * string2xml(const char *input)
const char * crm_ipc_buffer(crm_ipc_t *client)
int remote_proxy_check(lrmd_t *lrmd, GHashTable *hash)
#define LRMD_OP_RSC_UNREG
#define DEFAULT_REMOTE_KEY_LOCATION
struct trigger_s crm_trigger_t
struct lrmd_private_s lrmd_private_t
int(* free)(stonith_t *st)
Destroy the stonith api structure.
int(* dispatch)(gpointer userdata)
#define crm_warn(fmt, args...)
int(* exec_alert)(lrmd_t *lrmd, const char *alert_id, const char *alert_path, int timeout, lrmd_key_value_t *params)
Execute an alert agent.
int(* poke_connection)(lrmd_t *lrmd)
Poke lrmd connection to verify it is still capable of serving requests.
#define PCMK_RESOURCE_CLASS_OCF
#define crm_debug(fmt, args...)
struct crm_ipc_s crm_ipc_t
#define F_LRMD_RSC_EXIT_REASON
#define ALT_REMOTE_KEY_LOCATION
int crm_remote_send(crm_remote_t *remote, xmlNode *msg)
bool lrmd_dispatch(lrmd_t *lrmd)
Use after lrmd_poll returns 1 to read and dispatch a message.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
struct lrmd_list_s * next
gboolean services_action_sync(svc_action_t *op)
#define LRMD_PROTOCOL_VERSION
int(* get_metadata)(lrmd_t *lrmd, const char *class, const char *provider, const char *agent, char **output, enum lrmd_call_options options)
Get resource metadata for a specified resource agent.
lrmd_rsc_info_t *(* get_rsc_info)(lrmd_t *lrmd, const char *rsc_id, enum lrmd_call_options options)
Retrieve registration info for a rsc.
void lrmd_list_freeall(lrmd_list_t *head)
int(* connect)(lrmd_t *lrmd, const char *client_name, int *fd)
Connect from the lrmd.
#define crm_trace(fmt, args...)
crm_trigger_t * mainloop_add_trigger(int priority, int(*dispatch)(gpointer user_data), gpointer userdata)
#define LRMD_OP_NEW_CLIENT
xmlNode * create_xml_node(xmlNode *parent, const char *name)
void stonith_key_value_freeall(stonith_key_value_t *kvp, int keys, int values)
uint32_t pcmk_get_ra_caps(const char *standard)
Get capabilities of a resource agent standard.
lrmd_rsc_info_t * lrmd_new_rsc_info(const char *rsc_id, const char *standard, const char *provider, const char *type)
void mainloop_del_ipc_client(mainloop_io_t *client)
void crm_ipc_destroy(crm_ipc_t *client)
GList * resources_list_providers(const char *standard)
Get a list of providers.
lrmd_t * lrmd_api_new(void)
Create a new local lrmd connection.
int(* get_metadata_params)(lrmd_t *lrmd, const char *standard, const char *provider, const char *agent, char **output, enum lrmd_call_options options, lrmd_key_value_t *params)
Get resource metadata for a resource agent, passing parameters.
int crm_remote_ready(crm_remote_t *remote, int total_timeout)
int crm_remote_tcp_connect_async(const char *host, int port, int timeout, int *timer_id, void *userdata, void(*callback)(void *userdata, int sock))
struct lrmd_key_value_s * next
#define F_LRMD_RSC_USERDATA_STR
gboolean add_message_xml(xmlNode *msg, const char *field, xmlNode *xml)
void free_xml(xmlNode *child)
#define F_LRMD_RSC_INTERVAL
void lrmd_free_rsc_info(lrmd_rsc_info_t *rsc_info)
CRM_TRACE_INIT_DATA(lrmd)
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
int(* unregister_rsc)(lrmd_t *lrmd, const char *rsc_id, enum lrmd_call_options options)
Unregister a resource from the lrmd.
#define F_LRMD_RSC_START_DELAY
gboolean crm_remote_recv(crm_remote_t *remote, int total_timeout, int *disconnected)
int(* disconnect)(lrmd_t *lrmd)
Disconnect from the lrmd.
bool crm_ipc_connected(crm_ipc_t *client)
int lrmd_poll(lrmd_t *lrmd, int timeout)
Poll for a specified timeout period to determine if a message is ready for dispatch.
#define PCMK_RESOURCE_CLASS_STONITH
int crm_ipc_ready(crm_ipc_t *client)
Check whether an IPC connection is ready to be read.
int lrmd_tls_send_msg(crm_remote_t *session, xmlNode *msg, uint32_t id, const char *msg_type)
#define F_LRMD_RSC_RCCHANGE_TIME
int(* list_agents)(lrmd_t *lrmd, lrmd_list_t **agents, const char *class, const char *provider)
Retrieve a list of installed resource agents.
#define crm_log_xml_err(xml, text)
void lrmd_api_delete(lrmd_t *lrmd)
Destroy lrmd object.
#define F_LRMD_REMOTE_MSG_ID
#define crm_perror(level, fmt, args...)
Log a system error message.
const char * remote_nodename
lrmd_api_operations_t * cmds
crm_ipc_t * mainloop_get_ipc_client(mainloop_io_t *client)
GList * resources_list_standards(void)
#define crm_err(fmt, args...)
enum lrmd_callback_event type
lrmd_key_value_t * lrmd_key_value_add(lrmd_key_value_t *head, const char *key, const char *value)
stonith_api_operations_t * cmds
int crm_ipc_send(crm_ipc_t *client, xmlNode *message, enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply)
GHashTable * crm_str_table_dup(GHashTable *old_table)
lrmd_event_data_t * lrmd_new_event(const char *rsc_id, const char *task, int interval_ms)
int(* list_standards)(lrmd_t *lrmd, lrmd_list_t **standards)
Retrieve a list of standards supported by this machine/installation.
#define CRMD_ACTION_METADATA
crm_ipc_t * crm_ipc_new(const char *name, size_t max_size)
GList * resources_list_agents(const char *standard, const char *provider)
Get a list of resource agents.
GHashTable * xml2list(xmlNode *parent)
Retrieve XML attributes as a hash table.
#define F_LRMD_RSC_RUN_TIME
int(* register_rsc)(lrmd_t *lrmd, const char *rsc_id, const char *class, const char *provider, const char *agent, enum lrmd_call_options options)
Register a resource with the lrmd.
int(* list_ocf_providers)(lrmd_t *lrmd, const char *agent, lrmd_list_t **providers)
Retrieve a list of resource agent providers.
void lrmd_internal_set_proxy_callback(lrmd_t *lrmd, void *userdata, void(*callback)(lrmd_t *lrmd, void *userdata, xmlNode *msg))
#define crm_log_xml_trace(xml, text)
#define F_LRMD_CLIENTNAME
mainloop_io_t * mainloop_add_ipc_client(const char *name, int priority, size_t max_size, void *userdata, struct ipc_client_callbacks *callbacks)
#define F_LRMD_RSC_QUEUE_TIME
#define F_LRMD_RSC_DELETED
#define safe_str_eq(a, b)
#define F_LRMD_CALLBACK_TOKEN
int(* metadata)(stonith_t *st, int options, const char *device, const char *namespace, char **output, int timeout)
Get the metadata documentation for a resource.
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
void lrmd_free_event(lrmd_event_data_t *event)
#define F_LRMD_REMOTE_MSG_TYPE
void crm_ipc_close(crm_ipc_t *client)
#define crm_info(fmt, args...)
int(* is_connected)(lrmd_t *lrmd)
Is connected to lrmd daemon?
int(* dispatch)(const char *buffer, ssize_t length, gpointer userdata)
int crm_default_remote_port(void)
Get the default remote connection TCP port on this host.
void(* set_callback)(lrmd_t *lrmd, lrmd_event_callback callback)
Sets the callback to receive lrmd events on.
xmlNode * crm_remote_parse_buffer(crm_remote_t *remote)
enum crm_ais_msg_types type
int(* exec)(lrmd_t *lrmd, const char *rsc_id, const char *action, const char *userdata, int interval, int timeout, int start_delay, enum lrmd_call_options options, lrmd_key_value_t *params)
Issue a command on a resource.