Beispiel #1
0
int
qdevice_cmap_del_track(struct qdevice_instance *instance)
{
	cs_error_t res;

	res = cmap_track_delete(instance->cmap_handle, instance->cmap_reload_track_handle);
	if (res != CS_OK) {
		qdevice_log(LOG_WARNING, "Can't delete cmap totemconfig_reload_in_progress tracking");
	}

	res = cmap_track_delete(instance->cmap_handle, instance->cmap_nodelist_track_handle);
	if (res != CS_OK) {
		qdevice_log(LOG_WARNING, "Can't delete cmap nodelist tracking");
	}

	res = cmap_track_delete(instance->cmap_handle, instance->cmap_logging_track_handle);
	if (res != CS_OK) {
		qdevice_log(LOG_WARNING, "Can't delete cmap logging tracking");
	}

	res = cmap_track_delete(instance->cmap_handle, instance->cmap_heuristics_track_handle);
	if (res != CS_OK) {
		qdevice_log(LOG_WARNING, "Can't delete cmap heuristics tracking");
	}

	return (0);
}
static int
qdevice_net_msg_received_echo_reply(struct qdevice_net_instance *instance,
    const struct msg_decoded *msg)
{

	if (!msg->seq_number_set) {
		qdevice_log(LOG_ERR, "Received echo reply message doesn't contain seq_number.");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_REQUIRED_OPTION_MISSING;
		return (-1);
	}

	if (msg->seq_number != instance->echo_request_expected_msg_seq_num) {
		qdevice_log(LOG_WARNING, "Received echo reply message seq_number is not expected one.");
	}

	if (qdevice_net_algorithm_echo_reply_received(instance, msg->seq_number,
	    msg->seq_number == instance->echo_request_expected_msg_seq_num) != 0) {
		qdevice_log(LOG_DEBUG, "Algorithm returned error. Disconnecting");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_ECHO_REPLY_RECEIVED_ERR;
		return (-1);
	}

	instance->echo_reply_received_msg_seq_num = msg->seq_number;
	instance->last_echo_reply_received_time = time(NULL);

	return (0);
}
Beispiel #3
0
int
qdevice_model_net_destroy(struct qdevice_instance *instance)
{
	struct qdevice_net_instance *net_instance;

	net_instance = instance->model_data;

	qdevice_log(LOG_DEBUG, "Destroying algorithm");
	qdevice_net_algorithm_destroy(net_instance);

	qdevice_log(LOG_DEBUG, "Destroying qdevice_net_instance");
	qdevice_net_instance_destroy(net_instance);

	qdevice_log(LOG_DEBUG, "Shutting down NSS");
	SSL_ClearSessionCache();

	if (NSS_Shutdown() != SECSuccess) {
		qdevice_log_nss(LOG_WARNING, "Can't shutdown NSS");
	}

	if (PR_Cleanup() != PR_SUCCESS) {
		qdevice_log_nss(LOG_WARNING, "Can't shutdown NSPR");
	}

	free(net_instance);

	return (0);
}
int
qdevice_net_algorithm_register_all(void)
{

	if (qdevice_net_algo_test_register() != 0) {
		qdevice_log(LOG_CRIT, "Failed to register decision algorithm 'test' ");
		return (-1);
	}

	if (qdevice_net_algo_ffsplit_register() != 0) {
		qdevice_log(LOG_CRIT, "Failed to register decision algorithm 'ffsplit' ");
		return (-1);
	}

	if (qdevice_net_algo_2nodelms_register() != 0) {
		qdevice_log(LOG_CRIT, "Failed to register decision algorithm '2nodelms' ");
		return (-1);
	}

	if (qdevice_net_algo_lms_register() != 0) {
		qdevice_log(LOG_CRIT, "Failed to register decision algorithm 'lms' ");
		return (-1);
	}

	return (0);
}
/*
 * 0 - No error
 * 1 - Error
 */
