summaryrefslogtreecommitdiffstats
path: root/scheduler/rr/src/rr-options.c
diff options
context:
space:
mode:
Diffstat (limited to 'scheduler/rr/src/rr-options.c')
-rw-r--r--scheduler/rr/src/rr-options.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/scheduler/rr/src/rr-options.c b/scheduler/rr/src/rr-options.c
new file mode 100644
index 00000000000..3f0ffcaf2e9
--- /dev/null
+++ b/scheduler/rr/src/rr-options.c
@@ -0,0 +1,256 @@
+/*
+ Copyright (c) 2008 Z RESEARCH, Inc. <http://www.zresearch.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#include "scheduler.h"
+#include "rr-options.h"
+
+#define RR_LIMITS_MIN_FREE_DISK_OPTION_STRING "scheduler.limits.min-free-disk"
+#define RR_LIMITS_MIN_FREE_DISK_VALUE_DEFAULT 15
+#define RR_LIMITS_MIN_FREE_DISK_VALUE_MIN 0
+#define RR_LIMITS_MIN_FREE_DISK_VALUE_MAX 100
+
+#define RR_REFRESH_INTERVAL_OPTION_STRING "scheduler.refresh-interval"
+#define RR_REFRESH_INTERVAL_VALUE_DEFAULT 10
+
+#define RR_READ_ONLY_SUBVOLUMES_OPTION_STRING "scheduler.read-only-subvolumes"
+
+#define LOG_ERROR(args...) gf_log ("rr-options", GF_LOG_ERROR, ##args)
+#define LOG_WARNING(args...) gf_log ("rr-options", GF_LOG_WARNING, ##args)
+
+static int
+_rr_options_min_free_disk_validate (const char *value_string, uint32_t *n)
+{
+ uint32_t value = 0;
+
+ if (value_string == NULL)
+ {
+ return -1;
+ }
+
+ if (gf_string2percent (value_string, &value) != 0)
+ {
+ gf_log ("rr",
+ GF_LOG_ERROR,
+ "invalid number format [%s] of option [%s]",
+ value_string,
+ RR_LIMITS_MIN_FREE_DISK_OPTION_STRING);
+ return -1;
+ }
+
+ if ((value <= RR_LIMITS_MIN_FREE_DISK_VALUE_MIN) ||
+ (value >= RR_LIMITS_MIN_FREE_DISK_VALUE_MAX))
+ {
+ gf_log ("rr",
+ GF_LOG_ERROR,
+ "out of range [%d] of option [%s]. Allowed range is 0 to 100.",
+ value,
+ RR_LIMITS_MIN_FREE_DISK_OPTION_STRING);
+ return -1;
+ }
+
+ *n = value;
+
+ return 0;
+}
+
+static int
+_rr_options_refresh_interval_validate (const char *value_string, uint32_t *n)
+{
+ uint32_t value = 0;
+
+ if (value_string == NULL)
+ {
+ return -1;
+ }
+
+ if (gf_string2time (value_string, &value) != 0)
+ {
+ gf_log ("rr",
+ GF_LOG_ERROR,
+ "invalid number format [%s] of option [%s]",
+ value_string,
+ RR_REFRESH_INTERVAL_OPTION_STRING);
+ return -1;
+ }
+
+ *n = value;
+
+ return 0;
+}
+
+static int
+_rr_options_read_only_subvolumes_validate (const char *value_string,
+ char ***volume_list,
+ uint64_t *volume_count)
+{
+ char **vlist = NULL;
+ int vcount = 0;
+ int i = 0;
+
+ if (value_string == NULL || volume_list == NULL || volume_count)
+ {
+ return -1;
+ }
+
+ if (gf_strsplit (value_string,
+ ", ",
+ &vlist,
+ &vcount) != 0)
+ {
+ gf_log ("rr",
+ GF_LOG_ERROR,
+ "invalid subvolume list [%s] of option [%s]",
+ value_string,
+ RR_READ_ONLY_SUBVOLUMES_OPTION_STRING);
+ return -1;
+ }
+
+ for (i = 0; i < vcount; i++)
+ {
+ if (gf_volume_name_validate (vlist[i]) != 0)
+ {
+ gf_log ("rr",
+ GF_LOG_ERROR,
+ "invalid subvolume name [%s] in [%s] of option [%s]",
+ vlist[i],
+ value_string,
+ RR_READ_ONLY_SUBVOLUMES_OPTION_STRING);
+ goto free_exit;
+ }
+ }
+
+ *volume_list = vlist;
+ *volume_count = vcount;
+
+ return 0;
+
+ free_exit:
+ for (i = 0; i < vcount; i++)
+ {
+ free (vlist[i]);
+ }
+ free (vlist);
+
+ return -1;
+}
+
+int
+rr_options_validate (dict_t *options, rr_options_t *rr_options)
+{
+ char *value_string = NULL;
+
+ if (options == NULL || rr_options == NULL)
+ {
+ return -1;
+ }
+
+ if (dict_get (options, RR_LIMITS_MIN_FREE_DISK_OPTION_STRING))
+ if (data_to_str (dict_get (options, RR_LIMITS_MIN_FREE_DISK_OPTION_STRING)))
+ value_string = data_to_str (dict_get (options,
+ RR_LIMITS_MIN_FREE_DISK_OPTION_STRING));
+ if (value_string != NULL)
+ {
+ if (_rr_options_min_free_disk_validate (value_string,
+ &rr_options->min_free_disk) != 0)
+ {
+ return -1;
+ }
+
+ gf_log ("rr",
+ GF_LOG_WARNING,
+ "using %s = %d",
+ RR_LIMITS_MIN_FREE_DISK_OPTION_STRING,
+ rr_options->min_free_disk);
+ }
+ else
+ {
+ rr_options->min_free_disk = RR_LIMITS_MIN_FREE_DISK_VALUE_DEFAULT;
+
+ gf_log ("rr", GF_LOG_DEBUG,
+ "using %s = %d [default]",
+ RR_LIMITS_MIN_FREE_DISK_OPTION_STRING,
+ rr_options->min_free_disk);
+ }
+
+ value_string = NULL;
+ if (dict_get (options, RR_REFRESH_INTERVAL_OPTION_STRING))
+ value_string = data_to_str (dict_get (options,
+ RR_REFRESH_INTERVAL_OPTION_STRING));
+ if (value_string != NULL)
+ {
+ if (_rr_options_refresh_interval_validate (value_string,
+ &rr_options->refresh_interval) != 0)
+ {
+ return -1;
+ }
+
+ gf_log ("rr",
+ GF_LOG_WARNING,
+ "using %s = %d",
+ RR_REFRESH_INTERVAL_OPTION_STRING,
+ rr_options->refresh_interval);
+ }
+ else
+ {
+ rr_options->refresh_interval = RR_REFRESH_INTERVAL_VALUE_DEFAULT;
+
+ gf_log ("rr", GF_LOG_DEBUG,
+ "using %s = %d [default]",
+ RR_REFRESH_INTERVAL_OPTION_STRING,
+ rr_options->refresh_interval);
+ }
+
+ value_string = NULL;
+ if (dict_get (options, RR_READ_ONLY_SUBVOLUMES_OPTION_STRING))
+ value_string = data_to_str (dict_get (options,
+ RR_READ_ONLY_SUBVOLUMES_OPTION_STRING));
+ if (value_string != NULL)
+ {
+ if (_rr_options_read_only_subvolumes_validate (value_string,
+ &rr_options->read_only_subvolume_list,
+ &rr_options->read_only_subvolume_count) != 0)
+ {
+ return -1;
+ }
+
+ gf_log ("rr",
+ GF_LOG_WARNING,
+ "using %s = [%s]",
+ RR_READ_ONLY_SUBVOLUMES_OPTION_STRING,
+ value_string);
+ }
+
+ return 0;
+}
+
+struct volume_options options[] = {
+ { .key = { "scheduler.refresh-interval",
+ "rr.refresh-interval" },
+ .type = GF_OPTION_TYPE_TIME
+ },
+ { .key = { "scheduler.limits.min-free-disk",
+ "rr.limits.min-free-disk" },
+ .type = GF_OPTION_TYPE_PERCENT
+ },
+ { .key = { "scheduler.read-only-subvolumes",
+ "rr.read-only-subvolumes" },
+ .type = GF_OPTION_TYPE_ANY
+ },
+ { .key = {NULL} }
+};