Exemple #1
0
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);
}
Exemple #6
0
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);
}
Exemple #7
0
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;
}
Exemple #8
0
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);
}
Exemple #9
0
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);
}