diff options
| author | Amar Tumballi <amar@gluster.com> | 2010-08-12 04:49:50 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2010-08-12 03:29:58 -0700 | 
| commit | a9383208a60163f49e87c88a86439acd06f8356c (patch) | |
| tree | fc86250330d11c81fed833cdb7d639be38a860d4 /xlators/protocol | |
| parent | e0347526dd77f7171ae9da72fc92ca99a79dd282 (diff) | |
client changes for 'gluster volume migration' to work
Signed-off-by: Amar Tumballi <amar@gluster.com>
Signed-off-by: Pavan Vilas Sondur <pavan@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 1303 (Cleanup replace-brick state info)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1303
Diffstat (limited to 'xlators/protocol')
| -rw-r--r-- | xlators/protocol/client/src/client.c | 259 | ||||
| -rw-r--r-- | xlators/protocol/client/src/client.h | 4 | 
2 files changed, 230 insertions, 33 deletions
diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index c8bbd467206..c481ae96ad0 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -35,11 +35,10 @@  extern rpc_clnt_prog_t clnt_handshake_prog;  extern rpc_clnt_prog_t clnt_dump_prog; -int -client_handshake (xlator_t *this, struct rpc_clnt *rpc); - -void -client_start_ping (void *data); +int client_handshake (xlator_t *this, struct rpc_clnt *rpc); +void client_start_ping (void *data); +int client_init_rpc (xlator_t *this); +int client_destroy_rpc (xlator_t *this);  int  client_submit_request (xlator_t *this, void *req, call_frame_t *frame, @@ -836,16 +835,145 @@ out:  	return 0;  } +static gf_boolean_t +is_client_rpc_init_command (dict_t *dict, xlator_t *this, +                            char **value) +{ +        gf_boolean_t ret      = _gf_false; +        int          dict_ret = -1; + +        if (strncmp (this->name, "replace-brick", 13)) +                goto out; + +        dict_ret = dict_get_str (dict, CLIENT_CMD_CONNECT, value); +        if (dict_ret) +                goto out; + +        ret = _gf_true; + +out: +        return ret; + +} + +static gf_boolean_t +is_client_rpc_destroy_command (dict_t *dict, xlator_t *this) +{ +        gf_boolean_t ret      = _gf_false; +        int          dict_ret = -1; +        char        *dummy    = NULL; + +        if (strncmp (this->name, "replace-brick", 13)) +                goto out; + +        dict_ret = dict_get_str (dict, CLIENT_CMD_DISCONNECT, &dummy); +        if (dict_ret) +                goto out; + +        ret = _gf_true; + +out: +        return ret; + +} + +static gf_boolean_t +client_set_remote_options (char *value, xlator_t *this) +{ +        clnt_conf_t  *conf          = NULL; +        char         *dup_value     = NULL; +        char         *host          = NULL; +        char         *subvol        = NULL; +        char         *host_dup      = NULL; +        char         *subvol_dup    = NULL; +        char         *tmp           = NULL; +        gf_boolean_t  ret           = _gf_false; + +        conf = this->private; + +        dup_value = gf_strdup (value); +        host = strtok_r (dup_value, ":", &tmp); +        subvol = strtok_r (NULL, ":", &tmp); +        if (!subvol) { +                gf_log (this->name, GF_LOG_WARNING, +                        "proper value not passed as subvolume"); +                goto out; +        } + +        host_dup = gf_strdup (host); +        if (!host_dup) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Out of memory"); +                goto out; +        } + +        ret = dict_set_dynstr (this->options, "remote-host", host_dup); +        if (ret) { +                gf_log (this->name, GF_LOG_WARNING, +                        "failed to set remote-host with %s", host); +                goto out; +        } + +        subvol_dup = gf_strdup (subvol); +        if (!subvol_dup) { +                gf_log (this->name, GF_LOG_ERROR, +                        "Out of memory"); +                goto out; +        } + +        ret = dict_set_dynstr (this->options, "remote-subvolume", subvol_dup); +        if (ret) { +                gf_log (this->name, GF_LOG_WARNING, +                        "failed to set remote-host with %s", host); +                goto out; +        } + +        ret = _gf_true; +out: +        if (dup_value) +                GF_FREE (dup_value); + +        return ret; +}  int32_t  client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,                   int32_t flags)  { -        int          ret  = -1; -        clnt_conf_t *conf = NULL; -        rpc_clnt_procedure_t *proc = NULL; -        clnt_args_t  args = {0,}; +        int                   ret         = -1; +        int                   op_ret      = -1; +        int                   op_errno    = ENOTCONN; +        int                   need_unwind = 0; +        clnt_conf_t          *conf        = NULL; +        rpc_clnt_procedure_t *proc        = NULL; +        clnt_args_t           args        = {0,}; +        char                 *value       = NULL; + + +        if (is_client_rpc_init_command (dict, this, &value) == _gf_true) { +                GF_ASSERT (value); +                ret = client_set_remote_options (value, this); +                if (ret) +                        ret = client_init_rpc (this); + +                if (!ret) { +                        op_ret      = 0; +                        op_errno    = 0; +                } +                need_unwind = 1; +                goto out; +        } + +        if (is_client_rpc_destroy_command (dict, this) == _gf_true) { +                ret = client_destroy_rpc (this); +                if (ret) { +                        op_ret      = 0; +                        op_errno    = 0; +                } +                need_unwind = 1; +                goto out; +        }          conf = this->private;          if (!conf->fops) @@ -856,11 +984,17 @@ client_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,          args.flags = flags;          proc = &conf->fops->proctable[GF_FOP_SETXATTR]; -        if (proc->fn) +        if (proc->fn) {                  ret = proc->fn (frame, this, &args); +                if (ret) { +                        op_ret = -1; +                        op_errno = ENOTCONN; +                        need_unwind = 1; +                } +        }  out: -        if (ret) -                STACK_UNWIND_STRICT (setxattr, frame, -1, ENOTCONN); +        if (need_unwind) +                STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno);  	return 0;  } @@ -1476,14 +1610,6 @@ build_client_config (xlator_t *this, clnt_conf_t *conf)  {          int ret = 0; -        ret = dict_get_str (this->options, "remote-subvolume", -                            &conf->opt.remote_subvolume); -        if (ret) { -                gf_log (this->name, GF_LOG_ERROR, -                        "option 'remote-subvolume' not given"); -                goto out; -        } -          ret = dict_get_int32 (this->options, "frame-timeout",                                &conf->rpc_conf.rpc_timeout);          if (ret >= 0) { @@ -1517,6 +1643,16 @@ build_client_config (xlator_t *this, clnt_conf_t *conf)                  conf->opt.ping_timeout = GF_UNIVERSAL_ANSWER;          } +        ret = dict_get_str (this->options, "remote-subvolume", +                            &conf->opt.remote_subvolume); +        if (ret) { +                /* This is valid only if 'cluster/pump' is the parent */ +                gf_log (this->name, GF_LOG_NORMAL, +                        "option 'remote-subvolume' not given"); +                ret = 1; +                goto out; +        } +          ret = 0;  out:          return ret; @@ -1542,6 +1678,63 @@ mem_acct_init (xlator_t *this)          return ret;  } +int +client_destroy_rpc (xlator_t *this) +{ +        int          ret  = -1; +        clnt_conf_t *conf = NULL; + +        conf = this->private; + +        if (conf->rpc) { +                rpc_clnt_destroy (conf->rpc); +                ret = 0; +                gf_log (this->name, GF_LOG_DEBUG, +                        "Client rpc conn destroyed"); +                goto out; +        } + +        gf_log (this->name, GF_LOG_DEBUG, +                "RPC destory called on already destroyed " +                "connection"); + +out: +        return ret; +} + +int +client_init_rpc (xlator_t *this) +{ +        int          ret  = -1; +        clnt_conf_t *conf = NULL; + +        conf = this->private; + +        if (conf->rpc) { +                gf_log (this->name, GF_LOG_DEBUG, +                        "client rpc already init'ed"); +                ret = -1; +                goto out; +        } + +        conf->rpc = rpc_clnt_init (&conf->rpc_conf, this->options, this->ctx, +                                   this->name); +        if (!conf->rpc) +                goto out; + +        ret = rpc_clnt_register_notify (conf->rpc, client_rpc_notify, this); +        if (ret) +                goto out; + +        conf->handshake = &clnt_handshake_prog; +        conf->dump      = &clnt_dump_prog; + +        ret = 0; + +        gf_log (this->name, GF_LOG_DEBUG, "client init successful"); +out: +        return ret; +}  int  init (xlator_t *this) @@ -1569,24 +1762,24 @@ init (xlator_t *this)          pthread_mutex_init (&conf->lock, NULL);          INIT_LIST_HEAD (&conf->saved_fds); +        this->private = conf; + +        /* If it returns -1, then its a failure, if it returns +1 we need +           have to understand that 'this' is subvolume of a xlator which, +           will set the remote host and remote subvolume in a setxattr +           call. +        */ +          ret = build_client_config (this, conf); -        if (ret) +        if (ret == -1)                  goto out; -        conf->rpc = rpc_clnt_init (&conf->rpc_conf, this->options, this->ctx, -                                   this->name); -        if (!conf->rpc) -                goto out; -        conf->rpc->xid = 42; /* It should be enough random everytime :O */ -        ret = rpc_clnt_register_notify (conf->rpc, client_rpc_notify, this); -        if (ret) +        if (ret) { +                ret = 0;                  goto out; +        } -        conf->handshake = &clnt_handshake_prog; -        conf->dump      = &clnt_dump_prog; -        this->private = conf; - -        ret = 0; +        ret = client_init_rpc (this);  out:          if (ret)                  this->fini (this); diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h index 234df4e5f59..473ae2a4976 100644 --- a/xlators/protocol/client/src/client.h +++ b/xlators/protocol/client/src/client.h @@ -30,6 +30,10 @@  #include "protocol-common.h"  #include "glusterfs3-xdr.h" +/* FIXME: Needs to be defined in a common file */ +#define CLIENT_CMD_CONNECT "trusted.glusterfs.client-connect" +#define CLIENT_CMD_DISCONNECT "trusted.glusterfs.client-disconnect" +  struct clnt_options {          char *remote_subvolume;          int   ping_timeout;  | 