int
qdevice_heuristics_cmd_write(struct qdevice_heuristics_instance *instance)
{
	struct send_buffer_list_entry *send_buffer;
	int res;

	send_buffer = send_buffer_list_get_active(&instance->cmd_out_buffer_list);
	if (send_buffer == NULL) {
		qdevice_log(LOG_CRIT, "send_buffer_list_get_active in qdevice_heuristics_cmd_write returned NULL");

		return (-1);
	}

	res = qdevice_heuristics_io_write(instance->pipe_cmd_send, &send_buffer->buffer,
	    &send_buffer->msg_already_sent_bytes);

	if (res == 1) {
		send_buffer_list_delete(&instance->cmd_out_buffer_list, send_buffer);
	}

	if (res == -1) {
		qdevice_log(LOG_CRIT, "qdevice_heuristics_io_write returned -1 (write returned 0)");

		return (-1);
	}

	if (res == -2) {
		qdevice_log(LOG_CRIT, "Unhandled error in during sending message to heuristics "
		    "worker (qdevice_heuristics_io_write returned -2)");

		return (-1);
	}

	return (0);
}
Beispiel #6
0
/*
 * Called when cmap reload (or nodelist) was requested.
 *
 * nlist is node list
 * config_version is valid only if config_version_set != 0
 *
 * Should return 0 if processing should continue or -1 to call exit
 */
