diff options
| -rw-r--r-- | libglusterfs/src/xlator.c | 27 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.h | 7 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/Makefile.am | 2 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 11 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-shared.c | 732 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht.c | 733 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/nufa.c | 177 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/switch.c | 163 | 
8 files changed, 806 insertions, 1046 deletions
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index da5501b2cfa..1be4c86b2ed 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -225,8 +225,10 @@ xlator_dynload (xlator_t *xl)           */          vtbl = dlsym(handle,"class_methods");          if (vtbl) { -                xl->init = vtbl->init; -                xl->fini = vtbl->fini; +                xl->init        = vtbl->init; +                xl->fini        = vtbl->fini; +                xl->reconfigure = vtbl->reconfigure; +                xl->notify      = vtbl->notify;          }          else {                  if (!(*VOID(&xl->init) = dlsym (handle, "init"))) { @@ -240,11 +242,18 @@ xlator_dynload (xlator_t *xl)                                  dlerror ());                          goto out;                  } -        } +                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 ()); +                } -        if (!(*VOID(&(xl->notify)) = dlsym (handle, "notify"))) { -                gf_log ("xlator", GF_LOG_TRACE, -                        "dlsym(notify) on %s -- neglecting", dlerror ());          }          if (!(xl->dumpops = dlsym (handle, "dumpops"))) { @@ -258,12 +267,6 @@ xlator_dynload (xlator_t *xl)                          dlerror ());          } -        if (!(*VOID(&(xl->reconfigure)) = dlsym (handle, "reconfigure"))) { -                gf_log ("xlator", GF_LOG_TRACE, -                        "dlsym(reconfigure) on %s -- neglecting", -                        dlerror()); -        } -          vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t),                           gf_common_mt_volume_opt_list_t); diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 2567fc70c48..bb32797c379 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -828,8 +828,11 @@ struct _xlator {  };  typedef struct { -        int32_t (*init) (xlator_t *this); -        void    (*fini) (xlator_t *this); +        int32_t                 (*init) (xlator_t *this); +        void                    (*fini) (xlator_t *this); +        int32_t                 (*reconfigure) (xlator_t *this, +                                                dict_t *options); +        event_notify_fn_t       notify;  } class_methods_t;  #define xlator_has_parent(xl) (xl->parents != NULL) diff --git a/xlators/cluster/dht/src/Makefile.am b/xlators/cluster/dht/src/Makefile.am index 5324d21151e..174bea84110 100644 --- a/xlators/cluster/dht/src/Makefile.am +++ b/xlators/cluster/dht/src/Makefile.am @@ -4,7 +4,7 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/cluster  dht_common_source = dht-layout.c dht-helper.c dht-linkfile.c dht-rebalance.c \  	dht-selfheal.c dht-rename.c dht-hashfn.c dht-diskusage.c \ -	dht-common.c dht-inode-write.c dht-inode-read.c \ +	dht-common.c dht-inode-write.c dht-inode-read.c dht-shared.c \  	$(top_builddir)/xlators/lib/src/libxlator.c  dht_la_SOURCES = $(dht_common_source) dht.c diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index 3679918d79f..f079e688be9 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -684,6 +684,9 @@ int32_t dht_setattr (call_frame_t  *frame, xlator_t *this, loc_t *loc,  int32_t dht_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,                        struct iatt  *stbuf, int32_t valid, dict_t *xdata); +int32_t dht_init (xlator_t *this); +void    dht_fini (xlator_t *this); +int     dht_reconfigure (xlator_t *this, dict_t *options);  int32_t dht_notify (xlator_t *this, int32_t event, void *data, ...);  /* definitions for nufa/switch */ @@ -754,4 +757,12 @@ xlator_t *  dht_subvol_maxspace_nonzeroinode (xlator_t *this, xlator_t *subvol);  int  dht_linkfile_attr_heal (call_frame_t *frame, xlator_t *this); + +void +dht_layout_dump (dht_layout_t  *layout, const char *prefix); +int32_t +dht_priv_dump (xlator_t *this); +int32_t +dht_inodectx_dump (xlator_t *this, inode_t *inode); +  #endif/* _DHT_H */ diff --git a/xlators/cluster/dht/src/dht-shared.c b/xlators/cluster/dht/src/dht-shared.c new file mode 100644 index 00000000000..6b91c56a1df --- /dev/null +++ b/xlators/cluster/dht/src/dht-shared.c @@ -0,0 +1,732 @@ +/* +  Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> +  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 + +/* TODO: add NS locking */ + +#include "statedump.h" +#include "dht-common.h" + +/* TODO: +   - use volumename in xattr instead of "dht" +   - use NS locks +   - handle all cases in self heal layout reconstruction +   - complete linkfile selfheal +*/ +struct volume_options options[]; + +void +dht_layout_dump (dht_layout_t  *layout, const char *prefix) +{ + +        char    key[GF_DUMP_MAX_BUF_LEN]; +        int     i = 0; + +        if (!layout) +                goto out; +        if (!prefix) +                goto out; + +        gf_proc_dump_build_key(key, prefix, "cnt"); +        gf_proc_dump_write(key, "%d", layout->cnt); +        gf_proc_dump_build_key(key, prefix, "preset"); +        gf_proc_dump_write(key, "%d", layout->preset); +        gf_proc_dump_build_key(key, prefix, "gen"); +        gf_proc_dump_write(key, "%d", layout->gen); +        if (layout->type != IA_INVAL) { +                gf_proc_dump_build_key(key, prefix, "inode type"); +                gf_proc_dump_write(key, "%d", layout->type); +        } + +        if  (!IA_ISDIR (layout->type)) +                goto out; + +        for (i = 0; i < layout->cnt; i++) { +                gf_proc_dump_build_key(key, prefix,"list[%d].err", i); +                gf_proc_dump_write(key, "%d", layout->list[i].err); +                gf_proc_dump_build_key(key, prefix,"list[%d].start", i); +                gf_proc_dump_write(key, "%u", layout->list[i].start); +                gf_proc_dump_build_key(key, prefix,"list[%d].stop", i); +                gf_proc_dump_write(key, "%u", layout->list[i].stop); +                if (layout->list[i].xlator) { +                        gf_proc_dump_build_key(key, prefix, +                                               "list[%d].xlator.type", i); +                        gf_proc_dump_write(key, "%s", +                                           layout->list[i].xlator->type); +                        gf_proc_dump_build_key(key, prefix, +                                               "list[%d].xlator.name", i); +                        gf_proc_dump_write(key, "%s", +                                           layout->list[i].xlator->name); +                } +        } + +out: +        return; +} + + +int32_t +dht_priv_dump (xlator_t *this) +{ +        char            key_prefix[GF_DUMP_MAX_BUF_LEN]; +        char            key[GF_DUMP_MAX_BUF_LEN]; +        int             i = 0; +        dht_conf_t      *conf = NULL; +        int             ret = -1; + +        if (!this) +                goto out; + +        conf = this->private; +        if (!conf) +                goto out; + +        ret = TRY_LOCK(&conf->subvolume_lock); +        if (ret != 0) { +                return ret; +        } + +        gf_proc_dump_add_section("xlator.cluster.dht.%s.priv", this->name); +        gf_proc_dump_build_key(key_prefix,"xlator.cluster.dht","%s.priv", +                               this->name); +        gf_proc_dump_write("subvol_cnt","%d", conf->subvolume_cnt); +        for (i = 0; i < conf->subvolume_cnt; i++) { +                sprintf (key, "subvolumes[%d]", i); +                gf_proc_dump_write(key, "%s.%s", conf->subvolumes[i]->type, +                                   conf->subvolumes[i]->name); +                if (conf->file_layouts && conf->file_layouts[i]){ +                        sprintf (key, "file_layouts[%d]", i); +                        dht_layout_dump(conf->file_layouts[i], key); +                } +                if (conf->dir_layouts && conf->dir_layouts[i]) { +                        sprintf (key, "dir_layouts[%d]", i); +                        dht_layout_dump(conf->dir_layouts[i], key); +                } +                if (conf->subvolume_status) { + +                        sprintf (key, "subvolume_status[%d]", i); +                        gf_proc_dump_write(key, "%d", +                                           (int)conf->subvolume_status[i]); +                } + +        } + +        gf_proc_dump_write("search_unhashed", "%d", conf->search_unhashed); +        gf_proc_dump_write("gen", "%d", conf->gen); +        gf_proc_dump_write("min_free_disk", "%lf", conf->min_free_disk); +	gf_proc_dump_write("min_free_inodes", "%lf", conf->min_free_inodes); +        gf_proc_dump_write("disk_unit", "%c", conf->disk_unit); +        gf_proc_dump_write("refresh_interval", "%d", conf->refresh_interval); +        gf_proc_dump_write("unhashed_sticky_bit", "%d", conf->unhashed_sticky_bit); +        if (conf ->du_stats) { +                gf_proc_dump_write("du_stats.avail_percent", "%lf", +                                   conf->du_stats->avail_percent); +                gf_proc_dump_write("du_stats.avail_space", "%lu", +                                   conf->du_stats->avail_space); +		gf_proc_dump_write("du_stats.avail_inodes", "%lf", +                                   conf->du_stats->avail_inodes); +                gf_proc_dump_write("du_stats.log", "%lu", conf->du_stats->log); +        } + +        if (conf->last_stat_fetch.tv_sec) +                gf_proc_dump_write("last_stat_fetch", "%s", +                                    ctime(&conf->last_stat_fetch.tv_sec)); + +        UNLOCK(&conf->subvolume_lock); + +out: +        return ret; +} + +int32_t +dht_inodectx_dump (xlator_t *this, inode_t *inode) +{ +        int             ret = -1; +        dht_layout_t    *layout = NULL; + +        if (!this) +                goto out; +        if (!inode) +                goto out; + +        ret = dht_inode_ctx_layout_get (inode, this, &layout); + +        if ((ret != 0) || !layout) +                return ret; + +        gf_proc_dump_add_section("xlator.cluster.dht.%s.inode", this->name); +        dht_layout_dump(layout, "layout"); + +out: +        return ret; +} + +void +dht_fini (xlator_t *this) +{ +        int         i = 0; +        dht_conf_t *conf = NULL; + +        GF_VALIDATE_OR_GOTO ("dht", this, out); + +        conf = this->private; +        this->private = NULL; +        if (conf) { +                if (conf->file_layouts) { +                        for (i = 0; i < conf->subvolume_cnt; i++) { +                                GF_FREE (conf->file_layouts[i]); +                        } +                        GF_FREE (conf->file_layouts); +                } + +                GF_FREE (conf->subvolumes); + +                GF_FREE (conf->subvolume_status); + +                GF_FREE (conf); +        } +out: +        return; +} + +int32_t +mem_acct_init (xlator_t *this) +{ +        int     ret = -1; + +        GF_VALIDATE_OR_GOTO ("dht", this, out); + +        ret = xlator_mem_acct_init (this, gf_dht_mt_end + 1); + +        if (ret != 0) { +                gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" +                        "failed"); +                return ret; +        } +out: +        return ret; +} + + +int +dht_parse_decommissioned_bricks (xlator_t *this, dht_conf_t *conf, +                                 const char *bricks) +{ +        int         i  = 0; +        int         ret  = -1; +        char       *tmpstr = NULL; +        char       *dup_brick = NULL; +        char       *node = NULL; + +        if (!conf || !bricks) +                goto out; + +        dup_brick = gf_strdup (bricks); +        node = strtok_r (dup_brick, ",", &tmpstr); +        while (node) { +                for (i = 0; i < conf->subvolume_cnt; i++) { +                        if (!strcmp (conf->subvolumes[i]->name, node)) { +                                conf->decommissioned_bricks[i] = +                                        conf->subvolumes[i]; +                                        conf->decommission_subvols_cnt++; +                                gf_log (this->name, GF_LOG_INFO, +                                        "decommissioning subvolume %s", +                                        conf->subvolumes[i]->name); +                                break; +                        } +                } +                if (i == conf->subvolume_cnt) { +                        /* Wrong node given. */ +                        goto out; +                } +                node = strtok_r (NULL, ",", &tmpstr); +        } + +        ret = 0; +        conf->decommission_in_progress = 1; +out: +        GF_FREE (dup_brick); + +        return ret; +} + +void +dht_init_regex (xlator_t *this, dict_t *odict, char *name, +                regex_t *re, gf_boolean_t *re_valid) +{ +        char    *temp_str; + +        if (dict_get_str (odict, name, &temp_str) != 0) { +                if (strcmp(name,"rsync-hash-regex")) { +                        return; +                } +                temp_str = "^\\.(.+)\\.[^.]+$"; +        } + +        if (*re_valid) { +                regfree(re); +                *re_valid = _gf_false; +        } + +        if (!strcmp(temp_str,"none")) { +                return; +        } + +        if (regcomp(re,temp_str,REG_EXTENDED) == 0) { +                gf_log (this->name, GF_LOG_INFO, +                        "using regex %s = %s", name, temp_str); +                *re_valid = _gf_true; +        } +        else { +                gf_log (this->name, GF_LOG_WARNING, +                        "compiling regex %s failed", temp_str); +        } +} + +int +dht_reconfigure (xlator_t *this, dict_t *options) +{ +        dht_conf_t      *conf = NULL; +        char            *temp_str = NULL; +        gf_boolean_t     search_unhashed; +        int              ret = -1; + +        GF_VALIDATE_OR_GOTO ("dht", this, out); +        GF_VALIDATE_OR_GOTO ("dht", options, out); + +        conf = this->private; +        if (!conf) +                return 0; + +        if (dict_get_str (options, "lookup-unhashed", &temp_str) == 0) { +                /* If option is not "auto", other options _should_ be boolean*/ +                if (strcasecmp (temp_str, "auto")) { +                        if (!gf_string2boolean (temp_str, &search_unhashed)) { +                                gf_log(this->name, GF_LOG_DEBUG, "Reconfigure:" +                                       " lookup-unhashed reconfigured (%s)", +                                       temp_str); +                                conf->search_unhashed = search_unhashed; +                        } else { +                                gf_log(this->name, GF_LOG_ERROR, "Reconfigure:" +                                       " lookup-unhashed should be boolean," +                                       " not (%s), defaulting to (%d)", +                                       temp_str, conf->search_unhashed); +                                //return -1; +                                ret = -1; +                                goto out; +                        } +                } else { +                        gf_log(this->name, GF_LOG_DEBUG, "Reconfigure:" +                               " lookup-unhashed reconfigured auto "); +                        conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO; +                } +        } + +	GF_OPTION_RECONF ("min-free-disk", conf->min_free_disk, options, +                          percent_or_size, out); +        /* option can be any one of percent or bytes */ +        conf->disk_unit = 0; +        if (conf->min_free_disk < 100.0) +                conf->disk_unit = 'p'; + +	GF_OPTION_RECONF ("min-free-inodes", conf->min_free_inodes, options, +                          percent, out); + +        GF_OPTION_RECONF ("directory-layout-spread", conf->dir_spread_cnt, +                          options, uint32, out); + +        GF_OPTION_RECONF ("readdir-optimize", conf->readdir_optimize, options, +                          bool, out); +        if (conf->defrag) { +                GF_OPTION_RECONF ("rebalance-stats", conf->defrag->stats, +                                  options, bool, out); +        } + +        if (dict_get_str (options, "decommissioned-bricks", &temp_str) == 0) { +                ret = dht_parse_decommissioned_bricks (this, conf, temp_str); +                if (ret == -1) +                        goto out; +        } + +        dht_init_regex (this, options, "rsync-hash-regex", +                        &conf->rsync_regex, &conf->rsync_regex_valid); +        dht_init_regex (this, options, "extra-hash-regex", +                        &conf->extra_regex, &conf->extra_regex_valid); + +        ret = 0; +out: +        return ret; +} + +static int +gf_defrag_pattern_list_fill (xlator_t *this, gf_defrag_info_t *defrag, char *data) +{ +        int                    ret = -1; +        char                  *tmp_str = NULL; +        char                  *tmp_str1 = NULL; +        char                  *dup_str = NULL; +        char                  *num = NULL; +        char                  *pattern_str = NULL; +        char                  *pattern = NULL; +        gf_defrag_pattern_list_t *temp_list = NULL; +        gf_defrag_pattern_list_t *pattern_list = NULL; + +        if (!this || !defrag || !data) +                goto out; + +        /* Get the pattern for pattern list. "pattern:<optional-size>" +         * eg: *avi, *pdf:10MB, *:1TB +         */ +        pattern_str = strtok_r (data, ",", &tmp_str); +        while (pattern_str) { +                dup_str = gf_strdup (pattern_str); +                pattern_list = GF_CALLOC (1, sizeof (gf_defrag_pattern_list_t), +                                        1); +                if (!pattern_list) { +                        goto out; +                } +                pattern = strtok_r (dup_str, ":", &tmp_str1); +                num = strtok_r (NULL, ":", &tmp_str1); +                if (!pattern) +                        goto out; +                if (!num) { +                        if (gf_string2bytesize(pattern, &pattern_list->size) +                             == 0) { +                                pattern = "*"; +                        } +                } else if (gf_string2bytesize (num, &pattern_list->size) != 0) { +                        gf_log (this->name, GF_LOG_ERROR, +                                "invalid number format \"%s\"", num); +                        goto out; +                } +                memcpy (pattern_list->path_pattern, pattern, strlen (dup_str)); + +                if (!defrag->defrag_pattern) +                        temp_list = NULL; +                else +                        temp_list = defrag->defrag_pattern; + +                pattern_list->next = temp_list; + +                defrag->defrag_pattern = pattern_list; +                pattern_list = NULL; + +                GF_FREE (dup_str); +                dup_str = NULL; + +                pattern_str = strtok_r (NULL, ",", &tmp_str); +        } + +        ret = 0; +out: +        if (ret) +                GF_FREE (pattern_list); +        GF_FREE (dup_str); + +        return ret; +} + +int +dht_init (xlator_t *this) +{ +        dht_conf_t                      *conf           = NULL; +        char                            *temp_str       = NULL; +        int                              ret            = -1; +        int                              i              = 0; +        gf_defrag_info_t                *defrag         = NULL; +        int                              cmd            = 0; +        char                            *node_uuid      = NULL; + + +        GF_VALIDATE_OR_GOTO ("dht", this, err); + +        if (!this->children) { +                gf_log (this->name, GF_LOG_CRITICAL, +                        "Distribute needs more than one subvolume"); +                return -1; +        } + +        if (!this->parents) { +                gf_log (this->name, GF_LOG_WARNING, +                        "dangling volume. check volfile"); +        } + +        conf = GF_CALLOC (1, sizeof (*conf), gf_dht_mt_dht_conf_t); +        if (!conf) { +                goto err; +        } + +        ret = dict_get_int32 (this->options, "rebalance-cmd", &cmd); + +        if (cmd) { +                defrag = GF_CALLOC (1, sizeof (gf_defrag_info_t), +                                    gf_defrag_info_mt); + +                GF_VALIDATE_OR_GOTO (this->name, defrag, err); + +                LOCK_INIT (&defrag->lock); + +                defrag->is_exiting = 0; + +                conf->defrag = defrag; + +                ret = dict_get_str (this->options, "node-uuid", &node_uuid); +                if (ret) { +                        gf_log (this->name, GF_LOG_ERROR, "node-uuid not " +                                "specified"); +                        goto err; +                } + +                if (uuid_parse (node_uuid, defrag->node_uuid)) { +                        gf_log (this->name, GF_LOG_ERROR, "Cannot parse " +                                "glusterd node uuid"); +                        goto err; +                } + +                defrag->cmd = cmd; + +                defrag->stats = _gf_false; +        } + +        conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_ON; +        if (dict_get_str (this->options, "lookup-unhashed", &temp_str) == 0) { +                /* If option is not "auto", other options _should_ be boolean */ +                if (strcasecmp (temp_str, "auto")) +                        gf_string2boolean (temp_str, &conf->search_unhashed); +                else +                        conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO; +        } + +        GF_OPTION_INIT ("unhashed-sticky-bit", conf->unhashed_sticky_bit, bool, +                        err); + +        GF_OPTION_INIT ("use-readdirp", conf->use_readdirp, bool, err); + +	GF_OPTION_INIT ("min-free-disk", conf->min_free_disk, percent_or_size, +			err); + +        GF_OPTION_INIT ("min-free-inodes", conf->min_free_inodes, percent, +                        err); + +        conf->dir_spread_cnt = conf->subvolume_cnt; +        GF_OPTION_INIT ("directory-layout-spread", conf->dir_spread_cnt, +                        uint32, err); + +        GF_OPTION_INIT ("assert-no-child-down", conf->assert_no_child_down, +                        bool, err); + +        GF_OPTION_INIT ("readdir-optimize", conf->readdir_optimize, bool, err); + +        if (defrag) { +                GF_OPTION_INIT ("rebalance-stats", defrag->stats, bool, err); +                if (dict_get_str (this->options, "rebalance-filter", &temp_str) +                    == 0) { +                        if (gf_defrag_pattern_list_fill (this, defrag, temp_str) +                            == -1) { +                                gf_log (this->name, GF_LOG_ERROR, "Cannot parse" +                                        " rebalance-filter (%s)", temp_str); +                                goto err; +                        } +                } +        } + +        /* option can be any one of percent or bytes */ +        conf->disk_unit = 0; +        if (conf->min_free_disk < 100) +                conf->disk_unit = 'p'; + +        ret = dht_init_subvolumes (this, conf); +        if (ret == -1) { +                goto err; +        } + +        if (dict_get_str (this->options, "decommissioned-bricks", &temp_str) == 0) { +                ret = dht_parse_decommissioned_bricks (this, conf, temp_str); +                if (ret == -1) +                        goto err; +        } + +        dht_init_regex (this, this->options, "rsync-hash-regex", +                        &conf->rsync_regex, &conf->rsync_regex_valid); +        dht_init_regex (this, this->options, "extra-hash-regex", +                        &conf->extra_regex, &conf->extra_regex_valid); + +        ret = dht_layouts_init (this, conf); +        if (ret == -1) { +                goto err; +        } + +        LOCK_INIT (&conf->subvolume_lock); +        LOCK_INIT (&conf->layout_lock); + +        conf->gen = 1; + +        this->local_pool = mem_pool_new (dht_local_t, 512); +        if (!this->local_pool) { +                gf_log (this->name, GF_LOG_ERROR, +                        "failed to create local_t's memory pool"); +                goto err; +        } + +        GF_OPTION_INIT ("xattr-name", conf->xattr_name, str, err); +        gf_asprintf (&conf->link_xattr_name, "%s.linkto", conf->xattr_name); +        gf_asprintf (&conf->wild_xattr_name, "%s*", conf->xattr_name); +        if (!conf->link_xattr_name || !conf->wild_xattr_name) { +                goto err; +        } + +        this->private = conf; + +        return 0; + +err: +        if (conf) { +                if (conf->file_layouts) { +                        for (i = 0; i < conf->subvolume_cnt; i++) { +                                GF_FREE (conf->file_layouts[i]); +                        } +                        GF_FREE (conf->file_layouts); +                } + +                GF_FREE (conf->subvolumes); + +                GF_FREE (conf->subvolume_status); + +                GF_FREE (conf->du_stats); + +                GF_FREE (conf->defrag); + +                GF_FREE (conf->xattr_name); +                GF_FREE (conf->link_xattr_name); +                GF_FREE (conf->wild_xattr_name); + +                GF_FREE (conf); +        } + +        return -1; +} + + +struct volume_options options[] = { +        { .key  = {"lookup-unhashed"}, +          .value = {"auto", "yes", "no", "enable", "disable", "1", "0", +                    "on", "off"}, +          .type = GF_OPTION_TYPE_STR, +          .default_value = "on", +          .description = "This option if set to ON, does a lookup through " +          "all the sub-volumes, in case a lookup didn't return any result " +          "from the hash subvolume. If set to OFF, it does not do a lookup " +          "on the remaining subvolumes." +        }, +        { .key  = {"min-free-disk"}, +          .type = GF_OPTION_TYPE_PERCENT_OR_SIZET, +          .default_value = "10%", +          .description = "Percentage/Size of disk space, after which the " +          "process starts balancing out the cluster, and logs will appear " +          "in log files", +        }, +	{ .key  = {"min-free-inodes"}, +          .type = GF_OPTION_TYPE_PERCENT, +          .default_value = "5%", +          .description = "after system has only N% of inodes, warnings " +          "starts to appear in log files", +        }, +        { .key = {"unhashed-sticky-bit"}, +          .type = GF_OPTION_TYPE_BOOL, +          .default_value = "off", +        }, +        { .key = {"use-readdirp"}, +          .type = GF_OPTION_TYPE_BOOL, +          .default_value = "on", +          .description = "This option if set to ON, forces the use of " +          "readdirp, and hence also displays the stats of the files." +        }, +        { .key = {"assert-no-child-down"}, +          .type = GF_OPTION_TYPE_BOOL, +          .default_value = "off", +          .description = "This option if set to ON, in the event of " +          "CHILD_DOWN, will call exit." +        }, +        { .key  = {"directory-layout-spread"}, +          .type = GF_OPTION_TYPE_INT, +          .min  = 1, +          .validate = GF_OPT_VALIDATE_MIN, +          .description = "Specifies the directory layout spread." +        }, +        { .key  = {"decommissioned-bricks"}, +          .type = GF_OPTION_TYPE_ANY, +          .description = "This option if set to ON, decommissions " +          "the brick, so that no new data is allowed to be created " +          "on that brick." +        }, +        { .key  = {"rebalance-cmd"}, +          .type = GF_OPTION_TYPE_INT, +        }, +        { .key = {"node-uuid"}, +          .type = GF_OPTION_TYPE_STR, +        }, +        { .key = {"rebalance-stats"}, +          .type = GF_OPTION_TYPE_BOOL, +          .default_value = "off", +          .description = "This option if set to ON displays and logs the " +          " time taken for migration of each file, during the rebalance " +          "process. If set to OFF, the rebalance logs will only display the " +          "time spent in each directory." +        }, +        { .key = {"readdir-optimize"}, +          .type = GF_OPTION_TYPE_BOOL, +          .default_value = "off", +          .description = "This option if set to ON enables the optimization " +          "that allows DHT to requests non-first subvolumes to filter out " +          "directory entries." +        }, +        { .key = {"rsync-hash-regex"}, +          .type = GF_OPTION_TYPE_STR, +          /* Setting a default here doesn't work.  See dht_init_regex. */ +          .description = "Regular expression for stripping temporary-file " +          "suffix and prefix used by rsync, to prevent relocation when the " +          "file is renamed." +        }, +        { .key = {"extra-hash-regex"}, +          .type = GF_OPTION_TYPE_STR, +          /* Setting a default here doesn't work.  See dht_init_regex. */ +          .description = "Regular expression for stripping temporary-file " +          "suffix and prefix used by an application, to prevent relocation when " +          "the file is renamed." +        }, +        { .key = {"rebalance-filter"}, +          .type = GF_OPTION_TYPE_STR, +        }, + +        { .key = {"xattr-name"}, +          .type = GF_OPTION_TYPE_STR, +          .default_value = "trusted.glusterfs.dht", +          .description = "Base for extended attributes used by this " +          "translator instance, to avoid conflicts with others above or " +          "below it." +        }, + +        /* NUFA option */ +        { .key  = {"local-volume-name"}, +          .type = GF_OPTION_TYPE_XLATOR +        }, + +        /* switch option */ +        { .key  = {"pattern.switch.case"}, +          .type = GF_OPTION_TYPE_ANY +        }, + +        { .key  = {NULL} }, +}; diff --git a/xlators/cluster/dht/src/dht.c b/xlators/cluster/dht/src/dht.c index 777086ab4bc..814f0a8eb6f 100644 --- a/xlators/cluster/dht/src/dht.c +++ b/xlators/cluster/dht/src/dht.c @@ -14,633 +14,15 @@  #include "config.h"  #endif -/* TODO: add NS locking */ -  #include "statedump.h"  #include "dht-common.h" -/* TODO: -   - use volumename in xattr instead of "dht" -   - use NS locks -   - handle all cases in self heal layout reconstruction -   - complete linkfile selfheal -*/ -struct volume_options options[]; - -void -dht_layout_dump (dht_layout_t  *layout, const char *prefix) -{ - -        char    key[GF_DUMP_MAX_BUF_LEN]; -        int     i = 0; - -        if (!layout) -                goto out; -        if (!prefix) -                goto out; - -        gf_proc_dump_build_key(key, prefix, "cnt"); -        gf_proc_dump_write(key, "%d", layout->cnt); -        gf_proc_dump_build_key(key, prefix, "preset"); -        gf_proc_dump_write(key, "%d", layout->preset); -        gf_proc_dump_build_key(key, prefix, "gen"); -        gf_proc_dump_write(key, "%d", layout->gen); -        if (layout->type != IA_INVAL) { -                gf_proc_dump_build_key(key, prefix, "inode type"); -                gf_proc_dump_write(key, "%d", layout->type); -        } - -        if  (!IA_ISDIR (layout->type)) -                goto out; - -        for (i = 0; i < layout->cnt; i++) { -                gf_proc_dump_build_key(key, prefix,"list[%d].err", i); -                gf_proc_dump_write(key, "%d", layout->list[i].err); -                gf_proc_dump_build_key(key, prefix,"list[%d].start", i); -                gf_proc_dump_write(key, "%u", layout->list[i].start); -                gf_proc_dump_build_key(key, prefix,"list[%d].stop", i); -                gf_proc_dump_write(key, "%u", layout->list[i].stop); -                if (layout->list[i].xlator) { -                        gf_proc_dump_build_key(key, prefix, -                                               "list[%d].xlator.type", i); -                        gf_proc_dump_write(key, "%s", -                                           layout->list[i].xlator->type); -                        gf_proc_dump_build_key(key, prefix, -                                               "list[%d].xlator.name", i); -                        gf_proc_dump_write(key, "%s", -                                           layout->list[i].xlator->name); -                } -        } - -out: -        return; -} - - -int32_t -dht_priv_dump (xlator_t *this) -{ -        char            key_prefix[GF_DUMP_MAX_BUF_LEN]; -        char            key[GF_DUMP_MAX_BUF_LEN]; -        int             i = 0; -        dht_conf_t      *conf = NULL; -        int             ret = -1; - -        if (!this) -                goto out; - -        conf = this->private; -        if (!conf) -                goto out; - -        ret = TRY_LOCK(&conf->subvolume_lock); -        if (ret != 0) { -                return ret; -        } - -        gf_proc_dump_add_section("xlator.cluster.dht.%s.priv", this->name); -        gf_proc_dump_build_key(key_prefix,"xlator.cluster.dht","%s.priv", -                               this->name); -        gf_proc_dump_write("subvol_cnt","%d", conf->subvolume_cnt); -        for (i = 0; i < conf->subvolume_cnt; i++) { -                sprintf (key, "subvolumes[%d]", i); -                gf_proc_dump_write(key, "%s.%s", conf->subvolumes[i]->type, -                                   conf->subvolumes[i]->name); -                if (conf->file_layouts && conf->file_layouts[i]){ -                        sprintf (key, "file_layouts[%d]", i); -                        dht_layout_dump(conf->file_layouts[i], key); -                } -                if (conf->dir_layouts && conf->dir_layouts[i]) { -                        sprintf (key, "dir_layouts[%d]", i); -                        dht_layout_dump(conf->dir_layouts[i], key); -                } -                if (conf->subvolume_status) { - -                        sprintf (key, "subvolume_status[%d]", i); -                        gf_proc_dump_write(key, "%d", -                                           (int)conf->subvolume_status[i]); -                } - -        } - -        gf_proc_dump_write("search_unhashed", "%d", conf->search_unhashed); -        gf_proc_dump_write("gen", "%d", conf->gen); -        gf_proc_dump_write("min_free_disk", "%lf", conf->min_free_disk); -	gf_proc_dump_write("min_free_inodes", "%lf", conf->min_free_inodes); -        gf_proc_dump_write("disk_unit", "%c", conf->disk_unit); -        gf_proc_dump_write("refresh_interval", "%d", conf->refresh_interval); -        gf_proc_dump_write("unhashed_sticky_bit", "%d", conf->unhashed_sticky_bit); -        if (conf ->du_stats) { -                gf_proc_dump_write("du_stats.avail_percent", "%lf", -                                   conf->du_stats->avail_percent); -                gf_proc_dump_write("du_stats.avail_space", "%lu", -                                   conf->du_stats->avail_space); -		gf_proc_dump_write("du_stats.avail_inodes", "%lf", -                                   conf->du_stats->avail_inodes); -                gf_proc_dump_write("du_stats.log", "%lu", conf->du_stats->log); -        } - -        if (conf->last_stat_fetch.tv_sec) -                gf_proc_dump_write("last_stat_fetch", "%s", -                                    ctime(&conf->last_stat_fetch.tv_sec)); - -        UNLOCK(&conf->subvolume_lock); - -out: -        return ret; -} - -int32_t -dht_inodectx_dump (xlator_t *this, inode_t *inode) -{ -        int             ret = -1; -        dht_layout_t    *layout = NULL; - -        if (!this) -                goto out; -        if (!inode) -                goto out; - -        ret = dht_inode_ctx_layout_get (inode, this, &layout); - -        if ((ret != 0) || !layout) -                return ret; - -        gf_proc_dump_add_section("xlator.cluster.dht.%s.inode", this->name); -        dht_layout_dump(layout, "layout"); - -out: -        return ret; -} - -int -notify (xlator_t *this, int event, void *data, ...) -{ -        int              ret = -1; -        va_list          ap; -        dict_t          *output = NULL; - -        GF_VALIDATE_OR_GOTO ("dht", this, out); - - -        if (!data) -                goto out; - -        va_start (ap, data); -        output = va_arg (ap, dict_t*); - -        ret = dht_notify (this, event, data, output); - -out: -        return ret; -} - -void -fini (xlator_t *this) -{ -        int         i = 0; -        dht_conf_t *conf = NULL; - -        GF_VALIDATE_OR_GOTO ("dht", this, out); - -        conf = this->private; -        this->private = NULL; -        if (conf) { -                if (conf->file_layouts) { -                        for (i = 0; i < conf->subvolume_cnt; i++) { -                                GF_FREE (conf->file_layouts[i]); -                        } -                        GF_FREE (conf->file_layouts); -                } - -                GF_FREE (conf->subvolumes); - -                GF_FREE (conf->subvolume_status); - -                GF_FREE (conf); -        } -out: -        return; -} - -int32_t -mem_acct_init (xlator_t *this) -{ -        int     ret = -1; - -        GF_VALIDATE_OR_GOTO ("dht", this, out); - -        ret = xlator_mem_acct_init (this, gf_dht_mt_end + 1); - -        if (ret != 0) { -                gf_log (this->name, GF_LOG_ERROR, "Memory accounting init" -                        "failed"); -                return ret; -        } -out: -        return ret; -} - - -int -dht_parse_decommissioned_bricks (xlator_t *this, dht_conf_t *conf, -                                 const char *bricks) -{ -        int         i  = 0; -        int         ret  = -1; -        char       *tmpstr = NULL; -        char       *dup_brick = NULL; -        char       *node = NULL; - -        if (!conf || !bricks) -                goto out; - -        dup_brick = gf_strdup (bricks); -        node = strtok_r (dup_brick, ",", &tmpstr); -        while (node) { -                for (i = 0; i < conf->subvolume_cnt; i++) { -                        if (!strcmp (conf->subvolumes[i]->name, node)) { -                                conf->decommissioned_bricks[i] = -                                        conf->subvolumes[i]; -                                        conf->decommission_subvols_cnt++; -                                gf_log (this->name, GF_LOG_INFO, -                                        "decommissioning subvolume %s", -                                        conf->subvolumes[i]->name); -                                break; -                        } -                } -                if (i == conf->subvolume_cnt) { -                        /* Wrong node given. */ -                        goto out; -                } -                node = strtok_r (NULL, ",", &tmpstr); -        } - -        ret = 0; -        conf->decommission_in_progress = 1; -out: -        GF_FREE (dup_brick); - -        return ret; -} - -void -dht_init_regex (xlator_t *this, dict_t *odict, char *name, -                regex_t *re, gf_boolean_t *re_valid) -{ -        char    *temp_str; - -        if (dict_get_str (odict, name, &temp_str) != 0) { -                if (strcmp(name,"rsync-hash-regex")) { -                        return; -                } -                temp_str = "^\\.(.+)\\.[^.]+$"; -        } - -        if (*re_valid) { -                regfree(re); -                *re_valid = _gf_false; -        } - -        if (!strcmp(temp_str,"none")) { -                return; -        } - -        if (regcomp(re,temp_str,REG_EXTENDED) == 0) { -                gf_log (this->name, GF_LOG_INFO, -                        "using regex %s = %s", name, temp_str); -                *re_valid = _gf_true; -        } -        else { -                gf_log (this->name, GF_LOG_WARNING, -                        "compiling regex %s failed", temp_str); -        } -} - -int -reconfigure (xlator_t *this, dict_t *options) -{ -        dht_conf_t      *conf = NULL; -        char            *temp_str = NULL; -        gf_boolean_t     search_unhashed; -        int              ret = -1; - -        GF_VALIDATE_OR_GOTO ("dht", this, out); -        GF_VALIDATE_OR_GOTO ("dht", options, out); - -        conf = this->private; -        if (!conf) -                return 0; - -        if (dict_get_str (options, "lookup-unhashed", &temp_str) == 0) { -                /* If option is not "auto", other options _should_ be boolean*/ -                if (strcasecmp (temp_str, "auto")) { -                        if (!gf_string2boolean (temp_str, &search_unhashed)) { -                                gf_log(this->name, GF_LOG_DEBUG, "Reconfigure:" -                                       " lookup-unhashed reconfigured (%s)", -                                       temp_str); -                                conf->search_unhashed = search_unhashed; -                        } else { -                                gf_log(this->name, GF_LOG_ERROR, "Reconfigure:" -                                       " lookup-unhashed should be boolean," -                                       " not (%s), defaulting to (%d)", -                                       temp_str, conf->search_unhashed); -                                //return -1; -                                ret = -1; -                                goto out; -                        } -                } else { -                        gf_log(this->name, GF_LOG_DEBUG, "Reconfigure:" -                               " lookup-unhashed reconfigured auto "); -                        conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO; -                } -        } - -	GF_OPTION_RECONF ("min-free-disk", conf->min_free_disk, options, -                          percent_or_size, out); -        /* option can be any one of percent or bytes */ -        conf->disk_unit = 0; -        if (conf->min_free_disk < 100.0) -                conf->disk_unit = 'p'; - -	GF_OPTION_RECONF ("min-free-inodes", conf->min_free_inodes, options, -                          percent, out); - -        GF_OPTION_RECONF ("directory-layout-spread", conf->dir_spread_cnt, -                          options, uint32, out); - -        GF_OPTION_RECONF ("readdir-optimize", conf->readdir_optimize, options, -                          bool, out); -        if (conf->defrag) { -                GF_OPTION_RECONF ("rebalance-stats", conf->defrag->stats, -                                  options, bool, out); -        } - -        if (dict_get_str (options, "decommissioned-bricks", &temp_str) == 0) { -                ret = dht_parse_decommissioned_bricks (this, conf, temp_str); -                if (ret == -1) -                        goto out; -        } - -        dht_init_regex (this, options, "rsync-hash-regex", -                        &conf->rsync_regex, &conf->rsync_regex_valid); -        dht_init_regex (this, options, "extra-hash-regex", -                        &conf->extra_regex, &conf->extra_regex_valid); - -        ret = 0; -out: -        return ret; -} - -static int -gf_defrag_pattern_list_fill (xlator_t *this, gf_defrag_info_t *defrag, char *data) -{ -        int                    ret = -1; -        char                  *tmp_str = NULL; -        char                  *tmp_str1 = NULL; -        char                  *dup_str = NULL; -        char                  *num = NULL; -        char                  *pattern_str = NULL; -        char                  *pattern = NULL; -        gf_defrag_pattern_list_t *temp_list = NULL; -        gf_defrag_pattern_list_t *pattern_list = NULL; - -        if (!this || !defrag || !data) -                goto out; - -        /* Get the pattern for pattern list. "pattern:<optional-size>" -         * eg: *avi, *pdf:10MB, *:1TB -         */ -        pattern_str = strtok_r (data, ",", &tmp_str); -        while (pattern_str) { -                dup_str = gf_strdup (pattern_str); -                pattern_list = GF_CALLOC (1, sizeof (gf_defrag_pattern_list_t), -                                        1); -                if (!pattern_list) { -                        goto out; -                } -                pattern = strtok_r (dup_str, ":", &tmp_str1); -                num = strtok_r (NULL, ":", &tmp_str1); -                if (!pattern) -                        goto out; -                if (!num) { -                        if (gf_string2bytesize(pattern, &pattern_list->size) -                             == 0) { -                                pattern = "*"; -                        } -                } else if (gf_string2bytesize (num, &pattern_list->size) != 0) { -                        gf_log (this->name, GF_LOG_ERROR, -                                "invalid number format \"%s\"", num); -                        goto out; -                } -                memcpy (pattern_list->path_pattern, pattern, strlen (dup_str)); - -                if (!defrag->defrag_pattern) -                        temp_list = NULL; -                else -                        temp_list = defrag->defrag_pattern; - -                pattern_list->next = temp_list; - -                defrag->defrag_pattern = pattern_list; -                pattern_list = NULL; - -                GF_FREE (dup_str); -                dup_str = NULL; - -                pattern_str = strtok_r (NULL, ",", &tmp_str); -        } - -        ret = 0; -out: -        if (ret) -                GF_FREE (pattern_list); -        GF_FREE (dup_str); - -        return ret; -} - -int -init (xlator_t *this) -{ -        dht_conf_t                      *conf           = NULL; -        char                            *temp_str       = NULL; -        int                              ret            = -1; -        int                              i              = 0; -        gf_defrag_info_t                *defrag         = NULL; -        int                              cmd            = 0; -        char                            *node_uuid      = NULL; - - -        GF_VALIDATE_OR_GOTO ("dht", this, err); - -        if (!this->children) { -                gf_log (this->name, GF_LOG_CRITICAL, -                        "Distribute needs more than one subvolume"); -                return -1; -        } - -        if (!this->parents) { -                gf_log (this->name, GF_LOG_WARNING, -                        "dangling volume. check volfile"); -        } - -        conf = GF_CALLOC (1, sizeof (*conf), gf_dht_mt_dht_conf_t); -        if (!conf) { -                goto err; -        } -        memset (conf, 0, sizeof(*conf)); - -        ret = dict_get_int32 (this->options, "rebalance-cmd", &cmd); - -        if (cmd) { -                defrag = GF_CALLOC (1, sizeof (gf_defrag_info_t), -                                    gf_defrag_info_mt); - -                GF_VALIDATE_OR_GOTO (this->name, defrag, err); - -                LOCK_INIT (&defrag->lock); - -                defrag->is_exiting = 0; - -                conf->defrag = defrag; - -                ret = dict_get_str (this->options, "node-uuid", &node_uuid); -                if (ret) { -                        gf_log (this->name, GF_LOG_ERROR, "node-uuid not " -                                "specified"); -                        goto err; -                } - -                if (uuid_parse (node_uuid, defrag->node_uuid)) { -                        gf_log (this->name, GF_LOG_ERROR, "Cannot parse " -                                "glusterd node uuid"); -                        goto err; -                } - -                defrag->cmd = cmd; - -                defrag->stats = _gf_false; -        } - -        conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_ON; -        if (dict_get_str (this->options, "lookup-unhashed", &temp_str) == 0) { -                /* If option is not "auto", other options _should_ be boolean */ -                if (strcasecmp (temp_str, "auto")) -                        gf_string2boolean (temp_str, &conf->search_unhashed); -                else -                        conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO; -        } - -        GF_OPTION_INIT ("unhashed-sticky-bit", conf->unhashed_sticky_bit, bool, -                        err); - -        GF_OPTION_INIT ("use-readdirp", conf->use_readdirp, bool, err); - -	GF_OPTION_INIT ("min-free-disk", conf->min_free_disk, percent_or_size, -			err); - -        GF_OPTION_INIT ("min-free-inodes", conf->min_free_inodes, percent, -                        err); - -        conf->dir_spread_cnt = conf->subvolume_cnt; -        GF_OPTION_INIT ("directory-layout-spread", conf->dir_spread_cnt, -                        uint32, err); - -        GF_OPTION_INIT ("assert-no-child-down", conf->assert_no_child_down, -                        bool, err); - -        GF_OPTION_INIT ("readdir-optimize", conf->readdir_optimize, bool, err); - -        if (defrag) { -                GF_OPTION_INIT ("rebalance-stats", defrag->stats, bool, err); -                if (dict_get_str (this->options, "rebalance-filter", &temp_str) -                    == 0) { -                        if (gf_defrag_pattern_list_fill (this, defrag, temp_str) -                            == -1) { -                                gf_log (this->name, GF_LOG_ERROR, "Cannot parse" -                                        " rebalance-filter (%s)", temp_str); -                                goto err; -                        } -                } -        } - -        /* option can be any one of percent or bytes */ -        conf->disk_unit = 0; -        if (conf->min_free_disk < 100) -                conf->disk_unit = 'p'; - -        ret = dht_init_subvolumes (this, conf); -        if (ret == -1) { -                goto err; -        } - -        if (dict_get_str (this->options, "decommissioned-bricks", &temp_str) == 0) { -                ret = dht_parse_decommissioned_bricks (this, conf, temp_str); -                if (ret == -1) -                        goto err; -        } - -        dht_init_regex (this, this->options, "rsync-hash-regex", -                        &conf->rsync_regex, &conf->rsync_regex_valid); -        dht_init_regex (this, this->options, "extra-hash-regex", -                        &conf->extra_regex, &conf->extra_regex_valid); - -        ret = dht_layouts_init (this, conf); -        if (ret == -1) { -                goto err; -        } - -        LOCK_INIT (&conf->subvolume_lock); -        LOCK_INIT (&conf->layout_lock); - -        conf->gen = 1; - -        this->local_pool = mem_pool_new (dht_local_t, 512); -        if (!this->local_pool) { -                gf_log (this->name, GF_LOG_ERROR, -                        "failed to create local_t's memory pool"); -                goto err; -        } - -        GF_OPTION_INIT ("xattr-name", conf->xattr_name, str, err); -        gf_asprintf (&conf->link_xattr_name, "%s.linkto", conf->xattr_name); -        gf_asprintf (&conf->wild_xattr_name, "%s*", conf->xattr_name); -        if (!conf->link_xattr_name || !conf->wild_xattr_name) { -                goto err; -        } - -        this->private = conf; - -        return 0; - -err: -        if (conf) { -                if (conf->file_layouts) { -                        for (i = 0; i < conf->subvolume_cnt; i++) { -                                GF_FREE (conf->file_layouts[i]); -                        } -                        GF_FREE (conf->file_layouts); -                } - -                GF_FREE (conf->subvolumes); - -                GF_FREE (conf->subvolume_status); - -                GF_FREE (conf->du_stats); - -                GF_FREE (conf->defrag); - -                GF_FREE (conf->xattr_name); -                GF_FREE (conf->link_xattr_name); -                GF_FREE (conf->wild_xattr_name); - -                GF_FREE (conf); -        } - -        return -1; -} - +class_methods_t class_methods = { +        .init           = dht_init, +        .fini           = dht_fini, +        .reconfigure    = dht_reconfigure, +        .notify         = dht_notify +};  struct xlator_fops fops = {          .lookup      = dht_lookup, @@ -701,105 +83,4 @@ struct xlator_cbks cbks = {  //      .releasedir = dht_releasedir,          .forget     = dht_forget  }; - - -struct volume_options options[] = { -        { .key  = {"lookup-unhashed"}, -          .value = {"auto", "yes", "no", "enable", "disable", "1", "0", -                    "on", "off"}, -          .type = GF_OPTION_TYPE_STR, -          .default_value = "on", -          .description = "This option if set to ON, does a lookup through " -          "all the sub-volumes, in case a lookup didn't return any result " -          "from the hash subvolume. If set to OFF, it does not do a lookup " -          "on the remaining subvolumes." -        }, -        { .key  = {"min-free-disk"}, -          .type = GF_OPTION_TYPE_PERCENT_OR_SIZET, -          .default_value = "10%", -          .description = "Percentage/Size of disk space, after which the " -          "process starts balancing out the cluster, and logs will appear " -          "in log files", -        }, -	{ .key  = {"min-free-inodes"}, -          .type = GF_OPTION_TYPE_PERCENT, -          .default_value = "5%", -          .description = "after system has only N% of inodes, warnings " -          "starts to appear in log files", -        }, -        { .key = {"unhashed-sticky-bit"}, -          .type = GF_OPTION_TYPE_BOOL, -          .default_value = "off", -        }, -        { .key = {"use-readdirp"}, -          .type = GF_OPTION_TYPE_BOOL, -          .default_value = "on", -          .description = "This option if set to ON, forces the use of " -          "readdirp, and hence also displays the stats of the files." -        }, -        { .key = {"assert-no-child-down"}, -          .type = GF_OPTION_TYPE_BOOL, -          .default_value = "off", -          .description = "This option if set to ON, in the event of " -          "CHILD_DOWN, will call exit." -        }, -        { .key  = {"directory-layout-spread"}, -          .type = GF_OPTION_TYPE_INT, -          .min  = 1, -          .validate = GF_OPT_VALIDATE_MIN, -          .description = "Specifies the directory layout spread." -        }, -        { .key  = {"decommissioned-bricks"}, -          .type = GF_OPTION_TYPE_ANY, -          .description = "This option if set to ON, decommissions " -          "the brick, so that no new data is allowed to be created " -          "on that brick." -        }, -        { .key  = {"rebalance-cmd"}, -          .type = GF_OPTION_TYPE_INT, -        }, -        { .key = {"node-uuid"}, -          .type = GF_OPTION_TYPE_STR, -        }, -        { .key = {"rebalance-stats"}, -          .type = GF_OPTION_TYPE_BOOL, -          .default_value = "off", -          .description = "This option if set to ON displays and logs the " -          " time taken for migration of each file, during the rebalance " -          "process. If set to OFF, the rebalance logs will only display the " -          "time spent in each directory." -        }, -        { .key = {"readdir-optimize"}, -          .type = GF_OPTION_TYPE_BOOL, -          .default_value = "off", -          .description = "This option if set to ON enables the optimization " -          "that allows DHT to requests non-first subvolumes to filter out " -          "directory entries." -        }, -        { .key = {"rsync-hash-regex"}, -          .type = GF_OPTION_TYPE_STR, -          /* Setting a default here doesn't work.  See dht_init_regex. */ -          .description = "Regular expression for stripping temporary-file " -          "suffix and prefix used by rsync, to prevent relocation when the " -          "file is renamed." -        }, -        { .key = {"extra-hash-regex"}, -          .type = GF_OPTION_TYPE_STR, -          /* Setting a default here doesn't work.  See dht_init_regex. */ -          .description = "Regular expression for stripping temporary-file " -          "suffix and prefix used by an application, to prevent relocation when " -          "the file is renamed." -        }, -        { .key = {"rebalance-filter"}, -          .type = GF_OPTION_TYPE_STR, -        }, -        { .key = {"xattr-name"}, -          .type = GF_OPTION_TYPE_STR, -          .default_value = "trusted.glusterfs.dht", -          .description = "Base for extended attributes used by this " -          "translator instance, to avoid conflicts with others above or " -          "below it." -        }, - -        { .key  = {NULL} }, -}; +; diff --git a/xlators/cluster/dht/src/nufa.c b/xlators/cluster/dht/src/nufa.c index 19f16d78a4d..5e5c6805827 100644 --- a/xlators/cluster/dht/src/nufa.c +++ b/xlators/cluster/dht/src/nufa.c @@ -18,6 +18,8 @@  /* TODO: all 'TODO's in dht.c holds good */ +extern struct volume_options options[]; +  int  nufa_local_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                         int op_ret, int op_errno, @@ -460,42 +462,6 @@ err:  } -int -notify (xlator_t *this, int event, void *data, ...) -{ -        int ret = -1; - -        ret = dht_notify (this, event, data); - -        return ret; -} - -void -fini (xlator_t *this) -{ -        int         i = 0; -        dht_conf_t *conf = NULL; - -        conf = this->private; - -        if (conf) { -                if (conf->file_layouts) { -                        for (i = 0; i < conf->subvolume_cnt; i++) { -                                GF_FREE (conf->file_layouts[i]); -                        } -                        GF_FREE (conf->file_layouts); -                } - -                GF_FREE (conf->subvolumes); - -                GF_FREE (conf->subvolume_status); - -                GF_FREE (conf); -        } - -        return; -} -  gf_boolean_t  same_first_part (char *str1, char term1, char *str2, char term2)  { @@ -516,72 +482,24 @@ same_first_part (char *str1, char term1, char *str2, char term2)          }  } -int32_t -mem_acct_init (xlator_t *this) -{ -        int     ret = -1; - -        ret = xlator_mem_acct_init (this, gf_dht_mt_end + 1); -        return ret; -} -  int -init (xlator_t *this) +nufa_init (xlator_t *this)  {          dht_conf_t    *conf = NULL;          xlator_list_t *trav = NULL;          data_t        *data = NULL;          char          *local_volname = NULL; -        char          *temp_str = NULL;          int            ret = -1; -        int            i = 0;          char           my_hostname[256]; -        double         temp_free_disk = 0; -        uint64_t       size = 0;          xlator_t      *local_subvol = NULL;          char          *brick_host = NULL;          xlator_t      *kid = NULL; -        if (!this->children) { -                gf_log (this->name, GF_LOG_CRITICAL, -                        "NUFA needs more than one subvolume"); -                return -1; +        ret = dht_init(this); +        if (ret) { +                return ret;          } - -        if (!this->parents) { -                gf_log (this->name, GF_LOG_WARNING, -                        "dangling volume. check volfile"); -        } - -        conf = GF_CALLOC (1, sizeof (*conf), -                          gf_dht_mt_dht_conf_t); -        if (!conf) { -                goto err; -        } - -        conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_ON; -        if (dict_get_str (this->options, "lookup-unhashed", &temp_str) == 0) { -                /* If option is not "auto", other options _should_ be boolean */ -                if (strcasecmp (temp_str, "auto")) -                        gf_string2boolean (temp_str, &conf->search_unhashed); -                else -                        conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO; -        } - -        ret = dht_init_subvolumes (this, conf); -        if (ret == -1) { -                goto err; -        } - -        ret = dht_layouts_init (this, conf); -        if (ret == -1) { -                goto err; -        } - -        LOCK_INIT (&conf->subvolume_lock); -        LOCK_INIT (&conf->layout_lock); - -        conf->gen = 1; +        conf = this->private;          local_volname = "localhost";          ret = gethostname (my_hostname, 256); @@ -650,69 +568,22 @@ init (xlator_t *this)          } -        /* The volume specified exists */ - -        conf->min_free_disk = 10; -        conf->disk_unit = 'p'; - -        if (dict_get_str (this->options, "min-free-disk", -                          &temp_str) == 0) { -                if (gf_string2percent (temp_str, -                                       &temp_free_disk) == 0) { -                        if (temp_free_disk > 100) { -                                gf_string2bytesize (temp_str, &size); -                                conf->min_free_disk = size; -                                conf->disk_unit = 'b'; -                        } else { -                                conf->min_free_disk = temp_free_disk; -                                conf->disk_unit = 'p'; -                        } -                } else { -                        gf_string2bytesize (temp_str, &size); -                        conf->min_free_disk = size; -                        conf->disk_unit = 'b'; -                } -        } - -        conf->du_stats = GF_CALLOC (conf->subvolume_cnt, sizeof (dht_du_t), -                                    gf_dht_mt_dht_du_t); -        if (!conf->du_stats) { -                goto err; -        } - -        this->local_pool = mem_pool_new (dht_local_t, 128); -        if (!this->local_pool) { -                gf_log (this->name, GF_LOG_ERROR, -                        "failed to create local_t's memory pool"); -                goto err; -        } - -        this->private = conf; -          return 0;  err: -        if (conf) { -                if (conf->file_layouts) { -                        for (i = 0; i < conf->subvolume_cnt; i++) { -                                GF_FREE (conf->file_layouts[i]); -                        } -                        GF_FREE (conf->file_layouts); -                } - -                GF_FREE (conf->subvolumes); - -                GF_FREE (conf->subvolume_status); - -                GF_FREE (conf->du_stats); - -                GF_FREE (conf); -        } - +        dht_fini(this);          return -1;  } +class_methods_t class_methods = { +        .init           = nufa_init, +        .fini           = dht_fini, +        .reconfigure    = dht_reconfigure, +        .notify         = dht_notify +}; + +  struct xlator_fops fops = {          .lookup      = nufa_lookup,          .create      = nufa_create, @@ -757,19 +628,3 @@ struct xlator_fops fops = {  struct xlator_cbks cbks = {          .forget     = dht_forget  }; - - -struct volume_options options[] = { -        { .key  = {"lookup-unhashed"}, -          .value = {"auto", "yes", "no", "enable", "disable", "1", "0", -                    "on", "off"}, -          .type = GF_OPTION_TYPE_STR -        }, -        { .key  = {"local-volume-name"}, -          .type = GF_OPTION_TYPE_XLATOR -        }, -        { .key  = {"min-free-disk"}, -          .type = GF_OPTION_TYPE_PERCENT_OR_SIZET, -        }, -        { .key  = {NULL} }, -}; diff --git a/xlators/cluster/dht/src/switch.c b/xlators/cluster/dht/src/switch.c index 8e0b69887cf..861012247c9 100644 --- a/xlators/cluster/dht/src/switch.c +++ b/xlators/cluster/dht/src/switch.c @@ -22,6 +22,8 @@  #include <fnmatch.h>  #include <string.h> +extern struct volume_options options[]; +  struct switch_sched_array {          xlator_t *xl;          int32_t   eligible; @@ -569,20 +571,9 @@ err:  } -int -notify (xlator_t *this, int event, void *data, ...) -{ -        int ret = -1; - -        ret = dht_notify (this, event, data); - -        return ret; -} -  void -fini (xlator_t *this) +switch_fini (xlator_t *this)  { -        int                   i = 0;          dht_conf_t           *conf = NULL;          struct switch_struct *trav = NULL;          struct switch_struct *prev = NULL; @@ -598,22 +589,9 @@ fini (xlator_t *this)                          trav = trav->next;                          GF_FREE (prev);                  } - -                if (conf->file_layouts) { -                        for (i = 0; i < conf->subvolume_cnt; i++) { -                                GF_FREE (conf->file_layouts[i]); -                        } -                        GF_FREE (conf->file_layouts); -                } - -                GF_FREE (conf->subvolumes); - -                GF_FREE (conf->subvolume_status); - -                GF_FREE (conf);          } -        return; +        dht_fini(this);  }  int @@ -839,68 +817,18 @@ err:  } -int -init (xlator_t *this) +int32_t +switch_init (xlator_t *this)  {          dht_conf_t            *conf = NULL;          data_t                *data = NULL; -        char                  *temp_str = NULL;          int                    ret = -1; -        int                    i = 0; -        double                 temp_free_disk = 0; -        uint64_t               size = 0; - -        if (!this->children) { -                gf_log (this->name, GF_LOG_CRITICAL, -                        "SWITCH needs more than one subvolume"); -                return -1; -        } - -        if (!this->parents) { -                gf_log (this->name, GF_LOG_WARNING, -                        "dangling volume. check volfile"); -        } - -        conf = GF_CALLOC (1, sizeof (*conf), gf_switch_mt_dht_conf_t); -        if (!conf) { -                goto err; -        } - -        conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_ON; -        if (dict_get_str (this->options, "lookup-unhashed", &temp_str) == 0) { -                /* If option is not "auto", other options _should_ be boolean */ -                if (strcasecmp (temp_str, "auto")) -                        gf_string2boolean (temp_str, &conf->search_unhashed); -                else -                        conf->search_unhashed = GF_DHT_LOOKUP_UNHASHED_AUTO; -        } -        conf->unhashed_sticky_bit = 0; -        if (dict_get_str (this->options, "unhashed-sticky-bit", -                          &temp_str) == 0) { -                gf_string2boolean (temp_str, &conf->unhashed_sticky_bit); -        } - -        conf->min_free_disk = 10.0; -        conf->disk_unit = 'p'; - -        if (dict_get_str (this->options, "min-free-disk", -                          &temp_str) == 0) { -                if (gf_string2percent (temp_str, &temp_free_disk) == 0) { -                        if (temp_free_disk > 100) { -                                gf_string2bytesize (temp_str, &size); -                                conf->min_free_disk = size; -                                conf->disk_unit = 'b'; -                        } else { -                                conf->min_free_disk = temp_free_disk; -                                conf->disk_unit = 'p'; -                        } -                } else { -                        gf_string2bytesize (temp_str, &size); -                        conf->min_free_disk = size; -                        conf->disk_unit = 'b'; -                } +        ret = dht_init(this); +        if (ret) { +                return ret;          } +        conf = this->private;          data = dict_get (this->options, "pattern.switch.case");          if (data) { @@ -911,60 +839,23 @@ init (xlator_t *this)                  }          } -        ret = dht_init_subvolumes (this, conf); -        if (ret == -1) { -                goto err; -        } - -        ret = dht_layouts_init (this, conf); -        if (ret == -1) { -                goto err; -        } - -        LOCK_INIT (&conf->subvolume_lock); -        LOCK_INIT (&conf->layout_lock); - -        conf->gen = 1; - -        conf->du_stats = GF_CALLOC (conf->subvolume_cnt, sizeof (dht_du_t), -                                    gf_switch_mt_dht_du_t); -        if (!conf->du_stats) { -                goto err; -        } - -        this->local_pool = mem_pool_new (dht_local_t, 128); -        if (!this->local_pool) { -                gf_log (this->name, GF_LOG_ERROR, -                        "failed to create local_t's memory pool"); -                goto err; -        } -          this->private = conf; -          return 0;  err: -        if (conf) { -                if (conf->file_layouts) { -                        for (i = 0; i < conf->subvolume_cnt; i++) { -                                GF_FREE (conf->file_layouts[i]); -                        } -                        GF_FREE (conf->file_layouts); -                } - -                GF_FREE (conf->subvolumes); - -                GF_FREE (conf->subvolume_status); - -                GF_FREE (conf->du_stats); - -                GF_FREE (conf); -        } - +        dht_fini(this);          return -1;  } +class_methods_t class_methods = { +        .init           = switch_init, +        .fini           = switch_fini, +        .reconfigure    = dht_reconfigure, +        .notify         = dht_notify +}; + +  struct xlator_fops fops = {          .lookup      = switch_lookup,          .create      = switch_create, @@ -1009,19 +900,3 @@ struct xlator_fops fops = {  struct xlator_cbks cbks = {          .forget     = dht_forget  }; - - -struct volume_options options[] = { -        { .key  = {"lookup-unhashed"}, -          .value = {"auto", "yes", "no", "enable", "disable", "1", "0", -                    "on", "off"}, -          .type = GF_OPTION_TYPE_STR -        }, -        { .key  = {"pattern.switch.case"}, -          .type = GF_OPTION_TYPE_ANY -        }, -        { .key  = {"min-free-disk"}, -          .type = GF_OPTION_TYPE_PERCENT_OR_SIZET, -        }, -        { .key  = {NULL} }, -};  | 
