/* * 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); }
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; } } }
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); }