/*
 * 0 - No error
 * -1 - Unknown option
 * -2 - Incorrect value
 */
int
qdevice_advanced_settings_set(struct qdevice_advanced_settings *settings,
    const char *option, const char *value)
{
	long long int tmpll;
	char *ep;

	if (strcasecmp(option, "lock_file") == 0) {
		free(settings->lock_file);

		if ((settings->lock_file = strdup(value)) == NULL) {
			return (-1);
		}
	} else if (strcasecmp(option, "local_socket_file") == 0) {
		free(settings->local_socket_file);

		if ((settings->local_socket_file = strdup(value)) == NULL) {
			return (-1);
		}
	} else if (strcasecmp(option, "local_socket_backlog") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_MIN_LOCAL_SOCKET_BACKLOG || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->local_socket_backlog = (int)tmpll;
	} else if (strcasecmp(option, "max_cs_try_again") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_MIN_MAX_CS_TRY_AGAIN || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->max_cs_try_again = (int)tmpll;
	} else if (strcasecmp(option, "votequorum_device_name") == 0) {
		free(settings->votequorum_device_name);

		if ((settings->votequorum_device_name = strdup(value)) == NULL) {
			return (-1);
		}
	} else if (strcasecmp(option, "ipc_max_clients") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_MIN_IPC_MAX_CLIENTS || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->ipc_max_clients = (size_t)tmpll;
	} else if (strcasecmp(option, "ipc_max_receive_size") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_MIN_IPC_RECEIVE_SEND_SIZE || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->ipc_max_receive_size = (size_t)tmpll;
	} else if (strcasecmp(option, "ipc_max_send_size") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_MIN_IPC_RECEIVE_SEND_SIZE || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->ipc_max_send_size = (size_t)tmpll;
	} else if (strcasecmp(option, "net_nss_db_dir") == 0) {
		free(settings->net_nss_db_dir);

		if ((settings->net_nss_db_dir = strdup(value)) == NULL) {
			return (-1);
		}
	} else if (strcasecmp(option, "net_initial_msg_receive_size") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_NET_MIN_MSG_RECEIVE_SEND_SIZE || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->net_initial_msg_receive_size = (size_t)tmpll;
	} else if (strcasecmp(option, "net_initial_msg_send_size") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_NET_MIN_MSG_RECEIVE_SEND_SIZE || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->net_initial_msg_send_size = (size_t)tmpll;
	} else if (strcasecmp(option, "net_min_msg_send_size") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_NET_MIN_MSG_RECEIVE_SEND_SIZE || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->net_min_msg_send_size = (size_t)tmpll;
	} else if (strcasecmp(option, "net_max_msg_receive_size") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_NET_MIN_MSG_RECEIVE_SEND_SIZE || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->net_max_msg_receive_size = (size_t)tmpll;
	} else if (strcasecmp(option, "net_max_send_buffers") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_NET_MIN_MAX_SEND_BUFFERS || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->net_max_send_buffers = (size_t)tmpll;
	} else if (strcasecmp(option, "net_nss_qnetd_cn") == 0) {
		free(settings->net_nss_qnetd_cn);

		if ((settings->net_nss_qnetd_cn = strdup(value)) == NULL) {
			return (-1);
		}
	} else if (strcasecmp(option, "net_nss_client_cert_nickname") == 0) {
		free(settings->net_nss_client_cert_nickname);

		if ((settings->net_nss_client_cert_nickname = strdup(value)) == NULL) {
			return (-1);
		}
	} else if (strcasecmp(option, "net_heartbeat_interval_min") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_NET_MIN_HEARTBEAT_INTERVAL || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->net_heartbeat_interval_min = (uint32_t)tmpll;
	} else if (strcasecmp(option, "net_heartbeat_interval_max") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_NET_MIN_HEARTBEAT_INTERVAL || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->net_heartbeat_interval_max = (uint32_t)tmpll;
	} else if (strcasecmp(option, "net_min_connect_timeout") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_NET_MIN_CONNECT_TIMEOUT || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->net_min_connect_timeout = (uint32_t)tmpll;
	} else if (strcasecmp(option, "net_max_connect_timeout") == 0) {
		tmpll = strtoll(value, &ep, 10);
		if (tmpll < QDEVICE_NET_MIN_CONNECT_TIMEOUT || errno != 0 || *ep != '\0') {
			return (-2);
		}

		settings->net_max_connect_timeout = (uint32_t)tmpll;
	} else if (strcasecmp(option, "net_test_algorithm_enabled") == 0) {
		if ((tmpll = utils_parse_bool_str(value)) == -1) {
			return (-2);
		}

		settings->net_test_algorithm_enabled = (uint8_t)tmpll;
	} else if (strcasecmp(option, "master_wins") == 0) {
		tmpll = utils_parse_bool_str(value);

		if (tmpll == 0) {
			settings->master_wins = QDEVICE_ADVANCED_SETTINGS_MASTER_WINS_FORCE_OFF;
		} else if (tmpll == 1) {
			settings->master_wins = QDEVICE_ADVANCED_SETTINGS_MASTER_WINS_FORCE_ON;
		} else if (strcasecmp(value, "model") == 0) {
			settings->master_wins = QDEVICE_ADVANCED_SETTINGS_MASTER_WINS_MODEL;
		} else {
			return (-2);
		}
	} else {
		return (-1);
	}

	return (0);
}
Esempio n. 2
0
static void
cli_parse(int argc, char * const argv[], char **host_addr, uint16_t *host_port, int *foreground,
          int *debug_log, int *bump_log_priority, enum tlv_tls_supported *tls_supported,
          int *client_cert_required, size_t *max_clients, PRIntn *address_family,
          struct qnetd_advanced_settings *advanced_settings)
{
    int ch;
    char *ep;
    long long int tmpll;

