char * corosync_cluster_name(void) { cmap_handle_t handle; char *cluster_name = NULL; int rc = CS_OK; rc = cmap_initialize(&handle); if (rc != CS_OK) { crm_info("Failed to initialize the cmap API: %s (%d)", ais_error2text(rc), rc); return NULL; } rc = cmap_get_string(handle, "totem.cluster_name", &cluster_name); if (rc != CS_OK) { crm_info("Cannot get totem.cluster_name: %s (%d)", ais_error2text(rc), rc); } else { crm_debug("cmap totem.cluster_name = '%s'", cluster_name); } cmap_finalize(handle); return cluster_name; }
static int get_quorum_type(char *quorum_type, size_t quorum_type_len) { int err; char *str = NULL; if ((!quorum_type) || (quorum_type_len <= 0)) { return -1; } if (q_type == QUORUM_FREE) { return -1; } if ((err = cmap_get_string(cmap_handle, "quorum.provider", &str)) != CS_OK) { goto out; } if (!str) { return -1; } strncpy(quorum_type, str, quorum_type_len - 1); free(str); return 0; out: return err; }
static void _cs_cmap_members_key_changed ( cmap_handle_t cmap_handle_c, cmap_track_handle_t cmap_track_handle, int32_t event, const char *key_name, struct cmap_notify_value new_value, struct cmap_notify_value old_value, void *user_data) { char nodename[CS_MAX_NAME_LENGTH]; char* open_bracket = NULL; char* close_bracket = NULL; int res; uint32_t nodeid; char *ip_str; char tmp_key[CMAP_KEYNAME_MAXLEN]; cs_error_t err; int no_retries; if (event != CMAP_TRACK_ADD && event != CMAP_TRACK_MODIFY) { return ; } res = sscanf(key_name, "runtime.totem.pg.mrp.srp.members.%u.%s", &nodeid, tmp_key); if (res != 2) return ; if (strcmp(tmp_key, "status") != 0) { return ; } snprintf(tmp_key, CMAP_KEYNAME_MAXLEN, "runtime.totem.pg.mrp.srp.members.%u.ip", nodeid); no_retries = 0; while ((err = cmap_get_string(cmap_handle, tmp_key, &ip_str)) == CS_ERR_TRY_AGAIN && no_retries++ < CMAP_MAX_RETRIES) { sleep(1); } if (err != CS_OK) { return ; } /* * We want the ip out of: "r(0) ip(192.168.100.92)" */ open_bracket = strrchr(ip_str, '('); open_bracket++; close_bracket = strrchr(open_bracket, ')'); *close_bracket = '\0'; _cs_ip_to_hostname(open_bracket, nodename); _cs_node_membership_event(nodename, nodeid, (char *)new_value.data, open_bracket); free(ip_str); }
char * corosync_cluster_name(void) { cmap_handle_t handle; char *cluster_name = NULL; cs_error_t rc = CS_OK; int fd = -1; uid_t found_uid = 0; gid_t found_gid = 0; pid_t found_pid = 0; int rv; rc = cmap_initialize(&handle); if (rc != CS_OK) { crm_info("Failed to initialize the cmap API: %s (%d)", cs_strerror(rc), rc); return NULL; } rc = cmap_fd_get(handle, &fd); if (rc != CS_OK) { crm_err("Could not obtain the CMAP API connection: %s (%d)", cs_strerror(rc), rc); goto bail; } /* CMAP provider run as root (in given user namespace, anyway)? */ if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid, &found_uid, &found_gid))) { crm_err("CMAP provider is not authentic:" " process %lld (uid: %lld, gid: %lld)", (long long) PCMK__SPECIAL_PID_AS_0(found_pid), (long long) found_uid, (long long) found_gid); goto bail; } else if (rv < 0) { crm_err("Could not verify authenticity of CMAP provider: %s (%d)", strerror(-rv), -rv); goto bail; } rc = cmap_get_string(handle, "totem.cluster_name", &cluster_name); if (rc != CS_OK) { crm_info("Cannot get totem.cluster_name: %s (%d)", cs_strerror(rc), rc); } else { crm_debug("cmap totem.cluster_name = '%s'", cluster_name); } bail: cmap_finalize(handle); return cluster_name; }
static const char *node_name_by_nodelist(uint32_t nodeid) { cmap_iter_handle_t iter; char key_name[CMAP_KEYNAME_MAXLEN]; char tmp_key[CMAP_KEYNAME_MAXLEN]; static char ret_buf[_POSIX_HOST_NAME_MAX]; char *str = NULL; uint32_t node_pos, cur_nodeid; int res = 0; if (cmap_iter_init(cmap_handle, "nodelist.node.", &iter) != CS_OK) { return ""; } memset(ret_buf, 0, sizeof(ret_buf)); while ((cmap_iter_next(cmap_handle, iter, key_name, NULL, NULL)) == CS_OK) { res = sscanf(key_name, "nodelist.node.%u.%s", &node_pos, tmp_key); if (res != 2) { continue; } if (strcmp(tmp_key, "ring0_addr") != 0) { continue; } snprintf(tmp_key, CMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos); if (cmap_get_uint32(cmap_handle, tmp_key, &cur_nodeid) != CS_OK) { continue; } if (cur_nodeid != nodeid) { continue; } snprintf(tmp_key, CMAP_KEYNAME_MAXLEN, "nodelist.node.%u.ring0_addr", node_pos); if (cmap_get_string(cmap_handle, tmp_key, &str) != CS_OK) { continue; } if (!str) { continue; } strncpy(ret_buf, str, sizeof(ret_buf) - 1); free(str); break; } cmap_iter_finalize(cmap_handle, iter); return ret_buf; }
static int get_config_opt(cmap_handle_t object_handle, const char *key, char **value, const char *fallback) { int rc = 0, retries = 0; cs_repeat(retries, 5, rc = cmap_get_string(object_handle, key, value)); if(rc != CS_OK) { crm_trace("Search for %s failed %d, defaulting to %s", key, rc, fallback); if(fallback) { *value = strdup(fallback); } else { *value = NULL; } } crm_trace("%s: %s", key, *value); return rc; }
int qdevice_instance_configure_from_cmap(struct qdevice_instance *instance) { char *str; if (cmap_get_string(instance->cmap_handle, "quorum.device.model", &str) != CS_OK) { qdevice_log(LOG_ERR, "Can't read quorum.device.model cmap key."); return (-1); } if (qdevice_model_str_to_type(str, &instance->model_type) != 0) { qdevice_log(LOG_ERR, "Configured device model %s is not supported.", str); free(str); return (-1); } free(str); if (cmap_get_uint32(instance->cmap_handle, "runtime.votequorum.this_node_id", &instance->node_id) != CS_OK) { qdevice_log(LOG_ERR, "Unable to retrieve this node nodeid."); return (-1); } if (cmap_get_uint32(instance->cmap_handle, "quorum.device.timeout", &instance->heartbeat_interval) != CS_OK) { instance->heartbeat_interval = VOTEQUORUM_QDEVICE_DEFAULT_TIMEOUT; } if (cmap_get_uint32(instance->cmap_handle, "quorum.device.sync_timeout", &instance->sync_heartbeat_interval) != CS_OK) { instance->sync_heartbeat_interval = VOTEQUORUM_QDEVICE_DEFAULT_SYNC_TIMEOUT; } if (qdevice_instance_configure_from_cmap_heuristics(instance) != 0) { return (-1); } return (0); }
/* * Test cmap integration + restart policy */ static int test9 (pid_t pid, pid_t old_pid, int test_n) { cs_error_t err; cmap_handle_t cmap_handle; unsigned int instance_id; char *str; char key_name[CMAP_KEYNAME_MAXLEN]; err = cmap_initialize (&cmap_handle); if (err != CS_OK) { qb_log (LOG_INFO, "Could not initialize Cluster Map API instance error %d. Test skipped", err); return (1); } qb_log (LOG_INFO, "test %d", test_n); if (test_n == 1) { qb_log (LOG_INFO, " initialize"); err = sam_initialize (2000, SAM_RECOVERY_POLICY_RESTART | SAM_RECOVERY_POLICY_CMAP); if (err != CS_OK) { qb_log (LOG_ERR, "Can't initialize SAM API. Error %d", err); return 2; } qb_log (LOG_INFO, " register"); err = sam_register (&instance_id); if (err != CS_OK) { qb_log (LOG_ERR, "Can't register. Error %d", err); return 2; } qb_log (LOG_INFO, " iid %d", instance_id); if (instance_id < 3) { snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.recovery", pid); err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"recovery\" key: %d.", err); return (2); } if (strcmp(str, "restart") != 0) { qb_log (LOG_INFO, "Recovery key \"%s\" is not \"restart\".", str); return (2); } free(str); snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid); err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"state\" key: %d.", err); return (2); } if (strcmp(str, "stopped") != 0) { qb_log (LOG_INFO, "State key is not \"stopped\"."); return (2); } free(str); qb_log (LOG_INFO, "iid %d: start", instance_id); err = sam_start (); if (err != CS_OK) { qb_log (LOG_ERR, "Can't start hc. Error %d", err); return 2; } err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"state\" key: %d.", err); return (2); } if (strcmp(str, "running") != 0) { qb_log (LOG_INFO, "State key is not \"running\"."); return (2); } free(str); qb_log (LOG_INFO, "iid %d: waiting for kill", instance_id); sleep (10); return (2); } if (instance_id == 3) { qb_log (LOG_INFO, "iid %d: mark failed", instance_id); err = sam_mark_failed (); if (err != CS_OK) { qb_log (LOG_ERR, "Can't mark failed. Error %d", err); return 2; } sleep (10); return (2); } return (2); } if (test_n == 2) { qb_log (LOG_INFO, "Testing if status is failed"); /* * Previous should be FAILED */ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid); err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"state\" key: %d.", err); return (2); } if (strcmp(str, "failed") != 0) { qb_log (LOG_INFO, "State key is not \"failed\"."); return (2); } free(str); return (0); } return (2); }
/* * Test cmap integration + quit policy */ static int test8 (pid_t pid, pid_t old_pid, int test_n) { cmap_handle_t cmap_handle; cs_error_t err; uint64_t tstamp1, tstamp2; int32_t msec_diff; unsigned int instance_id; char key_name[CMAP_KEYNAME_MAXLEN]; char *str; err = cmap_initialize (&cmap_handle); if (err != CS_OK) { qb_log (LOG_INFO, "Could not initialize Cluster Map API instance error %d. Test skipped", err); return (1); } qb_log (LOG_INFO, "test %d", test_n); if (test_n == 2) { /* * Object should not exist */ qb_log (LOG_INFO, "Testing if object exists (it shouldn't)"); snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid); err = cmap_get_string(cmap_handle, key_name, &str); if (err == CS_OK) { qb_log (LOG_INFO, "Could find key \"%s\": %d.", key_name, err); free(str); return (2); } } if (test_n == 1 || test_n == 2) { qb_log (LOG_INFO, " initialize"); err = sam_initialize (2000, SAM_RECOVERY_POLICY_QUIT | SAM_RECOVERY_POLICY_CMAP); if (err != CS_OK) { qb_log (LOG_ERR, "Can't initialize SAM API. Error %d", err); return 2; } qb_log (LOG_INFO, " register"); err = sam_register (&instance_id); if (err != CS_OK) { qb_log (LOG_ERR, "Can't register. Error %d", err); return 2; } snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.recovery", pid); err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"recovery\" key: %d.", err); return (2); } if (strcmp(str, "quit") != 0) { qb_log (LOG_INFO, "Recovery key \"%s\" is not \"quit\".", key_name); return (2); } free(str); snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid); err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"state\" key: %d.", err); return (2); } if (strcmp(str, "stopped") != 0) { qb_log (LOG_INFO, "State key is not \"stopped\"."); return (2); } free(str); qb_log (LOG_INFO, "iid %d: start", instance_id); err = sam_start (); if (err != CS_OK) { qb_log (LOG_ERR, "Can't start hc. Error %d", err); return 2; } err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"state\" key: %d.", err); return (2); } if (strcmp(str, "running") != 0) { qb_log (LOG_INFO, "State key is not \"running\"."); return (2); } free(str); qb_log (LOG_INFO, "iid %d: stop", instance_id); err = sam_stop (); if (err != CS_OK) { qb_log (LOG_ERR, "Can't stop hc. Error %d", err); return 2; } err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"state\" key: %d.", err); return (2); } if (strcmp(str, "stopped") != 0) { qb_log (LOG_INFO, "State key is not \"stopped\"."); return (2); } free(str); qb_log (LOG_INFO, "iid %d: sleeping 5", instance_id); sleep (5); err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"state\" key: %d.", err); return (2); } if (strcmp(str, "stopped") != 0) { qb_log (LOG_INFO, "State key is not \"stopped\"."); return (2); } free(str); qb_log (LOG_INFO, "iid %d: start 2", instance_id); err = sam_start (); if (err != CS_OK) { qb_log (LOG_ERR, "Can't start hc. Error %d", err); return 2; } err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"state\" key: %d.", err); return (2); } if (strcmp(str, "running") != 0) { qb_log (LOG_INFO, "State key is not \"running\"."); return (2); } free(str); if (test_n == 2) { qb_log (LOG_INFO, "iid %d: sleeping 5. Should be killed", instance_id); sleep (5); return (2); } else { qb_log (LOG_INFO, "iid %d: Test HC", instance_id); err = sam_hc_send (); if (err != CS_OK) { qb_log (LOG_ERR, "Can't send hc. Error %d", err); return 2; } snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.last_updated", pid); err = cmap_get_uint64(cmap_handle, key_name, &tstamp1); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"last_updated\" key: %d.", err); return (2); } qb_log (LOG_INFO, "iid %d: Sleep 1", instance_id); sleep (1); err = sam_hc_send (); if (err != CS_OK) { qb_log (LOG_ERR, "Can't send hc. Error %d", err); return 2; } sleep (1); err = cmap_get_uint64(cmap_handle, key_name, &tstamp2); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"last_updated\" key: %d.", err); return (2); } msec_diff = (tstamp2 - tstamp1)/CS_TIME_NS_IN_MSEC; if (msec_diff < 500 || msec_diff > 2000) { qb_log (LOG_INFO, "Difference %d is not within <500, 2000> interval.", msec_diff); return (2); } qb_log (LOG_INFO, "iid %d: stop 2", instance_id); err = sam_stop (); if (err != CS_OK) { qb_log (LOG_ERR, "Can't stop hc. Error %d", err); return 2; } snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid); err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"state\" key: %d.", err); return (2); } if (strcmp(str, "stopped") != 0) { qb_log (LOG_INFO, "State key is not \"stopped\"."); return (2); } free(str); qb_log (LOG_INFO, "iid %d: exiting", instance_id); return (0); } } if (test_n == 3) { qb_log (LOG_INFO, "Testing if status is failed"); /* * Previous should be FAILED */ snprintf(key_name, CMAP_KEYNAME_MAXLEN, "resources.process.%d.state", pid); err = cmap_get_string(cmap_handle, key_name, &str); if (err != CS_OK) { qb_log (LOG_INFO, "Could not get \"state\" key: %d.", err); return (2); } if (strcmp(str, "failed") != 0) { qb_log (LOG_INFO, "State key is not \"failed\"."); return (2); } return (0); } return (2); }
static void print_key(cmap_handle_t handle, const char *key_name, size_t value_len, const void *value, cmap_value_types_t type) { char *str; char *bin_value = NULL; cs_error_t err; int8_t i8; uint8_t u8; int16_t i16; uint16_t u16; int32_t i32; uint32_t u32; int64_t i64; uint64_t u64; float flt; double dbl; int end_loop; int no_retries; size_t bin_value_len; end_loop = 0; no_retries = 0; err = CS_OK; while (!end_loop) { switch (type) { case CMAP_VALUETYPE_INT8: if (value == NULL) { err = cmap_get_int8(handle, key_name, &i8); } else { i8 = *((int8_t *)value); } break; case CMAP_VALUETYPE_INT16: if (value == NULL) { err = cmap_get_int16(handle, key_name, &i16); } else { i16 = *((int16_t *)value); } break; case CMAP_VALUETYPE_INT32: if (value == NULL) { err = cmap_get_int32(handle, key_name, &i32); } else { i32 = *((int32_t *)value); } break; case CMAP_VALUETYPE_INT64: if (value == NULL) { err = cmap_get_int64(handle, key_name, &i64); } else { i64 = *((int64_t *)value); } break; case CMAP_VALUETYPE_UINT8: if (value == NULL) { err = cmap_get_uint8(handle, key_name, &u8); } else { u8 = *((uint8_t *)value); } break; case CMAP_VALUETYPE_UINT16: if (value == NULL) { err = cmap_get_uint16(handle, key_name, &u16); } else { u16 = *((uint16_t *)value); } break; case CMAP_VALUETYPE_UINT32: if (value == NULL) { err = cmap_get_uint32(handle, key_name, &u32); } else { u32 = *((uint32_t *)value); } break; case CMAP_VALUETYPE_UINT64: if (value == NULL) { err = cmap_get_uint64(handle, key_name, &u64); } else { u64 = *((uint64_t *)value); } break; case CMAP_VALUETYPE_FLOAT: if (value == NULL) { err = cmap_get_float(handle, key_name, &flt); } else { flt = *((float *)value); } break; case CMAP_VALUETYPE_DOUBLE: if (value == NULL) { err = cmap_get_double(handle, key_name, &dbl); } else { dbl = *((double *)value); } break; case CMAP_VALUETYPE_STRING: if (value == NULL) { err = cmap_get_string(handle, key_name, &str); } else { str = (char *)value; } break; case CMAP_VALUETYPE_BINARY: if (show_binary) { if (value == NULL) { bin_value = malloc(value_len); if (bin_value == NULL) { fprintf(stderr, "Can't alloc memory\n"); exit(EXIT_FAILURE); } bin_value_len = value_len; err = cmap_get(handle, key_name, bin_value, &bin_value_len, NULL); } else { bin_value = (char *)value; } } break; } if (err == CS_OK) end_loop = 1; if (err == CS_ERR_TRY_AGAIN) { sleep(1); no_retries++; } if (no_retries > MAX_TRY_AGAIN) { end_loop = 1; } }; if (err != CS_OK) { fprintf(stderr, "Can't get value of %s. Error %s\n", key_name, cs_strerror(err)); return ; } printf("%s (", key_name); switch (type) { case CMAP_VALUETYPE_INT8: printf("%s) = %"PRId8, "i8", i8); break; case CMAP_VALUETYPE_UINT8: printf("%s) = %"PRIu8, "u8", u8); break; case CMAP_VALUETYPE_INT16: printf("%s) = %"PRId16, "i16", i16); break; case CMAP_VALUETYPE_UINT16: printf("%s) = %"PRIu16, "u16", u16); break; case CMAP_VALUETYPE_INT32: printf("%s) = %"PRId32, "i32", i32); break; case CMAP_VALUETYPE_UINT32: printf("%s) = %"PRIu32, "u32", u32); break; case CMAP_VALUETYPE_INT64: printf("%s) = %"PRId64, "i64", i64); break; case CMAP_VALUETYPE_UINT64: printf("%s) = %"PRIu64, "u64", u64); break; case CMAP_VALUETYPE_FLOAT: printf("%s) = %f", "flt", flt); break; case CMAP_VALUETYPE_DOUBLE: printf("%s) = %lf", "dbl", dbl); break; case CMAP_VALUETYPE_STRING: printf("%s) = %s", "str", str); if (value == NULL) { free(str); } break; case CMAP_VALUETYPE_BINARY: printf("%s)", "bin"); if (show_binary) { printf(" = "); if (bin_value) { print_binary_key(bin_value, value_len); if (value == NULL) { free(bin_value); } } else { printf("*empty*"); } } break; } printf("\n"); }
/* * CFG functionality stolen from node_name() in corosync-quorumtool.c * This resolves the first address assigned to a node and returns the name or IP address. */ char * corosync_node_name(uint64_t /*cmap_handle_t */ cmap_handle, uint32_t nodeid) { int lpc = 0; int rc = CS_OK; int retries = 0; char *name = NULL; cmap_handle_t local_handle = 0; /* nodeid == 0 == CMAN_NODEID_US */ if (nodeid == 0) { nodeid = get_local_nodeid(0); } if (cmap_handle == 0 && local_handle == 0) { retries = 0; crm_trace("Initializing CMAP connection"); do { rc = cmap_initialize(&local_handle); if (rc != CS_OK) { retries++; crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc), retries); sleep(retries); } } while (retries < 5 && rc != CS_OK); if (rc != CS_OK) { crm_warn("Could not connect to Cluster Configuration Database API, error %s", cs_strerror(rc)); local_handle = 0; } } if (cmap_handle == 0) { cmap_handle = local_handle; } while (name == NULL && cmap_handle != 0) { uint32_t id = 0; char *key = NULL; key = g_strdup_printf("nodelist.node.%d.nodeid", lpc); rc = cmap_get_uint32(cmap_handle, key, &id); crm_trace("Checking %u vs %u from %s", nodeid, id, key); g_free(key); if (rc != CS_OK) { break; } if (nodeid == id) { crm_trace("Searching for node name for %u in nodelist.node.%d %s", nodeid, lpc, name); if (name == NULL) { key = g_strdup_printf("nodelist.node.%d.ring0_addr", lpc); rc = cmap_get_string(cmap_handle, key, &name); crm_trace("%s = %s", key, name); if (node_name_is_valid(key, name) == FALSE) { free(name); name = NULL; } g_free(key); } if (name == NULL) { key = g_strdup_printf("nodelist.node.%d.name", lpc); rc = cmap_get_string(cmap_handle, key, &name); crm_trace("%s = %s %d", key, name, rc); g_free(key); } break; } lpc++; } if(local_handle) { cmap_finalize(local_handle); } if (name == NULL) { crm_notice("Unable to get node name for nodeid %u", nodeid); } return name; }
/* * CFG functionality stolen from node_name() in corosync-quorumtool.c * This resolves the first address assigned to a node and returns the name or IP address. */ char * corosync_node_name(uint64_t /*cmap_handle_t */ cmap_handle, uint32_t nodeid) { int lpc = 0; cs_error_t rc = CS_OK; int retries = 0; char *name = NULL; cmap_handle_t local_handle = 0; int fd = -1; uid_t found_uid = 0; gid_t found_gid = 0; pid_t found_pid = 0; int rv; if (nodeid == 0) { nodeid = get_local_nodeid(0); } if (cmap_handle == 0 && local_handle == 0) { retries = 0; crm_trace("Initializing CMAP connection"); do { rc = cmap_initialize(&local_handle); if (rc != CS_OK) { retries++; crm_debug("API connection setup failed: %s. Retrying in %ds", cs_strerror(rc), retries); sleep(retries); } } while (retries < 5 && rc != CS_OK); if (rc != CS_OK) { crm_warn("Could not connect to Cluster Configuration Database API, error %s", cs_strerror(rc)); local_handle = 0; } } if (cmap_handle == 0) { cmap_handle = local_handle; rc = cmap_fd_get(cmap_handle, &fd); if (rc != CS_OK) { crm_err("Could not obtain the CMAP API connection: %s (%d)", cs_strerror(rc), rc); goto bail; } /* CMAP provider run as root (in given user namespace, anyway)? */ if (!(rv = crm_ipc_is_authentic_process(fd, (uid_t) 0,(gid_t) 0, &found_pid, &found_uid, &found_gid))) { crm_err("CMAP provider is not authentic:" " process %lld (uid: %lld, gid: %lld)", (long long) PCMK__SPECIAL_PID_AS_0(found_pid), (long long) found_uid, (long long) found_gid); goto bail; } else if (rv < 0) { crm_err("Could not verify authenticity of CMAP provider: %s (%d)", strerror(-rv), -rv); goto bail; } } while (name == NULL && cmap_handle != 0) { uint32_t id = 0; char *key = NULL; key = crm_strdup_printf("nodelist.node.%d.nodeid", lpc); rc = cmap_get_uint32(cmap_handle, key, &id); crm_trace("Checking %u vs %u from %s", nodeid, id, key); free(key); if (rc != CS_OK) { break; } if (nodeid == id) { crm_trace("Searching for node name for %u in nodelist.node.%d %s", nodeid, lpc, name); if (name == NULL) { key = crm_strdup_printf("nodelist.node.%d.name", lpc); cmap_get_string(cmap_handle, key, &name); crm_trace("%s = %s", key, name); free(key); } if (name == NULL) { key = crm_strdup_printf("nodelist.node.%d.ring0_addr", lpc); cmap_get_string(cmap_handle, key, &name); crm_trace("%s = %s", key, name); if (node_name_is_valid(key, name) == FALSE) { free(name); name = NULL; } free(key); } break; } lpc++; } bail: if(local_handle) { cmap_finalize(local_handle); } if (name == NULL) { crm_info("Unable to get node name for nodeid %u", nodeid); } return name; }
int qdevice_cmap_get_nodelist(cmap_handle_t cmap_handle, struct node_list *list) { cs_error_t cs_err; cmap_iter_handle_t iter_handle; char key_name[CMAP_KEYNAME_MAXLEN + 1]; char tmp_key[CMAP_KEYNAME_MAXLEN + 1]; int res; int ret_value; unsigned int node_pos; uint32_t node_id; uint32_t data_center_id; char *tmp_str; char *addr0_str; int clear_node_high_byte; ret_value = 0; node_list_init(list); cs_err = cmap_iter_init(cmap_handle, "nodelist.node.", &iter_handle); if (cs_err != CS_OK) { return (-1); } while ((cs_err = cmap_iter_next(cmap_handle, iter_handle, key_name, NULL, NULL)) == CS_OK) { res = sscanf(key_name, "nodelist.node.%u.%s", &node_pos, tmp_key); if (res != 2) { continue; } if (strcmp(tmp_key, "ring0_addr") != 0) { continue; } snprintf(tmp_key, CMAP_KEYNAME_MAXLEN, "nodelist.node.%u.nodeid", node_pos); cs_err = cmap_get_uint32(cmap_handle, tmp_key, &node_id); if (cs_err == CS_ERR_NOT_EXIST) { /* * Nodeid doesn't exists -> autogenerate node id */ clear_node_high_byte = 0; if (cmap_get_string(cmap_handle, "totem.clear_node_high_bit", &tmp_str) == CS_OK) { if (strcmp (tmp_str, "yes") == 0) { clear_node_high_byte = 1; } free(tmp_str); } if (cmap_get_string(cmap_handle, key_name, &addr0_str) != CS_OK) { return (-1); } node_id = qdevice_cmap_autogenerate_node_id(addr0_str, clear_node_high_byte); free(addr0_str); } else if (cs_err != CS_OK) { ret_value = -1; goto iter_finalize; } snprintf(tmp_key, CMAP_KEYNAME_MAXLEN, "nodelist.node.%u.datacenterid", node_pos); if (cmap_get_uint32(cmap_handle, tmp_key, &data_center_id) != CS_OK) { data_center_id = 0; } if (node_list_add(list, node_id, data_center_id, TLV_NODE_STATE_NOT_SET) == NULL) { ret_value = -1; goto iter_finalize; } } iter_finalize: cmap_iter_finalize(cmap_handle, iter_handle); if (ret_value != 0) { node_list_free(list); } return (ret_value); }
int qdevice_instance_configure_from_cmap_heuristics(struct qdevice_instance *instance) { char *str; long int li; char *ep; int i; int res; cs_error_t cs_err; cmap_iter_handle_t iter_handle; char key_name[CMAP_KEYNAME_MAXLEN + 1]; size_t value_len; cmap_value_types_t type; struct qdevice_heuristics_exec_list tmp_exec_list; struct qdevice_heuristics_exec_list *exec_list; char *command; char exec_name[CMAP_KEYNAME_MAXLEN + 1]; char tmp_key[CMAP_KEYNAME_MAXLEN + 1]; size_t no_execs; int send_exec_list; instance->heuristics_instance.timeout = instance->heartbeat_interval / 2; if (cmap_get_string(instance->cmap_handle, "quorum.device.heuristics.timeout", &str) == CS_OK) { li = strtol(str, &ep, 10); if (li < instance->advanced_settings->heuristics_min_timeout || li > instance->advanced_settings->heuristics_max_timeout || *ep != '\0') { qdevice_log(LOG_ERR, "heuristics.timeout must be valid number in " "range <%"PRIu32",%"PRIu32">", instance->advanced_settings->heuristics_min_timeout, instance->advanced_settings->heuristics_max_timeout); free(str); return (-1); } else { instance->heuristics_instance.timeout = li; } free(str); } instance->heuristics_instance.sync_timeout = instance->sync_heartbeat_interval / 2; if (cmap_get_string(instance->cmap_handle, "quorum.device.heuristics.sync_timeout", &str) == CS_OK) { li = strtol(str, &ep, 10); if (li < instance->advanced_settings->heuristics_min_timeout || li > instance->advanced_settings->heuristics_max_timeout || *ep != '\0') { qdevice_log(LOG_ERR, "heuristics.sync_timeout must be valid number in " "range <%"PRIu32",%"PRIu32">", instance->advanced_settings->heuristics_min_timeout, instance->advanced_settings->heuristics_max_timeout); free(str); return (-1); } else { instance->heuristics_instance.sync_timeout = li; } free(str); } instance->heuristics_instance.interval = instance->heartbeat_interval * 3; if (cmap_get_string(instance->cmap_handle, "quorum.device.heuristics.interval", &str) == CS_OK) { li = strtol(str, &ep, 10); if (li < instance->advanced_settings->heuristics_min_interval || li > instance->advanced_settings->heuristics_max_interval || *ep != '\0') { qdevice_log(LOG_ERR, "heuristics.interval must be valid number in " "range <%"PRIu32",%"PRIu32">", instance->advanced_settings->heuristics_min_interval, instance->advanced_settings->heuristics_max_interval); free(str); return (-1); } else { instance->heuristics_instance.interval = li; } free(str); } instance->heuristics_instance.mode = QDEVICE_DEFAULT_HEURISTICS_MODE; if (cmap_get_string(instance->cmap_handle, "quorum.device.heuristics.mode", &str) == CS_OK) { if ((i = utils_parse_bool_str(str)) == -1) { if (strcasecmp(str, "sync") != 0) { qdevice_log(LOG_ERR, "quorum.device.heuristics.mode value is not valid."); free(str); return (-1); } else { instance->heuristics_instance.mode = QDEVICE_HEURISTICS_MODE_SYNC; } } else { if (i == 1) { instance->heuristics_instance.mode = QDEVICE_HEURISTICS_MODE_ENABLED; } else { instance->heuristics_instance.mode = QDEVICE_HEURISTICS_MODE_DISABLED; } } free(str); } send_exec_list = 0; exec_list = NULL; qdevice_heuristics_exec_list_init(&tmp_exec_list); if (instance->heuristics_instance.mode == QDEVICE_HEURISTICS_MODE_DISABLED) { exec_list = NULL; send_exec_list = 1; } else if (instance->heuristics_instance.mode == QDEVICE_HEURISTICS_MODE_ENABLED || instance->heuristics_instance.mode == QDEVICE_HEURISTICS_MODE_SYNC) { /* * Walk thru list of commands to exec */ cs_err = cmap_iter_init(instance->cmap_handle, "quorum.device.heuristics.exec_", &iter_handle); if (cs_err != CS_OK) { qdevice_log(LOG_ERR, "Can't iterate quorum.device.heuristics.exec_ keys. " "Error %s", cs_strerror(cs_err)); return (-1); } while ((cs_err = cmap_iter_next(instance->cmap_handle, iter_handle, key_name, &value_len, &type)) == CS_OK) { if (type != CMAP_VALUETYPE_STRING) { qdevice_log(LOG_WARNING, "%s key is not of string type. Ignoring"); continue ; } res = sscanf(key_name, "quorum.device.heuristics.exec_%[^.]%s", exec_name, tmp_key); if (res != 1) { qdevice_log(LOG_WARNING, "%s key is not correct heuristics exec name. Ignoring"); continue ; } cs_err = cmap_get_string(instance->cmap_handle, key_name, &command); if (cs_err != CS_OK) { qdevice_log(LOG_WARNING, "Can't get value of %s key. Ignoring"); continue ; } if (qdevice_heuristics_exec_list_add(&tmp_exec_list, exec_name, command) == NULL) { qdevice_log(LOG_WARNING, "Can't store value of %s key into list. Ignoring"); } free(command); } no_execs = qdevice_heuristics_exec_list_size(&tmp_exec_list); if (no_execs == 0) { qdevice_log(LOG_INFO, "No valid heuristics execs defined. Disabling heuristics."); instance->heuristics_instance.mode = QDEVICE_HEURISTICS_MODE_DISABLED; exec_list = NULL; send_exec_list = 1; } else if (no_execs > instance->advanced_settings->heuristics_max_execs) { qdevice_log(LOG_ERR, "Too much (%zu) heuristics execs defined (max is %zu)." " Disabling heuristics.", no_execs, instance->advanced_settings->heuristics_max_execs); instance->heuristics_instance.mode = QDEVICE_HEURISTICS_MODE_DISABLED; exec_list = NULL; send_exec_list = 1; } else if (qdevice_heuristics_exec_list_eq(&tmp_exec_list, &instance->heuristics_instance.exec_list) == 1) { qdevice_log(LOG_DEBUG, "Heuristics list is unchanged"); send_exec_list = 0; } else { qdevice_log(LOG_DEBUG, "Heuristics list changed"); exec_list = &tmp_exec_list; send_exec_list = 1; } } else { qdevice_log(LOG_CRIT, "Undefined heuristics mode"); exit(1); } if (send_exec_list) { if (qdevice_heuristics_change_exec_list(&instance->heuristics_instance, exec_list, instance->sync_in_progress) != 0) { return (-1); } } qdevice_heuristics_exec_list_free(&tmp_exec_list); return (0); }