int corosync_cmap_has_config(const char *prefix) { int rc = CS_OK; int retries = 0; static int found = -1; cmap_handle_t cmap_handle; cmap_iter_handle_t iter_handle; char key_name[CMAP_KEYNAME_MAXLEN + 1]; if(found != -1) { return found; } do { rc = cmap_initialize(&cmap_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: %s (rc=%d)", cs_strerror(rc), rc); return -1; } rc = cmap_iter_init(cmap_handle, prefix, &iter_handle); if (rc != CS_OK) { crm_warn("Failed to initialize iteration for corosync cmap '%s': %s (rc=%d)", prefix, cs_strerror(rc), rc); goto bail; } found = 0; while ((rc = cmap_iter_next(cmap_handle, iter_handle, key_name, NULL, NULL)) == CS_OK) { crm_trace("'%s' is configured in corosync cmap: %s", prefix, key_name); found++; break; } cmap_iter_finalize(cmap_handle, iter_handle); bail: cmap_finalize(cmap_handle); return found; }
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 void print_iter(cmap_handle_t handle, const char *prefix) { cmap_iter_handle_t iter_handle; char key_name[CMAP_KEYNAME_MAXLEN + 1]; size_t value_len; cmap_value_types_t type; cs_error_t err; err = cmap_iter_init(handle, prefix, &iter_handle); if (err != CS_OK) { fprintf (stderr, "Failed to initialize iteration. Error %s\n", cs_strerror(err)); exit (EXIT_FAILURE); } while ((err = cmap_iter_next(handle, iter_handle, key_name, &value_len, &type)) == CS_OK) { print_key(handle, key_name, value_len, NULL, type); } cmap_iter_finalize(handle, iter_handle); }
static void delete_with_prefix(cmap_handle_t handle, const char *prefix) { cmap_iter_handle_t iter_handle; char key_name[CMAP_KEYNAME_MAXLEN + 1]; size_t value_len; cmap_value_types_t type; cs_error_t err; cs_error_t err2; err = cmap_iter_init(handle, prefix, &iter_handle); if (err != CS_OK) { fprintf (stderr, "Failed to initialize iteration. Error %s\n", cs_strerror(err)); exit (EXIT_FAILURE); } while ((err = cmap_iter_next(handle, iter_handle, key_name, &value_len, &type)) == CS_OK) { err2 = cmap_delete(handle, key_name); if (err2 != CS_OK) { fprintf(stderr, "Can't delete key %s. Error %s\n", key_name, cs_strerror(err2)); } } cmap_iter_finalize(handle, iter_handle); }
static void track_link_updown_events(void) { cmap_iter_handle_t iter_handle; cmap_track_handle_t track_handle; char key_name[CMAP_KEYNAME_MAXLEN + 1]; size_t value_len; cmap_value_types_t type; cs_error_t err; struct track_item *track_item; err = cmap_iter_init(stats_handle, "stats.knet.", &iter_handle); if (err != CS_OK) { fprintf (stderr, "Failed to initialize knet stats iterator. Error %s\n", cs_strerror(err)); exit (EXIT_FAILURE); } while ((err = cmap_iter_next(stats_handle, iter_handle, key_name, &value_len, &type)) == CS_OK) { if (strstr(key_name, ".connected")) { track_item = malloc(sizeof(struct track_item)); if (!track_item) { return; } if ((err = cmap_track_add(stats_handle, key_name, CMAP_TRACK_MODIFY, _cs_cmap_link_faulty_key_changed, NULL, &track_handle)) != CS_OK) { fprintf (stderr, "Failed to add tracker for %s. Error %s\n", key_name, cs_strerror(err)); exit (EXIT_FAILURE); } strcpy(track_item->key_name, key_name); track_item->track_handle = track_handle; qb_map_put(tracker_map, track_item->key_name, track_item); } } cmap_iter_finalize(stats_handle, iter_handle); }
static int corosync_main_config_read_logging ( const char **error_string) { const char *error_reason; #ifdef LOGCONFIG_USE_ICMAP icmap_iter_t iter; const char *key_name; #else cmap_iter_handle_t iter; char key_name[CMAP_KEYNAME_MAXLEN]; #endif char key_subsys[MAP_KEYNAME_MAXLEN]; char key_item[MAP_KEYNAME_MAXLEN]; int res; /* format set is supported only for toplevel */ if (corosync_main_config_format_set(&error_reason) < 0) { goto parse_error; } if (corosync_main_config_set ("logging", NULL, &error_reason) < 0) { goto parse_error; } /* * we will need 2 of these to compensate for new logging * config format */ #ifdef LOGCONFIG_USE_ICMAP iter = icmap_iter_init("logging.logger_subsys."); while ((key_name = icmap_iter_next(iter, NULL, NULL)) != NULL) { #else cmap_iter_init(cmap_handle, "logging.logger_subsys.", &iter); while ((cmap_iter_next(cmap_handle, iter, key_name, NULL, NULL)) == CS_OK) { #endif res = sscanf(key_name, "logging.logger_subsys.%[^.].%s", key_subsys, key_item); if (res != 2) { continue ; } if (strcmp(key_item, "subsys") != 0) { continue ; } snprintf(key_item, MAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s", key_subsys); if (corosync_main_config_set(key_item, key_subsys, &error_reason) < 0) { goto parse_error; } } #ifdef LOGCONFIG_USE_ICMAP icmap_iter_finalize(iter); #else cmap_iter_finalize(cmap_handle, iter); #endif logsys_config_apply(); return 0; parse_error: *error_string = error_reason; return (-1); } #ifdef LOGCONFIG_USE_ICMAP static void main_logging_notify( int32_t event, const char *key_name, struct icmap_notify_value new_val, struct icmap_notify_value old_val, void *user_data) #else static void main_logging_notify( cmap_handle_t cmap_handle_unused, cmap_handle_t cmap_track_handle_unused, int32_t event, const char *key_name, struct cmap_notify_value new_val, struct cmap_notify_value old_val, void *user_data) #endif { const char *error_string; static int reload_in_progress = 0; /* If a full reload happens then suspend updates for individual keys until * it's all completed */ if (strcmp(key_name, "config.reload_in_progress") == 0) { if (*(uint8_t *)new_val.data == 1) { reload_in_progress = 1; } else { reload_in_progress = 0; } } if (reload_in_progress) { log_printf(LOGSYS_LEVEL_DEBUG, "Ignoring key change, reload in progress. %s\n", key_name); return; } /* * Reload the logsys configuration */ if (logsys_format_set(NULL) == -1) { fprintf (stderr, "Unable to setup logging format.\n"); } corosync_main_config_read_logging(&error_string); } #ifdef LOGCONFIG_USE_ICMAP static void add_logsys_config_notification(void) { icmap_track_t icmap_track = NULL; icmap_track_add("logging.", ICMAP_TRACK_ADD | ICMAP_TRACK_DELETE | ICMAP_TRACK_MODIFY | ICMAP_TRACK_PREFIX, main_logging_notify, NULL, &icmap_track); icmap_track_add("config.reload_in_progress", ICMAP_TRACK_ADD | ICMAP_TRACK_MODIFY, main_logging_notify, NULL, &icmap_track); }
int corosync_cmap_has_config(const char *prefix) { cs_error_t rc = CS_OK; int retries = 0; static int found = -1; cmap_handle_t cmap_handle; cmap_iter_handle_t iter_handle; char key_name[CMAP_KEYNAME_MAXLEN + 1]; int fd = -1; uid_t found_uid = 0; gid_t found_gid = 0; pid_t found_pid = 0; int rv; if(found != -1) { return found; } do { rc = cmap_initialize(&cmap_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: %s (rc=%d)", cs_strerror(rc), rc); return -1; } 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; } rc = cmap_iter_init(cmap_handle, prefix, &iter_handle); if (rc != CS_OK) { crm_warn("Failed to initialize iteration for corosync cmap '%s': %s (rc=%d)", prefix, cs_strerror(rc), rc); goto bail; } found = 0; while ((rc = cmap_iter_next(cmap_handle, iter_handle, key_name, NULL, NULL)) == CS_OK) { crm_trace("'%s' is configured in corosync cmap: %s", prefix, key_name); found++; break; } cmap_iter_finalize(cmap_handle, iter_handle); bail: cmap_finalize(cmap_handle); return found; }
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); }