diff options
| author | Krishnan Parthasarathi <kparthas@redhat.com> | 2013-06-27 17:59:43 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2013-07-04 07:30:00 -0700 | 
| commit | 45488a325f6c816675ca99874eb2cbdc0358a91e (patch) | |
| tree | 880adc74276bcf1a848723c23228608baacf727e | |
| parent | 78ee0265db1363b7b1f3943d6a3daa622b7564b8 (diff) | |
nufa: allow subvols with fanout > 1
Previously, nufa wouldn't work on volume topologies such as
distribute-replicate or distribute-stripe.
Change-Id: Ia89ed4412a00601022c1fc94f046056ce4820fe8
BUG: 980838
Signed-off-by: Krishnan Parthasarathi <kparthas@redhat.com>
Reviewed-on: http://review.gluster.org/5262
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
| -rw-r--r-- | tests/basic/nufa.t | 30 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/nufa.c | 167 | 
2 files changed, 130 insertions, 67 deletions
diff --git a/tests/basic/nufa.t b/tests/basic/nufa.t new file mode 100644 index 00000000000..05aaceec6b2 --- /dev/null +++ b/tests/basic/nufa.t @@ -0,0 +1,30 @@ +#!/bin/bash + +. $(dirname $0)/../include.rc +. $(dirname $0)/../volume.rc + +cleanup; + +TEST glusterd +TEST pidof glusterd +TEST $CLI volume info; + +TEST $CLI volume create $V0 replica 2 stripe 2 $H0:$B0/${V0}{1,2,3,4,5,6,7,8}; + +EXPECT "$V0" volinfo_field $V0 'Volume Name'; +EXPECT 'Created' volinfo_field $V0 'Status'; +EXPECT '8' brick_count $V0 + +TEST $CLI volume set $V0 nufa on; + +TEST $CLI volume start $V0; +EXPECT 'Started' volinfo_field $V0 'Status'; + +## Mount FUSE with caching disabled (read-only) +TEST glusterfs --entry-timeout=0 --attribute-timeout=0 --read-only -s $H0 --volfile-id $V0 $M1; + +## Wait for volume to register with rpc.mountd +sleep 5; + +## Mount NFS +TEST mount -t nfs -o nolock,soft,intr $H0:/$V0 $N0; diff --git a/xlators/cluster/dht/src/nufa.c b/xlators/cluster/dht/src/nufa.c index 5e5c6805827..9352ca55a49 100644 --- a/xlators/cluster/dht/src/nufa.c +++ b/xlators/cluster/dht/src/nufa.c @@ -482,92 +482,125 @@ same_first_part (char *str1, char term1, char *str2, char term2)          }  } +typedef struct nufa_args { +        xlator_t    *this; +        char        *volname; +        gf_boolean_t addr_match; +} nufa_args_t; + +static void +nufa_find_local_brick (xlator_t *xl, void *data) +{ +        nufa_args_t     *args = data; +        xlator_t        *this = args->this; +        char            *local_volname = args->volname; +        gf_boolean_t    addr_match = args->addr_match; +        char            *brick_host = NULL; +        dht_conf_t      *conf = this->private; +        int             ret = -1; + +        /*This means a local subvol was already found. We pick the first brick +         * that is local*/ +        if (conf->private) +                return; + +        if (strcmp (xl->name, local_volname) == 0) { +                conf->private = xl; +                gf_log (this->name, GF_LOG_INFO, "Using specified subvol %s", +                        local_volname); +                return; +        } + +        if (!addr_match) +                return; + +        ret = dict_get_str (xl->options, "remote-host", &brick_host); +        if ((ret == 0) && +            (gf_is_same_address (local_volname, brick_host) || +             gf_is_local_addr (brick_host))) { +                conf->private = xl; +                gf_log (this->name, GF_LOG_INFO, "Using the first local " +                        "subvol %s", xl->name); +                return; +        } + +} + +int +nufa_find_local_subvol (xlator_t *this, +                        void (*fn) (xlator_t *each, void* data), void *data) +{ +        int             ret = -1; +        dht_conf_t      *conf = this->private; +        xlator_list_t   *trav = NULL; +        xlator_t        *parent = NULL; +        xlator_t        *candidate = NULL; + +        xlator_foreach_depth_first (this, fn, data); +        if (!conf->private) { +                gf_log (this->name, GF_LOG_ERROR, "Couldn't find a local " +                        "brick"); +                return -1; +        } + +        candidate = conf->private; +        trav = candidate->parents; +        while (trav) { + +                parent = trav->xlator; +                if (strcmp (parent->type, "cluster/nufa") == 0) { +                        gf_log (this->name, GF_LOG_INFO, "Found local subvol, " +                                "%s", candidate->name); +                        ret = 0; +                        conf->private = candidate; +                        break; +                } + +                candidate = parent; +                trav = parent->parents; +        } + +        return ret; +} +  int  nufa_init (xlator_t *this)  { -        dht_conf_t    *conf = NULL; -        xlator_list_t *trav = NULL;          data_t        *data = NULL;          char          *local_volname = NULL;          int            ret = -1;          char           my_hostname[256]; -        xlator_t      *local_subvol = NULL; -        char          *brick_host = NULL; -        xlator_t      *kid = NULL; +        gf_boolean_t   addr_match = _gf_false; +        nufa_args_t    args = {0, };          ret = dht_init(this);          if (ret) {                  return ret;          } -        conf = this->private; - -        local_volname = "localhost"; -        ret = gethostname (my_hostname, 256); -        if (ret < 0) { -                gf_log (this->name, GF_LOG_WARNING, -                        "could not find hostname (%s)", -                        strerror (errno)); -        } - -        if (ret == 0) -                local_volname = my_hostname; -        data = dict_get (this->options, "local-volume-name"); -        if (data) { +        if ((data = dict_get (this->options, "local-volume-name"))) {                  local_volname = data->data; -        } -        for (trav = this->children; trav; trav = trav->next) { -                if (strcmp (trav->xlator->name, local_volname) == 0) -                        break; -                if (local_subvol) { -                        continue; -                } -                kid = trav->xlator; -                for (;;) { -                        if (dict_get_str(trav->xlator->options,"remote-host", -                                         &brick_host) == 0) { -                                /* Found it. */ -                                break; -                        } -                        if (!kid->children) { -                                /* Nowhere further to look. */ -                                gf_log (this->name, GF_LOG_ERROR, -                                        "could not get remote-host"); -                                goto err; -                        } -                        if (kid->children->next) { -                                /* Multiple choices, can't/shouldn't decide. */ -                                gf_log (this->name, GF_LOG_ERROR, -                                        "NUFA found fan-out (type %s) volume", -                                        kid->type); -                                goto err; -                        } -                        /* One-to-one xlators are OK, try the next one. */ -                        kid = kid->children->xlator; -                } -                if (same_first_part(my_hostname,'.',brick_host,'.')) { -                        local_subvol = trav->xlator; -                } -        } +        } else { +                addr_match = _gf_true; +                local_volname = "localhost"; +                ret = gethostname (my_hostname, 256); +                if (ret == 0) +                        local_volname = my_hostname; -        if (trav) { -                gf_log (this->name, GF_LOG_INFO, -                        "Using specified subvol %s", local_volname); -                conf->private = trav->xlator; -        } -        else if (local_subvol) { -                gf_log (this->name, GF_LOG_INFO, -                        "Using first local subvol %s", local_subvol->name); -                conf->private = local_subvol; -        } -        else { -                gf_log (this->name, GF_LOG_ERROR, -                        "Could not find specified or local subvol"); -                goto err; +                else +                        gf_log (this->name, GF_LOG_WARNING, +                                "could not find hostname (%s)", +                                strerror (errno));          } +        args.this = this; +        args.volname = local_volname; +        args.addr_match = addr_match; +        ret = nufa_find_local_subvol (this, nufa_find_local_brick, &args); +        if (ret) +                goto err;          return 0;  err:  | 