    *host_addr = NULL;
    *host_port = QNETD_DEFAULT_HOST_PORT;
    *foreground = 0;
    *debug_log = 0;
    *bump_log_priority = 0;
    *tls_supported = QNETD_DEFAULT_TLS_SUPPORTED;
    *client_cert_required = QNETD_DEFAULT_TLS_CLIENT_CERT_REQUIRED;
    *max_clients = QNETD_DEFAULT_MAX_CLIENTS;
    *address_family = PR_AF_UNSPEC;

    while ((ch = getopt(argc, argv, "46dfhvc:l:m:p:S:s:")) != -1) {
        switch (ch) {
        case '4':
            *address_family = PR_AF_INET;
            break;
        case '6':
            *address_family = PR_AF_INET6;
            break;
        case 'f':
            *foreground = 1;
            break;
        case 'd':
            if (*debug_log) {
                *bump_log_priority = 1;
            }
            *debug_log = 1;
            break;
        case 'c':
            if ((*client_cert_required = utils_parse_bool_str(optarg)) == -1) {
                errx(1, "client_cert_required should be on/yes/1, off/no/0");
            }
            break;
        case 'l':
            free(*host_addr);
            *host_addr = strdup(optarg);
            if (*host_addr == NULL) {
                errx(1, "Can't alloc memory for host addr string");
            }
            break;
        case 'm':
            errno = 0;

            tmpll = strtoll(optarg, &ep, 10);
            if (tmpll < 0 || errno != 0 || *ep != '\0') {
                errx(1, "max clients value %s is invalid", optarg);
            }
            *max_clients = (size_t)tmpll;
            break;
        case 'p':
            *host_port = strtol(optarg, &ep, 10);
            if (*host_port <= 0 || *host_port > ((uint16_t)~0) || *ep != '\0') {
                errx(1, "host port must be in range 0-65535");
            }
            break;
        case 'S':
            cli_parse_long_opt(advanced_settings, optarg);
            break;
        case 's':
            if (strcasecmp(optarg, "on") == 0) {
                *tls_supported = QNETD_DEFAULT_TLS_SUPPORTED;
            } else if (strcasecmp(optarg, "off") == 0) {
                *tls_supported = TLV_TLS_UNSUPPORTED;
            } else if (strcasecmp(optarg, "req") == 0) {
                *tls_supported = TLV_TLS_REQUIRED;
            } else {
                errx(1, "tls must be one of on, off, req");
            }
            break;
        case 'v':
            display_version();
            exit(1);
            break;
        case 'h':
        case '?':
            usage();
            exit(1);
            break;
        }
    }
}
Esempio n. 3
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);
}