diff options
Diffstat (limited to 'xlators/protocol/server/src')
| -rw-r--r-- | xlators/protocol/server/src/server-handshake.c | 78 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 48 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-helpers.h | 6 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-mem-types.h | 1 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server.c | 96 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server.h | 5 | 
6 files changed, 213 insertions, 21 deletions
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c index 2c8cf059be3..374f5a49ae7 100644 --- a/xlators/protocol/server/src/server-handshake.c +++ b/xlators/protocol/server/src/server-handshake.c @@ -354,6 +354,7 @@ server_setvolume (rpcsvc_request_t *req)          int32_t              op_errno      = EINVAL;          int32_t              fop_version   = 0;          int32_t              mgmt_version  = 0; +        uint32_t             lk_version    = 0;          char                *buf           = NULL;          params = dict_new (); @@ -408,8 +409,33 @@ server_setvolume (rpcsvc_request_t *req)                  goto fail;          } +        /*lk_verion :: [1..2^31-1]*/ +        ret = dict_get_uint32 (params, "clnt-lk-version", &lk_version); +        if (ret < 0) { +                ret = dict_set_str (reply, "ERROR", +                                    "lock state verison not supplied"); +                if (ret < 0) +                        gf_log (this->name, GF_LOG_DEBUG, +                                "failed to set error msg"); + +                op_ret = -1; +                op_errno = EINVAL; +                goto fail; +        }          conn = server_connection_get (this, process_uuid); +        if (!conn) { +                op_ret = -1; +                op_errno = ENOMEM; +                goto fail; +        } + +        server_cancel_conn_timer (this, conn); +        if (conn->lk_version != 0 && +            conn->lk_version != lk_version) { +                (void) server_connection_cleanup (this, conn); +        } +          if (req->trans->xl_private != conn)                  req->trans->xl_private = conn; @@ -595,6 +621,12 @@ server_setvolume (rpcsvc_request_t *req)                  gf_log (this->name, GF_LOG_DEBUG,                          "failed to set 'process-uuid'"); +        ret = dict_set_uint32 (reply, "clnt-lk-version", +                               conn->lk_version); +        if (ret) +                gf_log (this->name, GF_LOG_WARNING, +                        "failed to set 'clnt-lk-version'"); +          ret = dict_set_uint64 (reply, "transport-ptr",                                 ((uint64_t) (long) req->trans));          if (ret) @@ -663,12 +695,50 @@ server_ping (rpcsvc_request_t *req)          return 0;  } +int +server_set_lk_version (rpcsvc_request_t *req) +{ +        int                     op_ret          = -1; +        int                     op_errno        = EINVAL; +        gf_set_lk_ver_req       args            = {0, }; +        gf_set_lk_ver_rsp       rsp             = {0,}; +        server_connection_t     *conn           = NULL; +        xlator_t                *this           = NULL; + +        this = req->svc->mydata; +        //TODO: Decide on an appropriate errno for the error-path +        //below +        if (!this) +                goto fail; + +        if (!xdr_to_generic (req->msg[0], &args, +                             (xdrproc_t)xdr_gf_set_lk_ver_req)) { +                //failed to decode msg; +                req->rpc_err = GARBAGE_ARGS; +                goto fail; +        } + +        conn = server_connection_get (this, args.uid); +        conn->lk_version = args.lk_ver; +        server_connection_put (this, conn); + +        rsp.lk_ver   = args.lk_ver; + +        op_ret = 0; +fail: +        rsp.op_ret   = op_ret; +        rsp.op_errno = op_errno; +        server_submit_reply (NULL, req, &rsp, NULL, 0, NULL, +                             (xdrproc_t)xdr_gf_set_lk_ver_rsp); +        return 0; +}  rpcsvc_actor_t gluster_handshake_actors[] = { -        [GF_HNDSK_NULL]      = {"NULL",      GF_HNDSK_NULL,      server_null, NULL, NULL, 0}, -        [GF_HNDSK_SETVOLUME] = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, NULL, NULL, 0}, -        [GF_HNDSK_GETSPEC]   = {"GETSPEC",   GF_HNDSK_GETSPEC,   server_getspec, NULL, NULL, 0}, -        [GF_HNDSK_PING]      = {"PING",      GF_HNDSK_PING,      server_ping, NULL, NULL, 0}, +        [GF_HNDSK_NULL]       = {"NULL",      GF_HNDSK_NULL,      server_null, NULL, NULL, 0}, +        [GF_HNDSK_SETVOLUME]  = {"SETVOLUME", GF_HNDSK_SETVOLUME, server_setvolume, NULL, NULL, 0}, +        [GF_HNDSK_GETSPEC]    = {"GETSPEC",   GF_HNDSK_GETSPEC,   server_getspec, NULL, NULL, 0}, +        [GF_HNDSK_PING]       = {"PING",      GF_HNDSK_PING,      server_ping, NULL, NULL, 0}, +        [GF_HNDSK_SET_LK_VER] = {"SET_LK_VER", GF_HNDSK_SET_LK_VER, server_set_lk_version, NULL, NULL },  }; diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index 4980424d350..9de1082dc94 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -774,6 +774,7 @@ server_connection_t *  server_connection_get (xlator_t *this, const char *id)  {          server_connection_t *conn = NULL; +        server_connection_t *trav = NULL;          server_conf_t       *conf = NULL;          GF_VALIDATE_OR_GOTO ("server", this, out); @@ -783,20 +784,29 @@ server_connection_get (xlator_t *this, const char *id)          pthread_mutex_lock (&conf->mutex);          { +                list_for_each_entry (trav, &conf->conns, list) { +                        if (!strncmp (trav->id, id, strlen (id))) { +                                conn = trav; +                                conn->ref++; +                                goto unlock; +                        } +                } +                  conn = (void *) GF_CALLOC (1, sizeof (*conn),                                             gf_server_mt_conn_t);                  if (!conn)                          goto unlock;                  conn->id = gf_strdup (id); +                /*'0' denotes uninitialised lock state*/ +                conn->lk_version = 0; +                conn->ref++;                  conn->fdtable = gf_fd_fdtable_alloc ();                  conn->ltable  = gf_lock_table_new ();                  conn->this    = this;                  pthread_mutex_init (&conn->lock, NULL); -                  list_add (&conn->list, &conf->conns); -                conn->ref++;          }  unlock:          pthread_mutex_unlock (&conf->mutex); @@ -982,6 +992,17 @@ out:          return ret;  } +void +put_server_conn_state (xlator_t *this, rpc_transport_t *xprt) +{ +        GF_VALIDATE_OR_GOTO ("server", this, out); +        GF_VALIDATE_OR_GOTO ("server", xprt, out); + +        xprt->xl_private = NULL; +out: +        return; +} +  server_connection_t *  get_server_conn_state (xlator_t *this, rpc_transport_t *xprt)  { @@ -1497,3 +1518,26 @@ gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict)          return 0;  } + +void +server_cancel_conn_timer (xlator_t *this, server_connection_t *conn) +{ +        if (!this || !conn) { +                gf_log (THIS->name, GF_LOG_ERROR, "Invalid arguments to " +                        "cancel connection timer"); +                return; +        } + +        pthread_mutex_lock (&conn->lock); +        { +                if (!conn->timer) +                        goto unlock; + +                gf_timer_call_cancel (this->ctx, conn->timer); +                conn->timer = NULL; +        } +unlock: +        pthread_mutex_unlock (&conn->lock); + +        return; +} diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h index 844c98c27bf..99ba7e546b4 100644 --- a/xlators/protocol/server/src/server-helpers.h +++ b/xlators/protocol/server/src/server-helpers.h @@ -68,6 +68,12 @@ server_print_request (call_frame_t *frame);  call_frame_t *  get_frame_from_request (rpcsvc_request_t *req); +void +server_cancel_conn_timer (xlator_t *this, server_connection_t *conn); + +void +put_server_conn_state (xlator_t *this, rpc_transport_t *xprt); +  server_connection_t *  get_server_conn_state (xlator_t *this, rpc_transport_t *xptr); diff --git a/xlators/protocol/server/src/server-mem-types.h b/xlators/protocol/server/src/server-mem-types.h index 88bae8cb45d..5438ed6db1a 100644 --- a/xlators/protocol/server/src/server-mem-types.h +++ b/xlators/protocol/server/src/server-mem-types.h @@ -33,6 +33,7 @@ enum gf_server_mem_types_ {          gf_server_mt_dirent_rsp_t,          gf_server_mt_rsp_buf_t,          gf_server_mt_volfile_ctx_t, +        gf_server_mt_timer_data_t,          gf_server_mt_end,  };  #endif /* __SERVER_MEM_TYPES_H__ */ diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index b0697bb7b9d..b45b77baae0 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -36,6 +36,26 @@  #include "authenticate.h"  #include "rpcsvc.h" +void +grace_time_handler (void *data) +{ +        server_connection_t     *conn = NULL; +        xlator_t                *this = NULL; + +        conn = data; +        this = conn->this; + +        GF_VALIDATE_OR_GOTO (THIS->name, conn, out); +        GF_VALIDATE_OR_GOTO (THIS->name, this, out); + +        gf_log (this->name, GF_LOG_INFO, "grace timer expired"); + +        server_cancel_conn_timer (this, conn); +        server_connection_put (this, conn); +out: +        return; +} +  struct iobuf *  gfs_serialize_reply (rpcsvc_request_t *req, void *arg, struct iovec *outmsg,                       xdrproc_t xdrproc) @@ -554,11 +574,10 @@ int  server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,                     void *data)  { -        xlator_t            *this = NULL; -        rpc_transport_t     *xprt = NULL; -        server_connection_t *conn = NULL; -        server_conf_t       *conf = NULL; - +        xlator_t            *this       = NULL; +        rpc_transport_t     *xprt       = NULL; +        server_connection_t *conn       = NULL; +        server_conf_t       *conf       = NULL;          if (!xl || !data) {                  gf_log_callingfn ("server", GF_LOG_WARNING, @@ -589,20 +608,37 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,          }          case RPCSVC_EVENT_DISCONNECT:                  conn = get_server_conn_state (this, xprt); -                if (conn) -                        server_connection_cleanup (this, conn); - -                gf_log (this->name, GF_LOG_INFO, -                        "disconnected connection from %s", -                        xprt->peerinfo.identifier); +                if (!conn) +                        break; +                put_server_conn_state (this, xprt); +                gf_log (this->name, GF_LOG_INFO, "disconnecting connection" +                        "from %s", xprt->peerinfo.identifier);                  list_del (&xprt->list); +                pthread_mutex_lock (&conn->lock); +                { +                        if (conn->timer) +                                goto unlock; + +                        gf_log (this->name, GF_LOG_INFO, "starting a grace " +                                "timer for %s", xprt->name); + +                        conn->timer = gf_timer_call_after (this->ctx, +                                                           conf->grace_tv, +                                                           grace_time_handler, +                                                           conn); +                } +        unlock: +                pthread_mutex_unlock (&conn->lock); +                  break;          case RPCSVC_EVENT_TRANSPORT_DESTROY: -                conn = get_server_conn_state (this, xprt); -                if (conn) -                        server_connection_put (this, conn); +                /*- conn obj has been disassociated from xprt on first +                 *  disconnect. +                 *  conn cleanup and destruction is handed over to +                 *  grace_time_handler or the subsequent handler that 'owns' +                 *  the conn. Nothing left to be done here. */                  break;          default:                  break; @@ -668,6 +704,30 @@ _copy_auth_opt (dict_t *unused,  int +server_init_grace_timer (xlator_t *this, dict_t *options, +                         server_conf_t *conf) +{ +        int32_t   ret            = -1; +        int32_t   grace_timeout  = -1; + +        GF_VALIDATE_OR_GOTO ("server", this, out); +        GF_VALIDATE_OR_GOTO (this->name, options, out); +        GF_VALIDATE_OR_GOTO (this->name, conf, out); + +        ret = dict_get_int32 (options, "grace-timeout", &grace_timeout); +        if (!ret) +                conf->grace_tv.tv_sec = grace_timeout; +        else +                conf->grace_tv.tv_sec = 10; + +        conf->grace_tv.tv_usec  = 0; + +        ret = 0; +out: +        return ret; +} + +int  reconfigure (xlator_t *this, dict_t *options)  { @@ -761,6 +821,7 @@ reconfigure (xlator_t *this, dict_t *options)                                          "Reconfigure not found for transport" );                  }          } +        ret = server_init_grace_timer (this, options, conf);  out:          gf_log ("", GF_LOG_DEBUG, "returning %d", ret); @@ -797,6 +858,10 @@ init (xlator_t *this)          INIT_LIST_HEAD (&conf->xprt_list);          pthread_mutex_init (&conf->mutex, NULL); +        ret = server_init_grace_timer (this, this->options, conf); +        if (ret) +                goto out; +          ret = server_build_config (this, conf);          if (ret)                  goto out; @@ -1032,5 +1097,8 @@ struct volume_options options[] = {            .type          = GF_OPTION_TYPE_PATH,            .default_value = "/tmp"          }, +        {.key  = {"grace-timeout"}, +         .type = GF_OPTION_TYPE_INT, +        },          { .key   = {NULL} },  }; diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h index 92785c5a9d6..091a02ccba2 100644 --- a/xlators/protocol/server/src/server.h +++ b/xlators/protocol/server/src/server.h @@ -28,6 +28,7 @@  #include "protocol-common.h"  #include "server-mem-types.h"  #include "glusterfs3.h" +#include "timer.h"  #define DEFAULT_BLOCK_SIZE         4194304   /* 4MB */  #define DEFAULT_VOLUME_FILE_PATH   CONFDIR "/glusterfs.vol" @@ -60,8 +61,10 @@ struct _server_connection {          pthread_mutex_t     lock;          fdtable_t          *fdtable;          struct _lock_table *ltable; +        gf_timer_t         *timer;          xlator_t           *bound_xl;          xlator_t           *this; +        uint32_t           lk_version;  };  typedef struct _server_connection server_connection_t; @@ -92,7 +95,7 @@ struct server_conf {          gf_boolean_t            trace;          char                   *conf_dir;          struct _volfile_ctx    *volfile; - +        struct timeval          grace_tv;          dict_t                 *auth_modules;          pthread_mutex_t         mutex;          struct list_head        conns;  | 
