/* Copyright (c) 2013 Red Hat, Inc. This file is part of GlusterFS. This file is licensed to you under your choice of the GNU Lesser General Public License, version 3 or any later version (LGPLv3 or later), or the GNU General Public License, version 2 (GPLv2), in all cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include "glusterd-volgen.h" #include "glusterd-utils.h" static int check_dict_key_value (dict_t *dict, char *key, char *value) { glusterd_conf_t *priv = NULL; int ret = 0; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); priv = this->private; GF_ASSERT (priv); if (!dict) { gf_log (this->name, GF_LOG_ERROR, "Received Empty Dict."); ret = -1; goto out; } if (!key) { gf_log (this->name, GF_LOG_ERROR, "Received Empty Key."); ret = -1; goto out; } if (!value) { gf_log (this->name, GF_LOG_ERROR, "Received Empty Value."); ret = -1; goto out; } out: gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } static int get_volname_volinfo (dict_t *dict, char **volname, glusterd_volinfo_t **volinfo) { glusterd_conf_t *priv = NULL; int ret = 0; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); priv = this->private; GF_ASSERT (priv); ret = dict_get_str (dict, "volname", volname); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Unable to get volume name"); goto out; } ret = glusterd_volinfo_find (*volname, volinfo); if (ret) { gf_log (this->name, GF_LOG_ERROR, "Unable to allocate memory"); goto out; } out: gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } static int validate_cache_max_min_size (dict_t *dict, char *key, char *value, char **op_errstr) { char *current_max_value = NULL; char *current_min_value = NULL; char errstr[2048] = ""; char *volname = NULL; glusterd_conf_t *priv = NULL; glusterd_volinfo_t *volinfo = NULL; int ret = 0; uint64_t max_value = 0; uint64_t min_value = 0; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); priv = this->private; GF_ASSERT (priv); ret = check_dict_key_value (dict, key, value); if (ret) goto out; ret = get_volname_volinfo (dict, &volname, &volinfo); if (ret) goto out; if ((!strcmp (key, "performance.cache-min-file-size")) || (!strcmp (key, "cache-min-file-size"))) { glusterd_volinfo_get (volinfo, "performance.cache-max-file-size", ¤t_max_value); if (current_max_value) { gf_string2bytesize (current_max_value, &max_value); gf_string2bytesize (value, &min_value); current_min_value = value; } } else if ((!strcmp (key, "performance.cache-max-file-size")) || (!strcmp (key, "cache-max-file-size"))) { glusterd_volinfo_get (volinfo, "performance.cache-min-file-size", ¤t_min_value); if (current_min_value) { gf_string2bytesize (current_min_value, &min_value); gf_string2bytesize (value, &max_value); current_max_value = value; } } if (min_value > max_value) { snprintf (errstr, sizeof (errstr), "cache-min-file-size (%s) is greater than " "cache-max-file-size (%s)", current_min_value, current_max_value); gf_log (this->name, GF_LOG_ERROR, "%s", errstr); *op_errstr = gf_strdup (errstr); ret = -1; goto out; } out: gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } static int validate_quota (dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; char *volname = NULL; glusterd_conf_t *priv = NULL; glusterd_volinfo_t *volinfo = NULL; int ret = 0; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); priv = this->private; GF_ASSERT (priv); ret = check_dict_key_value (dict, key, value); if (ret) goto out; ret = get_volname_volinfo (dict, &volname, &volinfo); if (ret) goto out; ret = glusterd_volinfo_get_boolean (volinfo, VKEY_FEATURES_QUOTA); if (ret == -1) { gf_log (this->name, GF_LOG_ERROR, "failed to get the quota status"); goto out; } if (ret == _gf_false) { snprintf (errstr, sizeof (errstr), "Cannot set %s. Enable quota first.", key); gf_log (this->name, GF_LOG_ERROR, "%s", errstr); *op_errstr = gf_strdup (errstr); ret = -1; goto out; } ret = 0; out: gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } static int validate_stripe (dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; char *volname = NULL; glusterd_conf_t *priv = NULL; glusterd_volinfo_t *volinfo = NULL; int ret = 0; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); priv = this->private; GF_ASSERT (priv); ret = check_dict_key_value (dict, key, value); if (ret) goto out; ret = get_volname_volinfo (dict, &volname, &volinfo); if (ret) goto out; if (volinfo->stripe_count == 1) { snprintf (errstr, sizeof (errstr), "Cannot set %s for a non-stripe volume.", key); gf_log (this->name, GF_LOG_ERROR, "%s", errstr); *op_errstr = gf_strdup (errstr); ret = -1; goto out; } out: gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } static int validate_subvols_per_directory (dict_t *dict, char *key, char *value, char **op_errstr) { char errstr[2048] = ""; char *volname = NULL; glusterd_conf_t *priv = NULL; glusterd_volinfo_t *volinfo = NULL; int ret = 0; int subvols = 0; xlator_t *this = NULL; this = THIS; GF_ASSERT (this); priv = this->private; GF_ASSERT (priv); ret = check_dict_key_value (dict, key, value); if (ret) goto out; ret = get_volname_volinfo (dict, &volname, &volinfo); if (ret) goto out; subvols = atoi(value); /* Checking if the subvols-per-directory exceed the total number of subvolumes. */ if (subvols > volinfo->subvol_count) { snprintf (errstr, sizeof(errstr), "subvols-per-directory(%d) is greater " "than the number of subvolumes(%d).", subvols, volinfo->subvol_count); gf_log (this->name, GF_LOG_ERROR, "%s.", errstr); *op_errstr = gf_strdup (errstr); ret = -1; goto out; } out: gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret); return ret; } /* dispatch table for VOLUME SET * ----------------------------- * * Format of entries: * * First field is the , for the purpose of looking it up * in volume dictionary. Each is of the format ".". * * Second field is . * * Third field is