summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/xlator.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/xlator.c')
-rw-r--r--libglusterfs/src/xlator.c1478
1 files changed, 639 insertions, 839 deletions
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
index 5d677ac18..a277c58a8 100644
--- a/libglusterfs/src/xlator.c
+++ b/libglusterfs/src/xlator.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.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/>.
+ 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
@@ -28,894 +19,438 @@
#include <fnmatch.h>
#include "defaults.h"
-
#define SET_DEFAULT_FOP(fn) do { \
- if (!xl->fops->fn) \
- xl->fops->fn = default_##fn; \
- } while (0)
-
-#define SET_DEFAULT_MOP(fn) do { \
- if (!xl->mops->fn) \
- xl->mops->fn = default_##fn; \
- } while (0)
+ if (!xl->fops->fn) \
+ xl->fops->fn = default_##fn; \
+ } while (0)
#define SET_DEFAULT_CBK(fn) do { \
- if (!xl->cbks->fn) \
- xl->cbks->fn = default_##fn; \
- } while (0)
-
+ if (!xl->cbks->fn) \
+ xl->cbks->fn = default_##fn; \
+ } while (0)
-#define GF_OPTION_LIST_EMPTY(_opt) (_opt->value[0] == NULL)
static void
fill_defaults (xlator_t *xl)
{
- if (xl == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return;
- }
+ if (xl == NULL) {
+ gf_log_callingfn ("xlator", GF_LOG_WARNING, "invalid argument");
+ return;
+ }
- SET_DEFAULT_FOP (create);
- SET_DEFAULT_FOP (open);
- SET_DEFAULT_FOP (stat);
- SET_DEFAULT_FOP (readlink);
- SET_DEFAULT_FOP (mknod);
- SET_DEFAULT_FOP (mkdir);
- SET_DEFAULT_FOP (unlink);
- SET_DEFAULT_FOP (rmdir);
- SET_DEFAULT_FOP (symlink);
- SET_DEFAULT_FOP (rename);
- SET_DEFAULT_FOP (link);
- SET_DEFAULT_FOP (chmod);
- SET_DEFAULT_FOP (chown);
- SET_DEFAULT_FOP (truncate);
- SET_DEFAULT_FOP (utimens);
- SET_DEFAULT_FOP (readv);
- SET_DEFAULT_FOP (writev);
- SET_DEFAULT_FOP (statfs);
- SET_DEFAULT_FOP (flush);
- SET_DEFAULT_FOP (fsync);
- SET_DEFAULT_FOP (setxattr);
- SET_DEFAULT_FOP (getxattr);
- SET_DEFAULT_FOP (fsetxattr);
- SET_DEFAULT_FOP (fgetxattr);
- SET_DEFAULT_FOP (removexattr);
- SET_DEFAULT_FOP (opendir);
- SET_DEFAULT_FOP (readdir);
- SET_DEFAULT_FOP (fsyncdir);
- SET_DEFAULT_FOP (access);
- SET_DEFAULT_FOP (ftruncate);
- SET_DEFAULT_FOP (fstat);
- SET_DEFAULT_FOP (lk);
- SET_DEFAULT_FOP (inodelk);
- SET_DEFAULT_FOP (finodelk);
- SET_DEFAULT_FOP (entrylk);
- SET_DEFAULT_FOP (fentrylk);
- SET_DEFAULT_FOP (lookup);
- SET_DEFAULT_FOP (fchown);
- SET_DEFAULT_FOP (fchmod);
- SET_DEFAULT_FOP (setdents);
- SET_DEFAULT_FOP (getdents);
- SET_DEFAULT_FOP (checksum);
- SET_DEFAULT_FOP (rchecksum);
- SET_DEFAULT_FOP (xattrop);
- SET_DEFAULT_FOP (fxattrop);
- SET_DEFAULT_FOP (lock_notify);
- SET_DEFAULT_FOP (lock_fnotify);
-
- SET_DEFAULT_MOP (log);
- SET_DEFAULT_MOP (stats);
-
- SET_DEFAULT_CBK (release);
- SET_DEFAULT_CBK (releasedir);
- SET_DEFAULT_CBK (forget);
-
- if (!xl->notify)
- xl->notify = default_notify;
-
- return;
+ SET_DEFAULT_FOP (create);
+ SET_DEFAULT_FOP (open);
+ SET_DEFAULT_FOP (stat);
+ SET_DEFAULT_FOP (readlink);
+ SET_DEFAULT_FOP (mknod);
+ SET_DEFAULT_FOP (mkdir);
+ SET_DEFAULT_FOP (unlink);
+ SET_DEFAULT_FOP (rmdir);
+ SET_DEFAULT_FOP (symlink);
+ SET_DEFAULT_FOP (rename);
+ SET_DEFAULT_FOP (link);
+ SET_DEFAULT_FOP (truncate);
+ SET_DEFAULT_FOP (readv);
+ SET_DEFAULT_FOP (writev);
+ SET_DEFAULT_FOP (statfs);
+ SET_DEFAULT_FOP (flush);
+ SET_DEFAULT_FOP (fsync);
+ SET_DEFAULT_FOP (setxattr);
+ SET_DEFAULT_FOP (getxattr);
+ SET_DEFAULT_FOP (fsetxattr);
+ SET_DEFAULT_FOP (fgetxattr);
+ SET_DEFAULT_FOP (removexattr);
+ SET_DEFAULT_FOP (fremovexattr);
+ SET_DEFAULT_FOP (opendir);
+ SET_DEFAULT_FOP (readdir);
+ SET_DEFAULT_FOP (readdirp);
+ SET_DEFAULT_FOP (fsyncdir);
+ SET_DEFAULT_FOP (access);
+ SET_DEFAULT_FOP (ftruncate);
+ SET_DEFAULT_FOP (fstat);
+ SET_DEFAULT_FOP (lk);
+ SET_DEFAULT_FOP (inodelk);
+ SET_DEFAULT_FOP (finodelk);
+ SET_DEFAULT_FOP (entrylk);
+ SET_DEFAULT_FOP (fentrylk);
+ SET_DEFAULT_FOP (lookup);
+ SET_DEFAULT_FOP (rchecksum);
+ SET_DEFAULT_FOP (xattrop);
+ SET_DEFAULT_FOP (fxattrop);
+ SET_DEFAULT_FOP (setattr);
+ SET_DEFAULT_FOP (fsetattr);
+ SET_DEFAULT_FOP (fallocate);
+ SET_DEFAULT_FOP (discard);
+ SET_DEFAULT_FOP (zerofill);
+
+ SET_DEFAULT_FOP (getspec);
+
+ SET_DEFAULT_CBK (release);
+ SET_DEFAULT_CBK (releasedir);
+ SET_DEFAULT_CBK (forget);
+
+ if (!xl->notify)
+ xl->notify = default_notify;
+
+ if (!xl->mem_acct_init)
+ xl->mem_acct_init = default_mem_acct_init;
+
+ return;
}
-/* RFC 1123 & 952 */
-static char
-valid_host_name (char *address, int length)
+
+int
+xlator_set_type_virtual (xlator_t *xl, const char *type)
{
- int i = 0;
- char ret = 1;
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
+ GF_VALIDATE_OR_GOTO ("xlator", type, out);
- if ((length > 75) || (length == 1)) {
- ret = 0;
- goto out;
- }
+ xl->type = gf_strdup (type);
- if (!isalnum (address[length - 1])) {
- ret = 0;
- goto out;
- }
-
- for (i = 0; i < length; i++) {
- if (!isalnum (address[i]) && (address[i] != '.')
- && (address[i] != '-')) {
- ret = 0;
- goto out;
- }
- }
+ if (xl->type)
+ return 0;
out:
- return ret;
+ return -1;
}
-static char
-valid_ipv4_address (char *address, int length)
+
+int
+xlator_volopt_dynload (char *xlator_type, void **dl_handle,
+ volume_opt_list_t *opt_list)
{
- int octets = 0;
- int value = 0;
- char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
- char ret = 1;
-
- prev = tmp = strdup (address);
- prev = strtok_r (tmp, ".", &ptr);
-
- while (prev != NULL)
- {
- octets++;
- value = strtol (prev, &endptr, 10);
- if ((value > 255) || (value < 0) || (endptr != NULL)) {
- ret = 0;
- goto out;
- }
-
- prev = strtok_r (NULL, ".", &ptr);
- }
+ int ret = -1;
+ char *name = NULL;
+ void *handle = NULL;
- if (octets != 4) {
- ret = 0;
+ GF_VALIDATE_OR_GOTO ("xlator", xlator_type, out);
+
+ ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xlator_type);
+ if (-1 == ret) {
+ gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
+ goto out;
}
-out:
- FREE (tmp);
- return ret;
-}
+ ret = -1;
-static char
-valid_ipv6_address (char *address, int length)
-{
- int hex_numbers = 0;
- int value = 0;
- char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
- char ret = 1;
-
- tmp = strdup (address);
- prev = strtok_r (tmp, ":", &ptr);
-
- while (prev != NULL)
- {
- hex_numbers++;
- value = strtol (prev, &endptr, 16);
- if ((value > 0xffff) || (value < 0) || (endptr != NULL)) {
- ret = 0;
- goto out;
- }
-
- prev = strtok_r (NULL, ":", &ptr);
+ gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);
+
+ handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
+ if (!handle) {
+ gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
+ goto out;
}
-
- if (hex_numbers > 8) {
- ret = 0;
+
+ if (!(opt_list->given_opt = dlsym (handle, "options"))) {
+ dlerror ();
+ gf_log ("xlator", GF_LOG_ERROR,
+ "Failed to load xlator opt table");
+ goto out;
}
-out:
- FREE (tmp);
+ *dl_handle = handle;
+
+ ret = 0;
+ out:
+ GF_FREE (name);
+
+ gf_log ("xlator", GF_LOG_DEBUG, "Returning %d", ret);
return ret;
+
}
-static char
-valid_internet_address (char *address)
+
+int
+xlator_dynload (xlator_t *xl)
{
- char ret = 0;
- int length = 0;
+ int ret = -1;
+ char *name = NULL;
+ void *handle = NULL;
+ volume_opt_list_t *vol_opt = NULL;
+ class_methods_t *vtbl = NULL;
+
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
- if (address == NULL) {
+ INIT_LIST_HEAD (&xl->volume_options);
+
+ ret = gf_asprintf (&name, "%s/%s.so", XLATORDIR, xl->type);
+ if (-1 == ret) {
+ gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
goto out;
}
- length = strlen (address);
- if (length == 0) {
+ ret = -1;
+
+ gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);
+
+ handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
+ if (!handle) {
+ gf_log ("xlator", GF_LOG_WARNING, "%s", dlerror ());
goto out;
}
+ xl->dlhandle = handle;
- if (valid_ipv4_address (address, length)
- || valid_ipv6_address (address, length)
- || valid_host_name (address, length)) {
- ret = 1;
+ if (!(xl->fops = dlsym (handle, "fops"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(fops) on %s",
+ dlerror ());
+ goto out;
}
-out:
- return ret;
-}
+ if (!(xl->cbks = dlsym (handle, "cbks"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(cbks) on %s",
+ dlerror ());
+ goto out;
+ }
-int
-_volume_option_value_validate (xlator_t *xl,
- data_pair_t *pair,
- volume_option_t *opt)
-{
- int i = 0;
- int ret = -1;
- uint64_t input_size = 0;
- long long inputll = 0;
-
- /* Key is valid, validate the option */
- switch (opt->type) {
- case GF_OPTION_TYPE_PATH:
- {
- if (strstr (pair->value->data, "../")) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid path given '%s'",
- pair->value->data);
- ret = -1;
+ /*
+ * If class_methods exists, its contents override any definitions of
+ * init or fini for that translator. Otherwise, we fall back to the
+ * older method of looking for init and fini directly.
+ */
+ vtbl = dlsym(handle,"class_methods");
+ if (vtbl) {
+ xl->init = vtbl->init;
+ xl->fini = vtbl->fini;
+ xl->reconfigure = vtbl->reconfigure;
+ xl->notify = vtbl->notify;
+ }
+ else {
+ if (!(*VOID(&xl->init) = dlsym (handle, "init"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(init) on %s",
+ dlerror ());
goto out;
}
- /* Make sure the given path is valid */
- if (pair->value->data[0] != '/') {
- gf_log (xl->name, GF_LOG_WARNING,
- "option %s %s: '%s' is not an "
- "absolute path name",
- pair->key, pair->value->data,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_INT:
- {
- /* Check the range */
- if (gf_string2longlong (pair->value->data,
- &inputll) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- break;
- }
- if ((inputll < opt->min) ||
- (inputll > opt->max)) {
- gf_log (xl->name, GF_LOG_WARNING,
- "'%lld' in 'option %s %s' is out of "
- "range [%"PRId64" - %"PRId64"]",
- inputll, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_SIZET:
- {
- /* Check the range */
- if (gf_string2bytesize (pair->value->data,
- &input_size) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid size format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- break;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRId64"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_BOOL:
- {
- /* Check if the value is one of
- '0|1|on|off|no|yes|true|false|enable|disable' */
- gf_boolean_t bool_value;
- if (gf_string2boolean (pair->value->data,
- &bool_value) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not a valid "
- "boolean value",
- pair->key, pair->value->data,
- pair->value->data);
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_XLATOR:
- {
- /* Check if the value is one of the xlators */
- xlator_t *xlopt = xl;
- while (xlopt->prev)
- xlopt = xlopt->prev;
-
- while (xlopt) {
- if (strcmp (pair->value->data,
- xlopt->name) == 0) {
- ret = 0;
- break;
- }
- xlopt = xlopt->next;
- }
- if (!xlopt) {
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not a "
- "valid volume name",
- pair->key, pair->value->data,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_STR:
- {
- /* Check if the '*str' is valid */
- if (GF_OPTION_LIST_EMPTY(opt)) {
- ret = 0;
+ if (!(*VOID(&(xl->fini)) = dlsym (handle, "fini"))) {
+ gf_log ("xlator", GF_LOG_WARNING, "dlsym(fini) on %s",
+ dlerror ());
goto out;
}
-
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) &&
- opt->value[i]; i++) {
- if (strcasecmp (opt->value[i],
- pair->value->data) == 0) {
- ret = 0;
- break;
- }
- }
-
- if ((i == ZR_OPTION_MAX_ARRAY_SIZE)
- || ((i < ZR_OPTION_MAX_ARRAY_SIZE)
- && (!opt->value[i]))) {
- /* enter here only if
- * 1. reached end of opt->value array and haven't
- * validated input
- * OR
- * 2. valid input list is less than
- * ZR_OPTION_MAX_ARRAY_SIZE and input has not
- * matched all possible input values.
- */
- char given_array[4096] = {0,};
- for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) &&
- opt->value[i]; i++) {
- strcat (given_array, opt->value[i]);
- strcat (given_array, ", ");
- }
-
- gf_log (xl->name, GF_LOG_ERROR,
- "option %s %s: '%s' is not valid "
- "(possible options are %s)",
- pair->key, pair->value->data,
- pair->value->data, given_array);
-
- goto out;
- }
- }
- break;
- case GF_OPTION_TYPE_PERCENT:
- {
- uint32_t percent = 0;
-
-
- /* Check if the value is valid percentage */
- if (gf_string2percent (pair->value->data,
- &percent) != 0) {
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid percent format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((percent < 0) || (percent > 100)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%d' in 'option %s %s' is out of "
- "range [0 - 100]",
- percent, pair->key,
- pair->value->data);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_PERCENT_OR_SIZET:
- {
- uint32_t percent = 0;
- uint64_t input_size = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2percent (pair->value->data,
- &percent) == 0) {
- if (percent > 100) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "value given was greater than 100, "
- "assuming this is actually a size");
- if (gf_string2bytesize (pair->value->data,
- &input_size) == 0) {
- /* Check the range */
- if ((opt->min == 0) &&
- (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check "
- "required for "
- "'option %s %s'",
- pair->key,
- pair->value->data);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRId64"' in "
- "'option %s %s' is out"
- " of range [%"PRId64""
- "- %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- // It is a size
- ret = 0;
- goto out;
- } else {
- // It's not a percent or size
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- }
-
- }
- // It is a percent
- ret = 0;
- goto out;
- } else {
- if (gf_string2bytesize (pair->value->data,
- &input_size) == 0) {
- /* Check the range */
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- // It is a size
- ret = 0;
- goto out;
- }
- if ((input_size < opt->min) ||
- (input_size > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRId64"' in 'option %s %s'"
- " is out of range [%"PRId64" -"
- " %"PRId64"]",
- input_size, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- } else {
- // It's not a percent or size
- gf_log (xl->name, GF_LOG_ERROR,
- "invalid number format \"%s\" "
- "in \"option %s\"",
- pair->value->data, pair->key);
- }
- //It is a size
- ret = 0;
- goto out;
- }
-
- }
- break;
- case GF_OPTION_TYPE_TIME:
- {
- uint32_t input_time = 0;
-
- /* Check if the value is valid percentage */
- if (gf_string2time (pair->value->data,
- &input_time) != 0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in "
- "\"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for "
- "'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- goto out;
- }
- if ((input_time < opt->min) ||
- (input_time > opt->max)) {
- gf_log (xl->name, GF_LOG_ERROR,
- "'%"PRIu32"' in 'option %s %s' is "
- "out of range [%"PRId64" - %"PRId64"]",
- input_time, pair->key,
- pair->value->data,
- opt->min, opt->max);
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_DOUBLE:
- {
- double input_time = 0.0;
-
- /* Check if the value is valid double */
- if (gf_string2double (pair->value->data,
- &input_time) != 0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if (input_time < 0.0) {
- gf_log (xl->name,
- GF_LOG_ERROR,
- "invalid time format \"%s\" in \"option %s\"",
- pair->value->data, pair->key);
- goto out;
- }
-
- if ((opt->min == 0) && (opt->max == 0)) {
- gf_log (xl->name, GF_LOG_DEBUG,
- "no range check required for 'option %s %s'",
- pair->key, pair->value->data);
- ret = 0;
- goto out;
- }
- ret = 0;
- }
- break;
- case GF_OPTION_TYPE_INTERNET_ADDRESS:
- {
- if (valid_internet_address (pair->value->data)) {
- ret = 0;
+ if (!(*VOID(&(xl->reconfigure)) = dlsym (handle,
+ "reconfigure"))) {
+ gf_log ("xlator", GF_LOG_TRACE,
+ "dlsym(reconfigure) on %s -- neglecting",
+ dlerror());
+ }
+ if (!(*VOID(&(xl->notify)) = dlsym (handle, "notify"))) {
+ gf_log ("xlator", GF_LOG_TRACE,
+ "dlsym(notify) on %s -- neglecting",
+ dlerror ());
}
- }
- break;
- case GF_OPTION_TYPE_ANY:
- /* NO CHECK */
- ret = 0;
- break;
- }
-
-out:
- return ret;
-}
-int
-validate_xlator_volume_options (xlator_t *xl, volume_option_t *opt)
-{
- int i = 0;
- int ret = -1;
- int index = 0;
- volume_option_t *trav = NULL;
- data_pair_t *pairs = NULL;
-
- if (!opt) {
- ret = 0;
- goto out;
- }
+ }
- /* First search for not supported options, if any report error */
- pairs = xl->options->members_list;
- while (pairs) {
- ret = -1;
- for (index = 0;
- opt[index].key && opt[index].key[0] ; index++) {
- trav = &(opt[index]);
- for (i = 0 ;
- (i < ZR_VOLUME_MAX_NUM_KEY) &&
- trav->key[i]; i++) {
- /* Check if the key is valid */
- if (fnmatch (trav->key[i],
- pairs->key, FNM_NOESCAPE) == 0) {
- ret = 0;
- break;
- }
- }
- if (!ret) {
- if (i) {
- gf_log (xl->name, GF_LOG_WARNING,
- "option '%s' is deprecated, "
- "preferred is '%s', continuing"
- " with correction",
- trav->key[i], trav->key[0]);
- /* TODO: some bytes lost */
- pairs->key = strdup (trav->key[0]);
- }
- break;
- }
- }
- if (!ret) {
- ret = _volume_option_value_validate (xl, pairs, trav);
- if (-1 == ret) {
- goto out;
- }
- }
-
- pairs = pairs->next;
- }
-
- ret = 0;
- out:
- return ret;
-}
+ if (!(xl->dumpops = dlsym (handle, "dumpops"))) {
+ gf_log ("xlator", GF_LOG_TRACE,
+ "dlsym(dumpops) on %s -- neglecting", dlerror ());
+ }
-int32_t
-xlator_set_type (xlator_t *xl,
- const char *type)
-{
- int ret = 0;
- char *name = NULL;
- void *handle = NULL;
- volume_opt_list_t *vol_opt = NULL;
-
- if (xl == NULL || type == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return -1;
- }
+ if (!(*VOID(&(xl->mem_acct_init)) = dlsym (handle, "mem_acct_init"))) {
+ gf_log (xl->name, GF_LOG_TRACE,
+ "dlsym(mem_acct_init) on %s -- neglecting",
+ dlerror ());
+ }
- xl->type = strdup (type);
+ vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),
+ gf_common_mt_volume_opt_list_t);
- ret = asprintf (&name, "%s/%s.so", XLATORDIR, type);
- if (-1 == ret) {
- gf_log ("xlator", GF_LOG_ERROR, "asprintf failed");
- return -1;
+ if (!vol_opt) {
+ goto out;
}
- gf_log ("xlator", GF_LOG_TRACE, "attempt to load file %s", name);
+ if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
+ dlerror ();
+ gf_log (xl->name, GF_LOG_TRACE,
+ "Strict option validation not enforced -- neglecting");
+ }
+ INIT_LIST_HEAD (&vol_opt->list);
+ list_add_tail (&vol_opt->list, &xl->volume_options);
- handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL);
- if (!handle) {
- gf_log ("xlator", GF_LOG_DEBUG, "%s", dlerror ());
- return -1;
- }
+ fill_defaults (xl);
- if (!(xl->fops = dlsym (handle, "fops"))) {
- gf_log ("xlator", GF_LOG_DEBUG, "dlsym(fops) on %s",
- dlerror ());
- return -1;
- }
+ ret = 0;
- if (!(xl->mops = dlsym (handle, "mops"))) {
- gf_log ("xlator", GF_LOG_DEBUG, "dlsym(mops) on %s",
- dlerror ());
- return -1;
- }
+out:
+ GF_FREE (name);
+ return ret;
+}
- if (!(xl->cbks = dlsym (handle, "cbks"))) {
- gf_log ("xlator", GF_LOG_DEBUG, "dlsym(cbks) on %s",
- dlerror ());
- return -1;
- }
- if (!(xl->init = dlsym (handle, "init"))) {
- gf_log ("xlator", GF_LOG_DEBUG, "dlsym(init) on %s",
- dlerror ());
- return -1;
- }
+int
+xlator_set_type (xlator_t *xl, const char *type)
+{
+ int ret = 0;
- if (!(xl->fini = dlsym (handle, "fini"))) {
- gf_log ("xlator", GF_LOG_DEBUG, "dlsym(fini) on %s",
- dlerror ());
- return -1;
- }
+ ret = xlator_set_type_virtual (xl, type);
+ if (!ret)
+ ret = xlator_dynload (xl);
- if (!(xl->notify = dlsym (handle, "notify"))) {
- gf_log ("xlator", GF_LOG_DEBUG,
- "dlsym(notify) on %s -- neglecting", dlerror ());
- }
+ return ret;
+}
- if (!(xl->dumpops = dlsym (handle, "dumpops"))) {
- gf_log ("xlator", GF_LOG_DEBUG,
- "dlsym(dumpops) on %s -- neglecting", dlerror ());
- }
- INIT_LIST_HEAD (&xl->volume_options);
+void
+xlator_foreach (xlator_t *this,
+ void (*fn)(xlator_t *each,
+ void *data),
+ void *data)
+{
+ xlator_t *first = NULL;
+ xlator_t *old_THIS = NULL;
+
+ GF_VALIDATE_OR_GOTO ("xlator", this, out);
+ GF_VALIDATE_OR_GOTO ("xlator", fn, out);
- vol_opt = CALLOC (1, sizeof (volume_opt_list_t));
+ first = this;
- if (!(vol_opt->given_opt = dlsym (handle, "options"))) {
- dlerror ();
- gf_log (xl->name, GF_LOG_DEBUG,
- "Strict option validation not enforced -- neglecting");
- }
- list_add_tail (&vol_opt->list, &xl->volume_options);
+ while (first->prev)
+ first = first->prev;
+
+ while (first) {
+ old_THIS = THIS;
+ THIS = first;
- fill_defaults (xl);
+ fn (first, data);
- FREE (name);
- return 0;
+ THIS = old_THIS;
+ first = first->next;
+ }
+
+out:
+ return;
}
void
-xlator_foreach (xlator_t *this,
- void (*fn)(xlator_t *each,
- void *data),
- void *data)
+xlator_foreach_depth_first (xlator_t *this,
+ void (*fn)(xlator_t *each, void *data),
+ void *data)
{
- xlator_t *first = NULL;
+ xlator_list_t *subv = NULL;
- if (this == NULL || fn == NULL || data == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return;
- }
+ subv = this->children;
- first = this;
-
- while (first->prev)
- first = first->prev;
-
- while (first) {
- fn (first, data);
- first = first->next;
+ while (subv) {
+ xlator_foreach_depth_first (subv->xlator, fn, data);
+ subv = subv->next;
}
+
+ fn (this, data);
}
xlator_t *
xlator_search_by_name (xlator_t *any, const char *name)
{
- xlator_t *search = NULL;
+ xlator_t *search = NULL;
- if (any == NULL || name == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return NULL;
- }
+ GF_VALIDATE_OR_GOTO ("xlator", any, out);
+ GF_VALIDATE_OR_GOTO ("xlator", name, out);
- search = any;
+ search = any;
- while (search->prev)
- search = search->prev;
+ while (search->prev)
+ search = search->prev;
- while (search) {
- if (!strcmp (search->name, name))
- break;
- search = search->next;
- }
+ while (search) {
+ if (!strcmp (search->name, name))
+ break;
+ search = search->next;
+ }
- return search;
+out:
+ return search;
}
-
-static int32_t
-xlator_init_rec (xlator_t *xl)
+static int
+__xlator_init(xlator_t *xl)
{
- xlator_list_t *trav = NULL;
- int32_t ret = 0;
-
- if (xl == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return 0;
- }
+ xlator_t *old_THIS = NULL;
+ int ret = 0;
- trav = xl->children;
+ old_THIS = THIS;
+ THIS = xl;
- while (trav) {
- ret = 0;
- ret = xlator_init_rec (trav->xlator);
- if (ret != 0)
- break;
- gf_log (trav->xlator->name, GF_LOG_TRACE,
- "Initialization done");
- trav = trav->next;
- }
+ ret = xl->init (xl);
- if (!ret && !xl->ready) {
- ret = -1;
- if (xl->init) {
- ret = xlator_init (xl);
- if (ret) {
- gf_log ("xlator", GF_LOG_ERROR,
- "Initialization of volume '%s' failed,"
- " review your volfile again",
- xl->name);
- } else {
- xl->init_succeeded = 1;
- }
- } else {
- gf_log (xl->name, GF_LOG_DEBUG, "No init() found");
- }
- /* This 'xl' is checked */
- xl->ready = 1;
- }
+ THIS = old_THIS;
- return ret;
+ return ret;
}
-int32_t
-xlator_tree_init (xlator_t *xl)
+int
+xlator_init (xlator_t *xl)
{
- xlator_t *top = NULL;
- int32_t ret = 0;
+ int32_t ret = -1;
- if (xl == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return 0;
- }
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
- top = xl;
-/*
- while (top->parents)
- top = top->parents->xlator;
-*/
- ret = xlator_init_rec (top);
+ if (xl->mem_acct_init)
+ xl->mem_acct_init (xl);
- if (ret == 0 && top->notify) {
- top->notify (top, GF_EVENT_PARENT_UP, NULL);
- }
+ if (!xl->init) {
+ gf_log (xl->name, GF_LOG_WARNING, "No init() found");
+ goto out;
+ }
+
+ ret = __xlator_init (xl);
+
+ if (ret) {
+ gf_log (xl->name, GF_LOG_ERROR,
+ "Initialization of volume '%s' failed,"
+ " review your volfile again",
+ xl->name);
+ goto out;
+ }
+
+ xl->init_succeeded = 1;
- return ret;
+ ret = 0;
+out:
+ return ret;
}
static void
xlator_fini_rec (xlator_t *xl)
{
- xlator_list_t *trav = NULL;
+ xlator_list_t *trav = NULL;
+ xlator_t *old_THIS = NULL;
- if (xl == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return;
- }
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
- trav = xl->children;
+ trav = xl->children;
- while (trav) {
- if (!trav->xlator->init_succeeded) {
- break;
- }
+ while (trav) {
+ if (!trav->xlator->init_succeeded) {
+ break;
+ }
- xlator_fini_rec (trav->xlator);
- gf_log (trav->xlator->name, GF_LOG_DEBUG, "fini done");
- trav = trav->next;
- }
+ xlator_fini_rec (trav->xlator);
+ gf_log (trav->xlator->name, GF_LOG_DEBUG, "fini done");
+ trav = trav->next;
+ }
- if (xl->init_succeeded) {
- if (xl->fini) {
- xl->fini (xl);
- } else {
- gf_log (xl->name, GF_LOG_DEBUG, "No fini() found");
- }
- xl->init_succeeded = 0;
- }
+ if (xl->init_succeeded) {
+ if (xl->fini) {
+ old_THIS = THIS;
+ THIS = xl;
+
+ xl->fini (xl);
+
+ if (xl->local_pool)
+ mem_pool_destroy (xl->local_pool);
+
+ THIS = old_THIS;
+ } else {
+ gf_log (xl->name, GF_LOG_DEBUG, "No fini() found");
+ }
+ xl->init_succeeded = 0;
+ }
+
+out:
+ return;
}
@@ -937,57 +472,98 @@ xlator_notify (xlator_t *xl, int event, void *data, ...)
int
-xlator_init (xlator_t *xl)
+xlator_mem_acct_init (xlator_t *xl, int num_types)
{
- xlator_t *old_THIS = NULL;
- int ret = 0;
+ int i = 0;
+ int ret = 0;
- old_THIS = THIS;
- THIS = xl;
+ if (!xl)
+ return -1;
- ret = xl->init (xl);
+ if (!xl->ctx->mem_acct_enable)
+ return 0;
- THIS = old_THIS;
+ xl->mem_acct.num_types = num_types;
- return ret;
+ xl->mem_acct.rec = CALLOC(num_types, sizeof(struct mem_acct_rec));
+
+ if (!xl->mem_acct.rec) {
+ return -1;
+ }
+
+ for (i = 0; i < num_types; i++) {
+ ret = LOCK_INIT(&(xl->mem_acct.rec[i].lock));
+ if (ret) {
+ fprintf(stderr, "Unable to lock..errno : %d",errno);
+ }
+ }
+
+ return 0;
}
void
xlator_tree_fini (xlator_t *xl)
{
- xlator_t *top = NULL;
+ xlator_t *top = NULL;
- if (xl == NULL) {
- gf_log ("xlator", GF_LOG_DEBUG, "invalid argument");
- return;
- }
+ GF_VALIDATE_OR_GOTO ("xlator", xl, out);
+
+ top = xl;
+ xlator_fini_rec (top);
- top = xl;
- xlator_fini_rec (top);
+out:
+ return;
+}
+
+int
+xlator_list_destroy (xlator_list_t *list)
+{
+ xlator_list_t *next = NULL;
+
+ while (list) {
+ next = list->next;
+ GF_FREE (list);
+ list = next;
+ }
+
+ return 0;
}
int
xlator_tree_free (xlator_t *tree)
{
- xlator_t *trav = tree, *prev = tree;
-
- if (!tree) {
- gf_log ("parser", GF_LOG_ERROR, "Translator tree not found");
- return -1;
- }
-
- while (prev) {
- trav = prev->next;
- dict_destroy (prev->options);
- FREE (prev->name);
- FREE (prev->type);
- FREE (prev);
- prev = trav;
- }
-
- return 0;
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp = NULL;
+ xlator_t *trav = tree;
+ xlator_t *prev = tree;
+
+ if (!tree) {
+ gf_log ("parser", GF_LOG_ERROR, "Translator tree not found");
+ return -1;
+ }
+
+ while (prev) {
+ trav = prev->next;
+ if (prev->dlhandle)
+ dlclose (prev->dlhandle);
+ dict_unref (prev->options);
+ GF_FREE (prev->name);
+ GF_FREE (prev->type);
+ xlator_list_destroy (prev->children);
+ xlator_list_destroy (prev->parents);
+
+ list_for_each_entry_safe (vol_opt, tmp, &prev->volume_options,
+ list) {
+ list_del_init (&vol_opt->list);
+ GF_FREE (vol_opt);
+ }
+ GF_FREE (prev);
+ prev = trav;
+ }
+
+ return 0;
}
@@ -999,40 +575,264 @@ loc_wipe (loc_t *loc)
loc->inode = NULL;
}
if (loc->path) {
- FREE (loc->path);
+ GF_FREE ((char *)loc->path);
loc->path = NULL;
}
-
+
if (loc->parent) {
inode_unref (loc->parent);
loc->parent = NULL;
}
+
+ memset (loc, 0, sizeof (*loc));
}
+int
+loc_path (loc_t *loc, const char *bname)
+{
+ int ret = 0;
+
+ if (loc->path)
+ goto out;
+
+ ret = -1;
+
+ if (bname && !strlen (bname))
+ bname = NULL;
+
+ if (!bname)
+ goto inode_path;
+
+ if (loc->parent && !uuid_is_null (loc->parent->gfid)) {
+ ret = inode_path (loc->parent, bname, (char**)&loc->path);
+ } else if (!uuid_is_null (loc->pargfid)) {
+ ret = gf_asprintf ((char**)&loc->path, INODE_PATH_FMT"/%s",
+ uuid_utoa (loc->pargfid), bname);
+ }
+
+ if (loc->path)
+ goto out;
+
+inode_path:
+ if (loc->inode && !uuid_is_null (loc->inode->gfid)) {
+ ret = inode_path (loc->inode, NULL, (char **)&loc->path);
+ } else if (!uuid_is_null (loc->gfid)) {
+ ret = gf_asprintf ((char**)&loc->path, INODE_PATH_FMT,
+ uuid_utoa (loc->gfid));
+ }
+out:
+ return ret;
+}
+
+void
+loc_gfid (loc_t *loc, uuid_t gfid)
+{
+ if (!gfid)
+ goto out;
+ uuid_clear (gfid);
+
+ if (!loc)
+ goto out;
+ else if (!uuid_is_null (loc->gfid))
+ uuid_copy (gfid, loc->gfid);
+ else if (loc->inode && (!uuid_is_null (loc->inode->gfid)))
+ uuid_copy (gfid, loc->inode->gfid);
+out:
+ return;
+}
+
+char*
+loc_gfid_utoa (loc_t *loc)
+{
+ uuid_t gfid;
+ loc_gfid (loc, gfid);
+ return uuid_utoa (gfid);
+}
int
loc_copy (loc_t *dst, loc_t *src)
{
- int ret = -1;
+ int ret = -1;
- dst->ino = src->ino;
+ GF_VALIDATE_OR_GOTO ("xlator", dst, err);
+ GF_VALIDATE_OR_GOTO ("xlator", src, err);
- if (src->inode)
- dst->inode = inode_ref (src->inode);
+ uuid_copy (dst->gfid, src->gfid);
+ uuid_copy (dst->pargfid, src->pargfid);
+ uuid_copy (dst->gfid, src->gfid);
- if (src->parent)
- dst->parent = inode_ref (src->parent);
+ if (src->inode)
+ dst->inode = inode_ref (src->inode);
- dst->path = strdup (src->path);
+ if (src->parent)
+ dst->parent = inode_ref (src->parent);
- if (!dst->path)
- goto out;
+ if (src->path) {
+ dst->path = gf_strdup (src->path);
- dst->name = strrchr (dst->path, '/');
- if (dst->name)
- dst->name++;
+ if (!dst->path)
+ goto out;
+
+ if (src->name)
+ dst->name = strrchr (dst->path, '/');
+ if (dst->name)
+ dst->name++;
+ }
- ret = 0;
+ ret = 0;
out:
- return ret;
+ if (ret == -1)
+ loc_wipe (dst);
+
+err:
+ return ret;
}
+
+gf_boolean_t
+loc_is_root (loc_t *loc)
+{
+ if (loc && __is_root_gfid (loc->gfid)) {
+ return _gf_true;
+ } else if (loc && loc->inode && __is_root_gfid (loc->inode->gfid)) {
+ return _gf_true;
+ }
+ return _gf_false;
+}
+
+int
+xlator_destroy (xlator_t *xl)
+{
+ volume_opt_list_t *vol_opt = NULL;
+ volume_opt_list_t *tmp = NULL;
+
+ if (!xl)
+ return 0;
+
+ GF_FREE (xl->name);
+ GF_FREE (xl->type);
+ if (xl->dlhandle)
+ dlclose (xl->dlhandle);
+ if (xl->options)
+ dict_destroy (xl->options);
+
+ xlator_list_destroy (xl->children);
+
+ xlator_list_destroy (xl->parents);
+
+ list_for_each_entry_safe (vol_opt, tmp, &xl->volume_options, list) {
+ list_del_init (&vol_opt->list);
+ GF_FREE (vol_opt);
+ }
+
+ GF_FREE (xl);
+
+ return 0;
+}
+
+
+int
+is_gf_log_command (xlator_t *this, const char *name, char *value)
+{
+ xlator_t *trav = NULL;
+ char key[1024] = {0,};
+ int ret = -1;
+ int log_level = -1;
+ gf_boolean_t syslog_flag = 0;
+ glusterfs_ctx_t *ctx = NULL;
+
+ if (!strcmp ("trusted.glusterfs.syslog", name)) {
+ ret = gf_string2boolean (value, &syslog_flag);
+ if (ret) {
+ ret = EOPNOTSUPP;
+ goto out;
+ }
+ if (syslog_flag)
+ gf_log_enable_syslog ();
+ else
+ gf_log_disable_syslog ();
+
+ goto out;
+ }
+
+ if (fnmatch ("trusted.glusterfs*set-log-level", name, FNM_NOESCAPE))
+ goto out;
+
+ log_level = glusterd_check_log_level (value);
+ if (log_level == -1) {
+ ret = EOPNOTSUPP;
+ goto out;
+ }
+
+ /* Some crude way to change the log-level of process */
+ if (!strcmp (name, "trusted.glusterfs.set-log-level")) {
+ /* */
+ gf_log ("glusterfs", gf_log_get_loglevel(),
+ "setting log level to %d (old-value=%d)",
+ log_level, gf_log_get_loglevel());
+ gf_log_set_loglevel (log_level);
+ ret = 0;
+ goto out;
+ }
+
+ if (!strcmp (name, "trusted.glusterfs.fuse.set-log-level")) {
+ /* */
+ gf_log (this->name, gf_log_get_xl_loglevel (this),
+ "setting log level to %d (old-value=%d)",
+ log_level, gf_log_get_xl_loglevel (this));
+ gf_log_set_xl_loglevel (this, log_level);
+ ret = 0;
+ goto out;
+ }
+
+ ctx = this->ctx;
+ if (!ctx)
+ goto out;
+ if (!ctx->active)
+ goto out;
+ trav = ctx->active->top;
+
+ while (trav) {
+ snprintf (key, 1024, "trusted.glusterfs.%s.set-log-level",
+ trav->name);
+ if (fnmatch (name, key, FNM_NOESCAPE) == 0) {
+ gf_log (trav->name, gf_log_get_xl_loglevel (trav),
+ "setting log level to %d (old-value=%d)",
+ log_level, gf_log_get_xl_loglevel (trav));
+ gf_log_set_xl_loglevel (trav, log_level);
+ ret = 0;
+ }
+ trav = trav->next;
+ }
+out:
+ return ret;
+}
+
+
+int
+glusterd_check_log_level (const char *value)
+{
+ int log_level = -1;
+
+ if (!strcasecmp (value, "CRITICAL")) {
+ log_level = GF_LOG_CRITICAL;
+ } else if (!strcasecmp (value, "ERROR")) {
+ log_level = GF_LOG_ERROR;
+ } else if (!strcasecmp (value, "WARNING")) {
+ log_level = GF_LOG_WARNING;
+ } else if (!strcasecmp (value, "INFO")) {
+ log_level = GF_LOG_INFO;
+ } else if (!strcasecmp (value, "DEBUG")) {
+ log_level = GF_LOG_DEBUG;
+ } else if (!strcasecmp (value, "TRACE")) {
+ log_level = GF_LOG_TRACE;
+ } else if (!strcasecmp (value, "NONE")) {
+ log_level = GF_LOG_NONE;
+ }
+
+ if (log_level == -1)
+ gf_log (THIS->name, GF_LOG_ERROR, "Invalid log-level. possible values "
+ "are DEBUG|WARNING|ERROR|CRITICAL|NONE|TRACE");
+
+ return log_level;
+}
+