diff options
Diffstat (limited to 'api/src/glfs-mgmt.c')
| -rw-r--r-- | api/src/glfs-mgmt.c | 219 |
1 files changed, 55 insertions, 164 deletions
diff --git a/api/src/glfs-mgmt.c b/api/src/glfs-mgmt.c index 2ead93863..6843e9cb3 100644 --- a/api/src/glfs-mgmt.c +++ b/api/src/glfs-mgmt.c @@ -114,7 +114,7 @@ mgmt_cbk_event (struct rpc_clnt *rpc, void *mydata, void *data) } -rpcclnt_cb_actor_t gluster_cbk_actors[] = { +rpcclnt_cb_actor_t mgmt_cbk_actors[] = { [GF_CBK_FETCHSPEC] = {"FETCHSPEC", GF_CBK_FETCHSPEC, mgmt_cbk_spec }, [GF_CBK_EVENT_NOTIFY] = {"EVENTNOTIFY", GF_CBK_EVENT_NOTIFY, mgmt_cbk_event}, @@ -125,7 +125,7 @@ struct rpcclnt_cb_program mgmt_cbk_prog = { .progname = "GlusterFS Callback", .prognum = GLUSTER_CBK_PROGRAM, .progver = GLUSTER_CBK_VERSION, - .actors = gluster_cbk_actors, + .actors = mgmt_cbk_actors, .numactors = GF_CBK_MAXVALUE, }; @@ -203,162 +203,6 @@ out: static int -xlator_equal_rec (xlator_t *xl1, xlator_t *xl2) -{ - xlator_list_t *trav1 = NULL; - xlator_list_t *trav2 = NULL; - int ret = 0; - - if (xl1 == NULL || xl2 == NULL) { - gf_log ("xlator", GF_LOG_DEBUG, "invalid argument"); - return -1; - } - - trav1 = xl1->children; - trav2 = xl2->children; - - while (trav1 && trav2) { - ret = xlator_equal_rec (trav1->xlator, trav2->xlator); - if (ret) { - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "xlators children not equal"); - goto out; - } - - trav1 = trav1->next; - trav2 = trav2->next; - } - - if (trav1 || trav2) { - ret = -1; - goto out; - } - - if (strcmp (xl1->name, xl2->name)) { - ret = -1; - goto out; - } -out : - return ret; -} - - -static gf_boolean_t -is_graph_topology_equal (glusterfs_graph_t *graph1, - glusterfs_graph_t *graph2) -{ - xlator_t *trav1 = NULL; - xlator_t *trav2 = NULL; - gf_boolean_t ret = _gf_true; - - trav1 = graph1->first; - trav2 = graph2->first; - - ret = xlator_equal_rec (trav1, trav2); - - if (ret) { - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "graphs are not equal"); - ret = _gf_false; - goto out; - } - - ret = _gf_true; - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "graphs are equal"); - -out: - return ret; -} - - -/* Function has 3types of return value 0, -ve , 1 - * return 0 =======> reconfiguration of options has succeeded - * return 1 =======> the graph has to be reconstructed and all the xlators should be inited - * return -1(or -ve) =======> Some Internal Error occurred during the operation - */ -static int -glusterfs_volfile_reconfigure (struct glfs *fs, FILE *newvolfile_fp) -{ - glusterfs_graph_t *oldvolfile_graph = NULL; - glusterfs_graph_t *newvolfile_graph = NULL; - FILE *oldvolfile_fp = NULL; - glusterfs_ctx_t *ctx = NULL; - - int ret = -1; - - oldvolfile_fp = tmpfile (); - if (!oldvolfile_fp) - goto out; - - if (!fs->oldvollen) { - ret = 1; // Has to call INIT for the whole graph - goto out; - } - fwrite (fs->oldvolfile, fs->oldvollen, 1, oldvolfile_fp); - fflush (oldvolfile_fp); - if (ferror (oldvolfile_fp)) { - goto out; - } - - oldvolfile_graph = glusterfs_graph_construct (oldvolfile_fp); - if (!oldvolfile_graph) { - goto out; - } - - newvolfile_graph = glusterfs_graph_construct (newvolfile_fp); - if (!newvolfile_graph) { - goto out; - } - - if (!is_graph_topology_equal (oldvolfile_graph, - newvolfile_graph)) { - - ret = 1; - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "Graph topology not equal(should call INIT)"); - goto out; - } - - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "Only options have changed in the new " - "graph"); - - ctx = fs->ctx; - - if (!ctx) { - gf_log ("glfs-mgmt", GF_LOG_ERROR, - "glusterfs_ctx_get() returned NULL"); - goto out; - } - - oldvolfile_graph = ctx->active; - - if (!oldvolfile_graph) { - gf_log ("glfs-mgmt", GF_LOG_ERROR, - "glusterfs_ctx->active is NULL"); - goto out; - } - - /* */ - ret = glusterfs_graph_reconfigure (oldvolfile_graph, - newvolfile_graph); - if (ret) { - gf_log ("glfs-mgmt", GF_LOG_DEBUG, - "Could not reconfigure new options in old graph"); - goto out; - } - - ret = 0; -out: - if (oldvolfile_fp) - fclose (oldvolfile_fp); - - return ret; -} - - -static int glusterfs_oldvolfile_update (struct glfs *fs, char *volfile, ssize_t size) { int ret = -1; @@ -416,6 +260,7 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, gf_log (frame->this->name, GF_LOG_ERROR, "failed to get the 'volume file' from server"); ret = -1; + errno = rsp.op_errno; goto out; } @@ -450,7 +295,8 @@ mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, * return -1(or -ve) =======> Some Internal Error occurred during the operation */ - ret = glusterfs_volfile_reconfigure (fs, tmpfp); + ret = glusterfs_volfile_reconfigure (fs->oldvollen, tmpfp, fs->ctx, + fs->oldvolfile); if (ret == 0) { gf_log ("glusterfsd-mgmt", GF_LOG_DEBUG, "No need to re-load volfile, reconfigure done"); @@ -477,6 +323,14 @@ out: if (rsp.spec) free (rsp.spec); + // Stop if server is running at an unsupported op-version + if (ENOTSUP == ret) { + gf_log ("mgmt", GF_LOG_ERROR, "Server is operating at an " + "op-version which is not supported"); + errno = ENOTSUP; + glfs_init_done (fs, -1); + } + if (ret && ctx && !ctx->active) { /* Do it only for the first time */ /* Failed to get the volume file, something wrong, @@ -484,8 +338,11 @@ out: gf_log ("glfs-mgmt", GF_LOG_ERROR, "failed to fetch volume file (key:%s)", ctx->cmd_args.volfile_id); - if (!need_retry) + if (!need_retry) { + if (!errno) + errno = EINVAL; glfs_init_done (fs, -1); + } } if (tmpfp) @@ -503,6 +360,7 @@ glfs_volfile_fetch (struct glfs *fs) int ret = 0; call_frame_t *frame = NULL; glusterfs_ctx_t *ctx = NULL; + dict_t *dict = NULL; ctx = fs->ctx; cmd_args = &ctx->cmd_args; @@ -512,10 +370,41 @@ glfs_volfile_fetch (struct glfs *fs) req.key = cmd_args->volfile_id; req.flags = 0; + dict = dict_new (); + if (!dict) { + ret = -1; + goto out; + } + + // Set the supported min and max op-versions, so glusterd can make a + // decision + ret = dict_set_int32 (dict, "min-op-version", GD_OP_VERSION_MIN); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Failed to set min-op-version" + " in request dict"); + goto out; + } + + ret = dict_set_int32 (dict, "max-op-version", GD_OP_VERSION_MAX); + if (ret) { + gf_log (THIS->name, GF_LOG_ERROR, "Failed to set max-op-version" + " in request dict"); + goto out; + } + + ret = dict_allocate_and_serialize (dict, &req.xdata.xdata_val, + &req.xdata.xdata_len); + if (ret < 0) { + gf_log (THIS->name, GF_LOG_ERROR, + "Failed to serialize dictionary"); + goto out; + } + ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog, GF_HNDSK_GETSPEC, mgmt_getspec_cbk, (xdrproc_t)xdr_gf_getspec_req); - return ret; +out: + return ret; } @@ -544,9 +433,10 @@ mgmt_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, gf_log ("glfs-mgmt", GF_LOG_INFO, "%d connect attempts left", cmd_args->max_connect_attempts); - if (0 >= cmd_args->max_connect_attempts) + if (0 >= cmd_args->max_connect_attempts) { + errno = ENOTCONN; glfs_init_done (fs, -1); - break; + } } break; case RPC_CLNT_CONNECT: @@ -555,10 +445,11 @@ mgmt_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, ret = glfs_volfile_fetch (fs); if (ret && ctx && (ctx->active == NULL)) { /* Do it only for the first time */ - /* Exit the process.. there is some wrong options */ + /* Exit the process.. there are some wrong options */ gf_log ("glfs-mgmt", GF_LOG_ERROR, "failed to fetch volume file (key:%s)", ctx->cmd_args.volfile_id); + errno = EINVAL; glfs_init_done (fs, -1); } |