int
qdevice_model_net_config_node_list_changed(struct qdevice_instance *instance,
    const struct node_list *nlist, int config_version_set, uint64_t config_version)
{
	struct qdevice_net_instance *net_instance;
	int send_node_list;
	enum tlv_vote vote;

	net_instance = instance->model_data;

	if (net_instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS) {
		/*
		 * Nodelist changed, but connection to qnetd not initiated yet.
		 */
		send_node_list = 0;

		if (net_instance->cast_vote_timer_vote == TLV_VOTE_ACK) {
			vote = TLV_VOTE_NACK;
		} else {
			vote = TLV_VOTE_NO_CHANGE;
		}
	} else {
		send_node_list = 1;
		vote = TLV_VOTE_NO_CHANGE;
	}

	if (qdevice_net_algorithm_config_node_list_changed(net_instance, nlist, config_version_set,
	    config_version, &send_node_list, &vote) != 0) {
		qdevice_log(LOG_ERR, "Algorithm returned error, Disconnecting");

		net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_CONFIG_NODE_LIST_CHANGED_ERR;
		net_instance->schedule_disconnect = 1;

		return (0);
	} else {
		qdevice_log(LOG_DEBUG, "Algorithm decided to %s node list and result vote is %s",
		    (send_node_list ? "send" : "not send"), tlv_vote_to_str(vote));
	}

	if (qdevice_net_cast_vote_timer_update(net_instance, vote) != 0) {
		qdevice_log(LOG_CRIT, "qdevice_model_net_config_node_list_changed fatal error. "
				" Can't update cast vote timer vote");
		net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER;
		net_instance->schedule_disconnect = 1;

		return (0);
	}

	if (send_node_list) {
		if (qdevice_net_send_config_node_list(net_instance, nlist, config_version_set,
		    config_version, 0) != 0) {
			net_instance->schedule_disconnect = 1;
			net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER;

			return (0);
		}
	}

	return (0);
}
int
qdevice_heuristics_cmd_write_exec_list(struct qdevice_heuristics_instance *instance,
    const struct qdevice_heuristics_exec_list *new_exec_list)
{
	struct send_buffer_list_entry *send_buffer;
	struct qdevice_heuristics_exec_list_entry *entry;

	send_buffer = send_buffer_list_get_new(&instance->cmd_out_buffer_list);
	if (send_buffer == NULL) {
		qdevice_log(LOG_ERR, "Can't alloc send list for cmd change exec list");

		return (-1);
	}

	if (dynar_str_cpy(&send_buffer->buffer, QDEVICE_HEURISTICS_CMD_STR_EXEC_LIST_CLEAR) == -1 ||
	    dynar_str_cat(&send_buffer->buffer, "\n") == -1) {
		qdevice_log(LOG_ERR, "Can't alloc list clear message");

		send_buffer_list_discard_new(&instance->cmd_out_buffer_list, send_buffer);

		return (-1);
	}

	send_buffer_list_put(&instance->cmd_out_buffer_list, send_buffer);

	if (new_exec_list == NULL) {
		return (0);
	}

	/*
	 * new_exec_list is not NULL, send it
	 */
	TAILQ_FOREACH(entry, new_exec_list, entries) {
		send_buffer = send_buffer_list_get_new(&instance->cmd_out_buffer_list);
		if (send_buffer == NULL) {
			qdevice_log(LOG_ERR, "Can't alloc send list for cmd change exec list");

			return (-1);
		}

		if (dynar_str_cpy(&send_buffer->buffer,
		    QDEVICE_HEURISTICS_CMD_STR_EXEC_LIST_ADD_SPACE) == -1 ||
		    dynar_str_cat(&send_buffer->buffer, entry->name) == -1 ||
		    dynar_str_cat(&send_buffer->buffer, " ") == -1 ||
		    dynar_str_cat(&send_buffer->buffer, entry->command) == -1 ||
		    qdevice_heuristics_cmd_remove_newlines(&send_buffer->buffer) == -1 ||
		    dynar_str_cat(&send_buffer->buffer, "\n") == -1) {
			qdevice_log(LOG_ERR, "Can't alloc list add message");

			send_buffer_list_discard_new(&instance->cmd_out_buffer_list, send_buffer);

			return (-1);
		}

		send_buffer_list_put(&instance->cmd_out_buffer_list, send_buffer);
	}
Beispiel #8
0
static void
qdevice_cmap_heuristics_event(struct qdevice_instance *instance)
{

	qdevice_log(LOG_DEBUG, "Heuristics configuration possibly changed");
	if (qdevice_instance_configure_from_cmap_heuristics(instance) != 0) {
		qdevice_log(LOG_DEBUG, "qdevice_instance_configure_from_cmap_heuristics returned error -> exit");
		exit(2);
	}
}
/*
 * 1 - Line processed
 * 0 - No line to process - everything processed
 * -1 - Error
 */
static int
qdevice_heuristics_cmd_process_one_line(struct qdevice_heuristics_instance *instance,
    struct dynar *data)
{
	char *str;
	size_t str_len;
	size_t nl_pos;
	size_t zi;

	str = dynar_data(data);
	str_len = dynar_size(data);

	/*
	 * Find valid line
	 */
	for (zi = 0; zi < str_len && str[zi] != '\r' && str[zi] != '\n'; zi++) ;

	if (zi >= str_len) {
		/*
		 * Command is not yet fully readed
		 */
		return (0);
	}

	nl_pos = zi;

	str[nl_pos] = '\0';

	if (strncmp(str, QDEVICE_HEURISTICS_CMD_STR_EXEC_RESULT_ADD_SPACE,
	    strlen(QDEVICE_HEURISTICS_CMD_STR_EXEC_RESULT_ADD_SPACE)) == 0) {
		if (qdevice_heuristics_cmd_process_exec_result(instance, data) != 0) {
			return (-1);
		}
	} else {
		qdevice_log(LOG_CRIT,
		    "Heuristics worker sent unknown command \"%s\"", str);

		    return (-1);
	}

	/*
	 * Find place where is begining of new "valid" line
	 */
	for (zi = nl_pos + 1; zi < str_len && (str[zi] == '\0' || str[zi] == '\n' || str[zi] == '\r'); zi++) ;

	memmove(str, str + zi, str_len - zi);
	if (dynar_set_size(data, str_len - zi) == -1) {
		qdevice_log(LOG_CRIT,
		    "qdevice_heuristics_cmd_process_one_line: Can't set dynar size");
		return (-1);
	}

	return (1);
}
static int
qdevice_net_msg_received_ask_for_vote_reply(struct qdevice_net_instance *instance,
    const struct msg_decoded *msg)
{
	enum tlv_vote result_vote;
	int ring_id_is_valid;

	if (instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS) {
		qdevice_log(LOG_ERR, "Received unexpected ask for vote reply message. "
		    "Disconnecting from server");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_UNEXPECTED_MSG;
		return (-1);
	}

	if (!msg->vote_set || !msg->seq_number_set || !msg->ring_id_set) {
		qdevice_log(LOG_ERR, "Received node list reply message without "
		    "required options. Disconnecting from server");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_REQUIRED_OPTION_MISSING;
		return (-1);
	}

	qdevice_log(LOG_DEBUG, "Received ask for vote reply");
	qdevice_log(LOG_DEBUG, "  seq = "UTILS_PRI_MSG_SEQ, msg->seq_number);
	qdevice_log(LOG_DEBUG, "  vote = %s", tlv_vote_to_str(msg->vote));
	qdevice_log(LOG_DEBUG, "  ring id = ("UTILS_PRI_RING_ID")",
		    msg->ring_id.node_id, msg->ring_id.seq);

	result_vote = msg->vote;

	if (!tlv_ring_id_eq(&msg->ring_id, &instance->last_sent_ring_id)) {
		ring_id_is_valid = 0;
		qdevice_log(LOG_DEBUG, "Received ask for vote reply with old ring id.");
	} else {
		ring_id_is_valid = 1;
	}

	if (qdevice_net_algorithm_ask_for_vote_reply_received(instance, msg->seq_number,
	    &msg->ring_id, ring_id_is_valid, &result_vote) != 0) {
		qdevice_log(LOG_DEBUG, "Algorithm returned error. Disconnecting.");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_ASK_FOR_VOTE_REPLY_ERR;
		return (-1);
	} else {
		qdevice_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(result_vote));
	}

	if (qdevice_net_cast_vote_timer_update(instance, result_vote) != 0) {
		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER;
		return (-1);
	}

	return (0);
}
Beispiel #11
0
static void
qdevice_cmap_node_list_event(struct qdevice_instance *instance)
{
	struct node_list nlist;
	int config_version_set;
	uint64_t config_version;

	qdevice_log(LOG_DEBUG, "Node list configuration possibly changed");
	if (qdevice_cmap_get_nodelist(instance->cmap_handle, &nlist) != 0) {
		qdevice_log(LOG_ERR, "Can't get configuration node list.");

		if (qdevice_model_get_config_node_list_failed(instance) != 0) {
			qdevice_log(LOG_DEBUG, "qdevice_model_get_config_node_list_failed returned error -> exit");
			exit(2);
		}

		return ;
	}

	config_version_set = (qdevice_cmap_get_config_version(instance->cmap_handle,
	    &config_version) == 0);

	if (node_list_eq(&instance->config_node_list, &nlist)) {
		return ;
	}

	qdevice_log(LOG_DEBUG, "Node list changed");
	if (config_version_set) {
		qdevice_log(LOG_DEBUG, "  config_version = "UTILS_PRI_CONFIG_VERSION, config_version);
	}
	qdevice_log_debug_dump_node_list(&nlist);

	if (qdevice_model_config_node_list_changed(instance, &nlist,
	    config_version_set, config_version) != 0) {
		qdevice_log(LOG_DEBUG, "qdevice_model_config_node_list_changed returned error -> exit");
		exit(2);
	}

	node_list_free(&instance->config_node_list);
	if (node_list_clone(&instance->config_node_list, &nlist) != 0) {
		qdevice_log(LOG_ERR, "Can't allocate instance->config_node_list clone");

		node_list_free(&nlist);

		if (qdevice_model_get_config_node_list_failed(instance) != 0) {
			qdevice_log(LOG_DEBUG, "qdevice_model_get_config_node_list_failed returned error -> exit");
			exit(2);
		}

		return ;
	}

	instance->config_node_list_version_set = config_version_set;

	if (config_version_set) {
		instance->config_node_list_version = config_version;
	}
}
Beispiel #12
0
int
qdevice_model_net_cmap_changed(struct qdevice_instance *instance,
    const struct qdevice_cmap_change_events *events)
{
	struct qdevice_net_instance *net_instance;
	enum qdevice_heuristics_mode active_heuristics_mode;
	int heuristics_enabled;

	net_instance = instance->model_data;

	if (events->heuristics) {
		active_heuristics_mode = instance->heuristics_instance.mode;
		heuristics_enabled = (active_heuristics_mode == QDEVICE_HEURISTICS_MODE_ENABLED ||
		    active_heuristics_mode == QDEVICE_HEURISTICS_MODE_SYNC);

		if (net_instance->state == QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS &&
		    !net_instance->server_supports_heuristics && heuristics_enabled) {
			qdevice_log(LOG_ERR, "Heuristics are enabled but not supported by the server");

			net_instance->disconnect_reason =
			    QDEVICE_NET_DISCONNECT_REASON_SERVER_DOESNT_SUPPORT_REQUIRED_OPT;

			net_instance->schedule_disconnect = 1;

			return (0);
		}

		if (qdevice_net_heuristics_schedule_timer(net_instance) != 0) {
			return (0);
		}
	}

	return (0);
}
Beispiel #13
0
static void
qdevice_cmap_logging_event(struct qdevice_instance *instance)
{

	qdevice_log(LOG_DEBUG, "Logging configuration possibly changed");
	qdevice_log_configure(instance);
}
Beispiel #14
0
void
qdevice_log_debug_dump_node_list(const struct node_list *nlist)
{
	struct node_list_entry *node_info;
	size_t zi;

	qdevice_log(LOG_DEBUG, "  Node list:");

	zi = 0;

	TAILQ_FOREACH(node_info, nlist, entries) {
		qdevice_log(LOG_DEBUG, "    %zu node_id = "UTILS_PRI_NODE_ID", "
		    "data_center_id = "UTILS_PRI_DATACENTER_ID", node_state = %s",
		    zi, node_info->node_id, node_info->data_center_id,
		    tlv_node_state_to_str(node_info->node_state));
		zi++;
	}
Beispiel #15
0
int
qdevice_cmap_add_track(struct qdevice_instance *instance)
{
	cs_error_t res;

	res = cmap_track_add(instance->cmap_handle, "config.totemconfig_reload_in_progress",
	    CMAP_TRACK_ADD | CMAP_TRACK_MODIFY, qdevice_cmap_reload_cb,
	    NULL, &instance->cmap_reload_track_handle);

	if (res != CS_OK) {
		qdevice_log(LOG_ERR, "Can't initialize cmap totemconfig_reload_in_progress tracking");
		return (-1);
	}

	res = cmap_track_add(instance->cmap_handle, "nodelist.",
	    CMAP_TRACK_ADD | CMAP_TRACK_DELETE | CMAP_TRACK_MODIFY | CMAP_TRACK_PREFIX,
	    qdevice_cmap_reload_cb,
	    NULL, &instance->cmap_nodelist_track_handle);

	if (res != CS_OK) {
		qdevice_log(LOG_ERR, "Can't initialize cmap nodelist tracking");
		return (-1);
	}

	res = cmap_track_add(instance->cmap_handle, "logging.",
	    CMAP_TRACK_ADD | CMAP_TRACK_DELETE | CMAP_TRACK_MODIFY | CMAP_TRACK_PREFIX,
	    qdevice_cmap_reload_cb,
	    NULL, &instance->cmap_logging_track_handle);

	if (res != CS_OK) {
		qdevice_log(LOG_ERR, "Can't initialize logging tracking");
		return (-1);
	}

	res = cmap_track_add(instance->cmap_handle, "quorum.device.heuristics.",
	    CMAP_TRACK_ADD | CMAP_TRACK_DELETE | CMAP_TRACK_MODIFY | CMAP_TRACK_PREFIX,
	    qdevice_cmap_reload_cb,
	    NULL, &instance->cmap_heuristics_track_handle);

	if (res != CS_OK) {
		qdevice_log(LOG_ERR, "Can't initialize logging tracking");
		return (-1);
	}

	return (0);
}
Beispiel #16
0
static int
qdevice_heuristics_cmd_process_exec_result(struct qdevice_heuristics_instance *instance,
    struct dynar *data)
{
	uint32_t seq_number;
	char *str;
	enum qdevice_heuristics_exec_result exec_result;

	str = dynar_data(data);

	if (sscanf(str, QDEVICE_HEURISTICS_CMD_STR_EXEC_RESULT_ADD_SPACE "%"PRIu32" %u", &seq_number,
	    &exec_result) != 2) {
		qdevice_log(LOG_CRIT, "Can't parse exec result command (sscanf)");

		return (-1);
	}

	qdevice_log(LOG_DEBUG,
	    "Received heuristics exec result command with seq_no \"%"PRIu32"\" and result \"%s\"", seq_number,
	    qdevice_heuristics_exec_result_to_str(exec_result));

	if (!instance->waiting_for_result) {
		qdevice_log(LOG_DEBUG, "Received exec result is not expected. Ignoring.");

		return (0);
	}

	if (seq_number != instance->expected_reply_seq_number) {
		qdevice_log(LOG_DEBUG, "Received heuristics exec result seq number %"PRIu32
		    " is not expected one (expected %"PRIu32"). Ignoring.", seq_number,
		    instance->expected_reply_seq_number);

		return (0);
	}

	instance->waiting_for_result = 0;

	if (qdevice_heuristics_result_notifier_notify(&instance->exec_result_notifier_list,
	    (void *)instance, seq_number, exec_result) != 0) {
		qdevice_log(LOG_DEBUG, "qdevice_heuristics_result_notifier_notify returned non-zero result");
		return (-1);
	}

	return (0);
}
static int
qdevice_net_msg_received_server_error(struct qdevice_net_instance *instance,
    const struct msg_decoded *msg)
{

	if (!msg->reply_error_code_set) {
		qdevice_log(LOG_ERR, "Received server error without error code set. "
		    "Disconnecting from server");

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_REQUIRED_OPTION_MISSING;
	} else {
		qdevice_log(LOG_ERR, "Received server error %"PRIu16". "
		    "Disconnecting from server", msg->reply_error_code);

		instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_SERVER_SENT_ERROR;
	}

	return (-1);
}
Beispiel #18
0
void
qdevice_cmap_destroy(struct qdevice_instance *instance)
{
	cs_error_t res;

	res = cmap_finalize(instance->cmap_handle);

	if (res != CS_OK) {
		qdevice_log(LOG_WARNING, "Can't finalize cmap. Error %s", cs_strerror(res));
	}
}
Beispiel #19
0
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);
}
int
qdevice_net_algorithm_init(struct qdevice_net_instance *instance)
{

	if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
	    qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) {
		qdevice_log(LOG_CRIT, "qdevice_net_algorithm_init unhandled decision algorithm");
		exit(1);
	}

	return (qdevice_net_algorithm_array[instance->decision_algorithm]->init(instance));
}
static int
qdevice_net_msg_received_unexpected_msg(struct qdevice_net_instance *instance,
    const struct msg_decoded *msg, const char *msg_str)
{

	qdevice_log(LOG_ERR, "Received unexpected %s message. Disconnecting from server",
	    msg_str);

	instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_UNEXPECTED_MSG;

	return (-1);
}
static void
qdevice_net_msg_received_log_msg_decode_error(int ret)
{

	switch (ret) {
	case -1:
		qdevice_log(LOG_WARNING, "Received message with option with invalid length");
		break;
	case -2:
		qdevice_log(LOG_CRIT, "Can't allocate memory");
		break;
	case -3:
		qdevice_log(LOG_WARNING, "Received inconsistent msg (tlv len > msg size)");
		break;
	case -4:
		qdevice_log(LOG_ERR, "Received message with option with invalid value");
		break;
	default:
		qdevice_log(LOG_ERR, "Unknown error occurred when decoding message");
		break;
	}
}
Beispiel #23
0
/*
 * 0 - No error
 * 1 - Error
 */
