diff options
Diffstat (limited to 'glusterfsd/src/fetch-spec.c')
-rw-r--r-- | glusterfsd/src/fetch-spec.c | 474 |
1 files changed, 235 insertions, 239 deletions
diff --git a/glusterfsd/src/fetch-spec.c b/glusterfsd/src/fetch-spec.c index f8dcb75844f..ac2961062a8 100644 --- a/glusterfsd/src/fetch-spec.c +++ b/glusterfsd/src/fetch-spec.c @@ -33,271 +33,267 @@ #include "event.h" #include "defaults.h" +#include "rpc-clnt.h" +#include "protocol-common.h" +#include "glusterfs3.h" -#if 0 -int glusterfs_graph_parent_up (xlator_t *graph); +typedef ssize_t (*mgmt_serialize_t) (struct iovec outmsg, void *args); -static int -fetch_cbk (call_frame_t *frame, - void *cookie, - xlator_t *this, - int32_t op_ret, - int32_t op_errno, - char *spec_data) -{ - FILE *spec_fp = NULL; - - spec_fp = frame->local; - - if (op_ret >= 0) { - fwrite (spec_data, strlen (spec_data), 1, spec_fp); - fflush (spec_fp); - fclose (spec_fp); - } - else { - gf_log (frame->this->name, GF_LOG_ERROR, - "GETSPEC from server returned -1 (%s)", - strerror (op_errno)); - } - - frame->local = NULL; - STACK_DESTROY (frame->root); - - /* exit the child process */ - exit (op_ret); -} +char *clnt_handshake_procs[GF_HNDSK_MAXVALUE] = { + [GF_HNDSK_NULL] = "NULL", + [GF_HNDSK_SETVOLUME] = "SETVOLUME", + [GF_HNDSK_GETSPEC] = "GETSPEC", + [GF_HNDSK_PING] = "PING", +}; +rpc_clnt_prog_t clnt_handshake_prog = { + .progname = "GlusterFS Handshake", + .prognum = GLUSTER_HNDSK_PROGRAM, + .progver = GLUSTER_HNDSK_VERSION, + .procnames = clnt_handshake_procs, +}; -static int -fetch_notify (xlator_t *this_xl, int event, void *data, ...) + +int glusterfs_volfile_fetch (glusterfs_ctx_t *ctx); +int glusterfs_process_volfp (glusterfs_ctx_t *ctx, FILE *fp); + +int +mgmt_submit_request (void *req, call_frame_t *frame, + glusterfs_ctx_t *ctx, + rpc_clnt_prog_t *prog, int procnum, + mgmt_serialize_t sfunc, fop_cbk_fn_t cbkfn) { - int ret = 0; - call_frame_t *frame = NULL; - static int failed_connects = 0; - - switch (event) - { - case GF_EVENT_CHILD_UP: - frame = create_frame (this_xl, this_xl->ctx->pool); - frame->local = this_xl->private; - - STACK_WIND (frame, fetch_cbk, - this_xl->children->xlator, - this_xl->children->xlator->fops->getspec, - this_xl->ctx->cmd_args.volfile_id, - 0); - break; - case GF_EVENT_CHILD_DOWN: - failed_connects++; - if (failed_connects - >= this_xl->ctx->cmd_args.max_connect_attempts) { - exit (1); + int ret = -1; + int count = 0; + struct iovec iov = {0, }; + struct iobuf *iobuf = NULL; + struct iobref *iobref = NULL; + + iobref = iobref_new (); + if (!iobref) { + goto out; + } + + iobuf = iobuf_get (ctx->iobuf_pool); + if (!iobuf) { + goto out; + }; + + iobref_add (iobref, iobuf); + + iov.iov_base = iobuf->ptr; + iov.iov_len = 128 * GF_UNIT_KB; + + + /* Create the xdr payload */ + if (req && sfunc) { + ret = sfunc (iov, req); + if (ret == -1) { + goto out; } - break; - default: - ret = default_notify (this_xl, event, data); - break; - } - - return ret; -} + iov.iov_len = ret; + count = 1; + } + /* Send the msg */ + ret = rpc_clnt_submit (ctx->mgmt, prog, procnum, cbkfn, + &iov, count, + NULL, 0, iobref, frame); -static int -fetch_init (xlator_t *xl) -{ - return 0; +out: + if (iobref) + iobref_unref (iobref); + + return ret; } -static xlator_t * -get_shrub (glusterfs_ctx_t *ctx, - const char *remote_host, - const char *transport, - uint32_t remote_port) + +/* XXX: move these into @ctx */ +static char oldvolfile[131072]; +static int oldvollen = 0; +static void *timer; + +int +mgmt_getspec_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) { - volume_opt_list_t *vol_opt = NULL; - xlator_t *trav = NULL; - int ret = 0; - xlator_t *top = NULL; - xlator_t *trans = NULL; - xlator_list_t *parent = NULL, *tmp = NULL; - - top = CALLOC (1, sizeof (*top)); - ERR_ABORT (top); - trans = CALLOC (1, sizeof (*trans)); - ERR_ABORT (trans); - - INIT_LIST_HEAD (&top->volume_options); - INIT_LIST_HEAD (&trans->volume_options); - - top->name = "top"; - top->ctx = ctx; - top->next = trans; - top->init = fetch_init; - top->notify = fetch_notify; - top->children = (void *) CALLOC (1, sizeof (*top->children)); - ERR_ABORT (top->children); - top->children->xlator = trans; - - trans->name = "trans"; - trans->ctx = ctx; - trans->prev = top; - trans->init = fetch_init; - trans->notify = default_notify; - trans->options = get_new_dict (); - - parent = CALLOC (1, sizeof(*parent)); - parent->xlator = top; - if (trans->parents == NULL) - trans->parents = parent; - else { - tmp = trans->parents; - while (tmp->next) - tmp = tmp->next; - tmp->next = parent; - } - - /* TODO: log on failure to set dict */ - if (remote_host) { - ret = dict_set (trans->options, "remote-host", - str_to_data ((char *)remote_host)); + gf_getspec_rsp rsp = {0,}; + call_frame_t *frame = NULL; + glusterfs_ctx_t *ctx = NULL; + int ret = 0; + ssize_t size = 0; + FILE *tmpfp = NULL; + struct timeval tv = {0, }; + + frame = myframe; + ctx = frame->this->ctx; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; } - if (remote_port) - ret = dict_set_uint32 (trans->options, "remote-port", - remote_port); - - /* 'option remote-subvolume <x>' is needed here even though - * its not used - */ - ret = dict_set_static_ptr (trans->options, "remote-subvolume", - "brick"); - ret = dict_set_static_ptr (trans->options, "disable-handshake", "on"); - ret = dict_set_static_ptr (trans->options, "non-blocking-io", "off"); - - if (transport) { - char *transport_type = CALLOC (1, strlen (transport) + 10); - ERR_ABORT (transport_type); - strcpy(transport_type, transport); - - if (strchr (transport_type, ':')) - *(strchr (transport_type, ':')) = '\0'; - - ret = dict_set_dynstr (trans->options, "transport-type", - transport_type); - } - - xlator_set_type (trans, "protocol/client"); - - trav = top; - while (trav) { - /* Get the first volume_option */ - if (!list_empty (&trav->volume_options)) { - list_for_each_entry (vol_opt, - &trav->volume_options, list) - break; - if ((ret = - validate_xlator_volume_options (trav, - vol_opt->given_opt)) < 0) { - gf_log (trav->name, GF_LOG_ERROR, - "validating translator failed"); - return NULL; - } - } - trav = trav->next; - } + ret = xdr_to_getspec_rsp (*iov, &rsp); + if (ret < 0) { + gf_log (frame->this->name, GF_LOG_ERROR, "error"); + rsp.op_ret = -1; + rsp.op_errno = EINVAL; + goto out; + } + + if (-1 == rsp.op_ret) { + gf_log (frame->this->name, GF_LOG_ERROR, + "failed to get the 'volume file' from server"); + goto out; + } + + size = rsp.op_ret; + + if (size == oldvollen && (memcmp (oldvolfile, rsp.spec, size) == 0)) + goto out; + + tmpfp = tmpfile (); + if (!tmpfp) + goto out; + + fwrite (rsp.spec, size, 1, tmpfp); + fflush (tmpfp); + + + ret = glusterfs_process_volfp (ctx, tmpfp); + if (ret) + goto out; + + oldvollen = size; + memcpy (oldvolfile, rsp.spec, size); + +out: + tv.tv_sec = 1; + timer = gf_timer_call_after (ctx, tv, + (gf_timer_cbk_t) glusterfs_volfile_fetch, + ctx); - if (xlator_tree_init (top) != 0) - return NULL; + STACK_DESTROY (frame->root); - glusterfs_graph_parent_up (top); - - return top; + if (rsp.spec) + free (rsp.spec); + + return 0; } -static int -_fetch (glusterfs_ctx_t *ctx, - FILE *spec_fp, - const char *remote_host, - const char *transport, - uint32_t remote_port) +int +glusterfs_volfile_fetch (glusterfs_ctx_t *ctx) { - xlator_t *this = NULL; - - this = get_shrub (ctx, remote_host, transport, remote_port); - if (this == NULL) - return -1; - - this->private = spec_fp; - - event_dispatch (ctx->event_pool); - - return 0; + cmd_args_t *cmd_args = NULL; + gf_getspec_req req = {0, }; + int ret = 0; + call_frame_t *frame = NULL; + + + { + if (timer) + gf_timer_call_cancel (ctx, timer); + timer = NULL; + } + + cmd_args = &ctx->cmd_args; + + frame = create_frame (THIS, ctx->pool); + + req.key = cmd_args->volfile_id; + req.flags = 0; + + ret = mgmt_submit_request (&req, frame, ctx, &clnt_handshake_prog, + GF_HNDSK_GETSPEC, xdr_from_getspec_req, + mgmt_getspec_cbk); + return ret; } -static int -_fork_and_fetch (glusterfs_ctx_t *ctx, - FILE *spec_fp, - const char *remote_host, - const char *transport, - uint32_t remote_port) +static int +mgmt_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, + void *data) { - int ret; - - ret = fork (); - switch (ret) { - case -1: - perror ("fork()"); - break; - case 0: - /* child */ - ret = _fetch (ctx, spec_fp, remote_host, - transport, remote_port); - if (ret == -1) - exit (ret); - default: - /* parent */ - wait (&ret); - ret = WEXITSTATUS (ret); - } - return ret; + xlator_t *this = NULL; + glusterfs_ctx_t *ctx = NULL; + int ret = 0; + + this = mydata; + ctx = this->ctx; + + switch (event) { + case RPC_CLNT_CONNECT: + rpc_clnt_set_connected (ctx->mgmt); + + ret = glusterfs_volfile_fetch (ctx); + + break; + default: + break; + } + + return 0; } -FILE * -fetch_spec (glusterfs_ctx_t *ctx) + +int +glusterfs_mgmt_init (glusterfs_ctx_t *ctx) { - char *remote_host = NULL; - char *transport = NULL; - FILE *spec_fp; - int32_t ret; - - spec_fp = tmpfile (); - - if (!spec_fp) { - perror ("tmpfile ()"); - return NULL; - } - - remote_host = ctx->cmd_args.volfile_server; - transport = ctx->cmd_args.volfile_server_transport; - if (!transport) - transport = "tcp"; - - ret = _fork_and_fetch (ctx, spec_fp, remote_host, transport, - ctx->cmd_args.volfile_server_port); - - if (!ret) { - fseek (spec_fp, 0, SEEK_SET); - } - else { - fclose (spec_fp); - spec_fp = NULL; - } - - return spec_fp; + cmd_args_t *cmd_args = NULL; + struct rpc_clnt *rpc = NULL; + struct rpc_clnt_config rpc_cfg = {0,}; + dict_t *options = NULL; + int ret = -1; + int port = 6969; + char *host = NULL; + + cmd_args = &ctx->cmd_args; + + if (ctx->mgmt) + return 0; + + options = dict_new (); + if (!options) + goto out; + + if (cmd_args->volfile_server_port) + port = cmd_args->volfile_server_port; + + host = "localhost"; + if (cmd_args->volfile_server) + host = cmd_args->volfile_server; + + rpc_cfg.remote_host = host; + rpc_cfg.remote_port = port; + + ret = dict_set_int32 (options, "remote-port", port); + if (ret) + goto out; + + ret = dict_set_str (options, "remote-host", host); + if (ret) + goto out; + + ret = dict_set_str (options, "transport.address-family", "inet"); + if (ret) + goto out; + + rpc = rpc_clnt_init (&rpc_cfg, options, THIS->ctx, THIS->name); + if (!rpc) { + ret = -1; + goto out; + } + + ctx->mgmt = rpc; + + ret = rpc_clnt_register_notify (rpc, mgmt_rpc_notify, THIS); + if (ret) + goto out; + +out: + return ret; } -#endif |