int
qdevice_heuristics_cmd_read_from_pipe(struct qdevice_heuristics_instance *instance)
{
	int res;
	int ret;

	res = qdevice_heuristics_io_read(instance->pipe_cmd_recv, &instance->cmd_in_buffer);

	ret = 0;

	switch (res) {
	case 0:
		/*
		 * Partial read
		 */
		break;
	case -1:
		qdevice_log(LOG_ERR, "Lost connection with heuristics worker");
		ret = -1;
		break;
	case -2:
		qdevice_log(LOG_ERR, "Heuristics worker sent too long cmd.");
		ret = -1;
		break;
	case -3:
		qdevice_log(LOG_ERR, "Unhandled error when reading from heuristics worker cmd fd");
		ret = -1;
		break;
	case 1:
		/*
		 * At least one cmd line received
		 */
		ret = qdevice_heuristics_cmd_process(instance);
		break;
	}

	return (ret);
}
Beispiel #24
0
int
qdevice_model_net_votequorum_expected_votes_notify(struct qdevice_instance *instance,
    uint32_t expected_votes)
{
	struct qdevice_net_instance *net_instance;
	enum tlv_vote vote;

	net_instance = instance->model_data;

	qdevice_log(LOG_DEBUG, "qdevice_model_net_votequorum_expected_votes_notify"
	    " (expected votes old=%"PRIu32" / new=%"PRIu32")",
	    net_instance->qdevice_instance_ptr->vq_expected_votes, expected_votes);

	vote = TLV_VOTE_NO_CHANGE;

	if (qdevice_net_algorithm_votequorum_expected_votes_notify(net_instance, expected_votes,
	    &vote) != 0) {
		qdevice_log(LOG_DEBUG, "Algorithm returned error. Disconnecting.");

		net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_VOTEQUORUM_EXPECTED_VOTES_NOTIFY_ERR;
		net_instance->schedule_disconnect = 1;

		return (0);
	} else {
		qdevice_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(vote));
	}

	if (qdevice_net_cast_vote_timer_update(net_instance, vote) != 0) {
		qdevice_log(LOG_CRIT, "qdevice_model_net_votequorum_expected_votes_notify fatal error. "
				" Can't update cast vote timer vote");
		net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER;
		net_instance->schedule_disconnect = 1;

		return (0);
	}

	return (0);
}
static int
qdevice_net_msg_check_seq_number(struct qdevice_net_instance *instance,
    const struct msg_decoded *msg)
{

	if (!msg->seq_number_set || msg->seq_number != instance->last_msg_seq_num) {
		qdevice_log(LOG_ERR, "Received message doesn't contain seq_number or "
		    "it's not expected one.");

		return (-1);
	}

	return (0);
}
int
qdevice_net_algorithm_connected(struct qdevice_net_instance *instance, int *send_config_node_list,
    int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote)
{

	if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
	    qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) {
		qdevice_log(LOG_CRIT, "qdevice_net_algorithm_connected unhandled decision algorithm");
		exit(1);
	}

	return (qdevice_net_algorithm_array[instance->decision_algorithm]->connected(instance,
	    send_config_node_list, send_membership_node_list, send_quorum_node_list, vote));
}
int
qdevice_net_algorithm_echo_reply_received(struct qdevice_net_instance *instance,
    uint32_t seq_number, int is_expected_seq_number)
{

	if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
	    qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) {
		qdevice_log(LOG_CRIT, "qdevice_net_algorithm_echo_reply_received "
		    "unhandled decision algorithm");
		exit(1);
	}

	return (qdevice_net_algorithm_array[instance->decision_algorithm]->
	    echo_reply_received(instance, seq_number, is_expected_seq_number));
}
int
qdevice_net_algorithm_disconnected(struct qdevice_net_instance *instance,
    enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote)
{

	if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
	    qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) {
		qdevice_log(LOG_CRIT, "qdevice_net_algorithm_disconnected "
		    "unhandled decision algorithm");
		exit(1);
	}

	return (qdevice_net_algorithm_array[instance->decision_algorithm]->
	    disconnected(instance, disconnect_reason, try_reconnect, vote));
}
int
qdevice_net_algorithm_votequorum_expected_votes_notify(struct qdevice_net_instance *instance,
    uint32_t expected_votes, enum tlv_vote *vote)
{

	if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE ||
	    qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) {
		qdevice_log(LOG_CRIT, "qdevice_net_algorithm_votequorum_expected_votes_notify "
		    "unhandled decision algorithm");
		exit(1);
	}

	return (qdevice_net_algorithm_array[instance->decision_algorithm]->
	    votequorum_expected_votes_notify(instance, expected_votes, vote));
}
Beispiel #30
0
static int
qdevice_model_net_timer_connect_timeout(void *data1, void *data2)
{
	struct qdevice_net_instance *instance;

	instance = (struct qdevice_net_instance *)data1;

	qdevice_log(LOG_ERR, "Connect timeout");

	instance->schedule_disconnect = 1;

	instance->connect_timer = NULL;
	instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_CONNECT_TO_THE_SERVER;

	return (0);
}