diff options
39 files changed, 1389 insertions, 5501 deletions
diff --git a/rpc/rpc-lib/src/rpc-clnt.c b/rpc/rpc-lib/src/rpc-clnt.c index 819951c7e0d..09e676179d3 100644 --- a/rpc/rpc-lib/src/rpc-clnt.c +++ b/rpc/rpc-lib/src/rpc-clnt.c @@ -392,7 +392,8 @@ rpc_clnt_reconnect (void *trans_ptr) gf_log (trans->name, GF_LOG_TRACE, "attempting reconnect"); - ret = rpc_transport_connect (trans, conn->config.remote_port); + ret = rpc_transport_connect (trans, + conn->config.remote_port); /* Every time there is a disconnection, processes should try to connect to 'glusterd' (ie, default port) or whichever port given as 'option remote-port' @@ -435,7 +436,8 @@ rpc_clnt_fill_request_info (struct rpc_clnt *clnt, rpc_request_info_t *info) pthread_mutex_unlock (&clnt->conn.lock); if (ret == -1) { - gf_log (clnt->conn.trans->name, GF_LOG_CRITICAL, "cannot lookup the saved " + gf_log (clnt->conn.trans->name, GF_LOG_CRITICAL, + "cannot lookup the saved " "frame corresponding to xid (%d)", info->xid); goto out; } @@ -633,7 +635,8 @@ rpc_clnt_reply_init (rpc_clnt_connection_t *conn, rpc_transport_pollin_t *msg, goto out; } - gf_log (conn->trans->name, GF_LOG_TRACE, "received rpc message (RPC XID: 0x%ux" + gf_log (conn->trans->name, GF_LOG_TRACE, + "received rpc message (RPC XID: 0x%ux" " Program: %s, ProgVers: %d, Proc: %d) from rpc-transport (%s)", saved_frame->rpcreq->xid, saved_frame->rpcreq->prog->progname, @@ -831,8 +834,8 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata, pthread_mutex_unlock (&conn->lock); if (clnt->notifyfn) - ret = clnt->notifyfn (clnt, clnt->mydata, RPC_CLNT_DISCONNECT, - NULL); + ret = clnt->notifyfn (clnt, clnt->mydata, + RPC_CLNT_DISCONNECT, NULL); break; } @@ -878,7 +881,8 @@ rpc_clnt_notify (rpc_transport_t *trans, void *mydata, case RPC_TRANSPORT_CONNECT: { if (clnt->notifyfn) - ret = clnt->notifyfn (clnt, clnt->mydata, RPC_CLNT_CONNECT, NULL); + ret = clnt->notifyfn (clnt, clnt->mydata, + RPC_CLNT_CONNECT, NULL); break; } @@ -1051,7 +1055,8 @@ xdr_serialize_glusterfs_auth (char *dest, struct auth_glusterfs_parms *au) XDR_ENCODE); if (!xdr_auth_glusterfs_parms (&xdr, au)) { - gf_log (THIS->name, GF_LOG_WARNING, "failed to encode auth glusterfs elements"); + gf_log (THIS->name, GF_LOG_WARNING, + "failed to encode auth glusterfs elements"); ret = -1; goto ret; } @@ -1145,7 +1150,8 @@ out: struct iobuf * rpc_clnt_record_build_record (struct rpc_clnt *clnt, int prognum, int progver, int procnum, size_t payload, uint64_t xid, - struct auth_glusterfs_parms *au, struct iovec *recbuf) + struct auth_glusterfs_parms *au, + struct iovec *recbuf) { struct rpc_msg request = {0, }; struct iobuf *request_iob = NULL; diff --git a/rpc/rpc-lib/src/rpc-common.c b/rpc/rpc-lib/src/rpc-common.c index db7b92834e7..d62ed42042a 100644 --- a/rpc/rpc-lib/src/rpc-common.c +++ b/rpc/rpc-lib/src/rpc-common.c @@ -89,7 +89,8 @@ xdr_gf_prog_detail (XDR *xdrs, gf_prog_detail *objp) return FALSE; if (!xdr_u_quad_t (xdrs, &objp->progver)) return FALSE; - if (!xdr_pointer (xdrs, (char **)&objp->next, sizeof (gf_prog_detail), (xdrproc_t) xdr_gf_prog_detail)) + if (!xdr_pointer (xdrs, (char **)&objp->next, sizeof (gf_prog_detail), + (xdrproc_t) xdr_gf_prog_detail)) return FALSE; return TRUE; } @@ -103,7 +104,8 @@ xdr_gf_dump_rsp (XDR *xdrs, gf_dump_rsp *objp) return FALSE; if (!xdr_int (xdrs, &objp->op_errno)) return FALSE; - if (!xdr_pointer (xdrs, (char **)&objp->prog, sizeof (gf_prog_detail), (xdrproc_t) xdr_gf_prog_detail)) + if (!xdr_pointer (xdrs, (char **)&objp->prog, sizeof (gf_prog_detail), + (xdrproc_t) xdr_gf_prog_detail)) return FALSE; return TRUE; } diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c index 082ceec6e7b..b7245a8c9b8 100644 --- a/rpc/rpc-lib/src/rpc-transport.c +++ b/rpc/rpc-lib/src/rpc-transport.c @@ -525,7 +525,7 @@ rpc_transport_pollin_destroy (rpc_transport_pollin_t *pollin) if (pollin->iobref) { iobref_unref (pollin->iobref); } - + if (pollin->hdr_iobuf) { iobuf_unref (pollin->hdr_iobuf); } @@ -909,7 +909,8 @@ rpc_transport_unref (rpc_transport_t *this) if (refcount == 0) { if (this->mydata) - this->notify (this, this->mydata, RPC_TRANSPORT_CLEANUP, NULL); + this->notify (this, this->mydata, RPC_TRANSPORT_CLEANUP, + NULL); rpc_transport_destroy (this); } @@ -978,7 +979,8 @@ out: } int -rpc_transport_inet_options_build (dict_t **options, const char *hostname, int port) +rpc_transport_inet_options_build (dict_t **options, const char *hostname, + int port) { dict_t *dict = NULL; char *host = NULL; @@ -1000,15 +1002,15 @@ rpc_transport_inet_options_build (dict_t **options, const char *hostname, int po ret = dict_set_dynstr (dict, "remote-host", host); if (ret) { - gf_log (THIS->name, GF_LOG_WARNING, "failed to set remote-host with %s", - host); + gf_log (THIS->name, GF_LOG_WARNING, + "failed to set remote-host with %s", host); goto out; } ret = dict_set_int32 (dict, "remote-port", port); if (ret) { - gf_log (THIS->name, GF_LOG_WARNING, "failed to set remote-port with %d", - port); + gf_log (THIS->name, GF_LOG_WARNING, + "failed to set remote-port with %d", port); goto out; } ret = dict_set_str (dict, "transport.address-family", "inet/inet6"); diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h index f8396f572eb..5790b23f4f8 100644 --- a/rpc/rpc-lib/src/rpc-transport.h +++ b/rpc/rpc-lib/src/rpc-transport.h @@ -188,7 +188,7 @@ struct rpc_transport { * transport came from. valid only * on server process. */ - + void *private; void *xl_private; void *xl; /* Used for THIS */ @@ -203,7 +203,7 @@ struct rpc_transport { data_t *buf; int32_t (*init) (rpc_transport_t *this); void (*fini) (rpc_transport_t *this); - int32_t (*validate_options) (rpc_transport_t *this, + int32_t (*validate_options) (rpc_transport_t *this, char **op_errstr); int (*reconfigure) (rpc_transport_t *this, dict_t *options); rpc_transport_notify_t notify; diff --git a/rpc/rpc-lib/src/rpcsvc-auth.c b/rpc/rpc-lib/src/rpcsvc-auth.c index fcf4617ca9b..558ada509f0 100644 --- a/rpc/rpc-lib/src/rpcsvc-auth.c +++ b/rpc/rpc-lib/src/rpcsvc-auth.c @@ -318,8 +318,8 @@ rpcsvc_authenticate (rpcsvc_request_t *req) if (!req) return ret; - //minauth = rpcsvc_request_prog_minauth (req); - minauth = 1; + /* FIXME use rpcsvc_request_prog_minauth() */ + minauth = 0; if (minauth > rpcsvc_request_cred_flavour (req)) { gf_log (GF_RPCSVC, GF_LOG_WARNING, "Auth too weak"); rpcsvc_request_set_autherr (req, AUTH_TOOWEAK); @@ -339,6 +339,93 @@ err: return ret; } +int +rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen) +{ + int count = 0; + int gen = RPCSVC_AUTH_REJECT; + int spec = RPCSVC_AUTH_REJECT; + int final = RPCSVC_AUTH_REJECT; + char *srchstr = NULL; + char *valstr = NULL; + gf_boolean_t boolval = _gf_false; + int ret = 0; + + struct rpcsvc_auth_list *auth = NULL; + struct rpcsvc_auth_list *tmp = NULL; + + if ((!svc) || (!autharr) || (!volname)) + return -1; + + memset (autharr, 0, arrlen * sizeof(int)); + if (list_empty (&svc->authschemes)) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "No authentication!"); + goto err; + } + + list_for_each_entry_safe (auth, tmp, &svc->authschemes, authlist) { + if (count >= arrlen) + break; + + gen = gf_asprintf (&srchstr, "rpc-auth.%s", auth->name); + if (gen == -1) { + count = -1; + goto err; + } + + gen = RPCSVC_AUTH_REJECT; + if (dict_get (svc->options, srchstr)) { + ret = dict_get_str (svc->options, srchstr, &valstr); + if (ret == 0) { + ret = gf_string2boolean (valstr, &boolval); + if (ret == 0) { + if (boolval == _gf_true) + gen = RPCSVC_AUTH_ACCEPT; + } else + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile" + "d to read auth val"); + } else + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile" + "d to read auth val"); + } + + GF_FREE (srchstr); + spec = gf_asprintf (&srchstr, "rpc-auth.%s.%s", auth->name, + volname); + if (spec == -1) { + count = -1; + goto err; + } + + spec = RPCSVC_AUTH_DONTCARE; + if (dict_get (svc->options, srchstr)) { + ret = dict_get_str (svc->options, srchstr, &valstr); + if (ret == 0) { + ret = gf_string2boolean (valstr, &boolval); + if (ret == 0) { + if (boolval == _gf_true) + spec = RPCSVC_AUTH_ACCEPT; + else + spec = RPCSVC_AUTH_REJECT; + } else + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile" + "d to read auth val"); + } else + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile" + "d to read auth val"); + } + + GF_FREE (srchstr); + final = rpcsvc_combine_gen_spec_volume_checks (gen, spec); + if (final == RPCSVC_AUTH_ACCEPT) { + autharr[count] = auth->auth->authnum; + ++count; + } + } + +err: + return count; +} gid_t * rpcsvc_auth_unix_auxgids (rpcsvc_request_t *req, int *arrlen) diff --git a/rpc/rpc-lib/src/rpcsvc-common.h b/rpc/rpc-lib/src/rpcsvc-common.h index 442049433a7..233dac53c27 100644 --- a/rpc/rpc-lib/src/rpcsvc-common.h +++ b/rpc/rpc-lib/src/rpcsvc-common.h @@ -60,7 +60,7 @@ typedef struct rpcsvc_state { /* Allow insecure ports. */ int allow_insecure; - + gf_boolean_t register_portmap; glusterfs_ctx_t *ctx; /* list of connections which will listen for incoming connections */ diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c index 519d4e3466a..10198b0f35e 100644 --- a/rpc/rpc-lib/src/rpcsvc.c +++ b/rpc/rpc-lib/src/rpcsvc.c @@ -105,8 +105,33 @@ out: return; } +rpcsvc_vector_sizer +rpcsvc_get_program_vector_sizer (rpcsvc_t *svc, uint32_t prognum, + uint32_t progver, uint32_t procnum) +{ + rpcsvc_program_t *program = NULL; + char found = 0; + if (!svc) + return NULL; + pthread_mutex_lock (&svc->rpclock); + { + list_for_each_entry (program, &svc->programs, program) { + if ((program->prognum == prognum) + && (program->progver == progver)) { + found = 1; + break; + } + } + } + pthread_mutex_unlock (&svc->rpclock); + + if (found) + return program->actors[procnum].vector_sizer; + else + return NULL; +} /* This needs to change to returning errors, since * we need to return RPC specific error messages when some @@ -442,8 +467,10 @@ rpcsvc_handle_rpc_call (rpcsvc_t *svc, rpc_transport_t *trans, gf_log ("rpcsvc", GF_LOG_TRACE, "Client port: %d", (int)port); - if ((port > 1024) && (0 == svc->allow_insecure)) { //Non-privileged user, fail request - gf_log ("glusterd", GF_LOG_ERROR, "Request received from non-" + if ((port > 1024) && (0 == svc->allow_insecure)) { + /* Non-privileged user, fail request */ + gf_log ("glusterd", GF_LOG_ERROR, + "Request received from non-" "privileged port. Failing request"); return -1; } @@ -505,10 +532,10 @@ rpcsvc_handle_disconnect (rpcsvc_t *svc, rpc_transport_t *trans) rpcsvc_notify_wrapper_t *wrappers = NULL, *wrapper; int32_t ret = -1, i = 0, wrapper_count = 0; rpcsvc_listener_t *listener = NULL; - + event = (trans->listener == NULL) ? RPCSVC_EVENT_LISTENER_DEAD : RPCSVC_EVENT_DISCONNECT; - + pthread_mutex_lock (&svc->rpclock); { wrappers = GF_CALLOC (svc->notify_count, sizeof (*wrapper), @@ -516,35 +543,35 @@ rpcsvc_handle_disconnect (rpcsvc_t *svc, rpc_transport_t *trans) if (!wrappers) { goto unlock; } - + list_for_each_entry (wrapper, &svc->notify, list) { if (wrapper->notify) { wrappers[i++] = *wrapper; } } - + wrapper_count = i; } unlock: pthread_mutex_unlock (&svc->rpclock); - + if (wrappers) { for (i = 0; i < wrapper_count; i++) { wrappers[i].notify (svc, wrappers[i].data, event, trans); } - + GF_FREE (wrappers); } - + if (event == RPCSVC_EVENT_LISTENER_DEAD) { listener = rpcsvc_get_listener (svc, -1, trans->listener); rpcsvc_listener_destroy (listener); } - + return ret; } - + int rpcsvc_notify (rpc_transport_t *trans, void *mydata, @@ -1114,6 +1141,11 @@ out: return ret; } +int +rpcsvc_register_portmap_enabled (rpcsvc_t *svc) +{ + return svc->register_portmap; +} int32_t rpcsvc_get_listener_port (rpcsvc_listener_t *listener) @@ -1152,7 +1184,7 @@ rpcsvc_get_listener (rpcsvc_t *svc, uint16_t port, rpc_transport_t *trans) { rpcsvc_listener_t *listener = NULL; char found = 0; - uint32_t listener_port = 0; + uint32_t listener_port = 0; if (!svc) { goto out; @@ -1343,7 +1375,7 @@ rpcsvc_create_listener (rpcsvc_t *svc, dict_t *options, char *name) { rpc_transport_t *trans = NULL; rpcsvc_listener_t *listener = NULL; - int32_t ret = -1; + int32_t ret = -1; if (!svc || !options) { goto out; @@ -1577,7 +1609,6 @@ out: return ret; } - static void free_prog_details (gf_dump_rsp *rsp) { @@ -1670,8 +1701,39 @@ fail: int rpcsvc_init_options (rpcsvc_t *svc, dict_t *options) { + char *optstr = NULL; + int ret = -1; + + if ((!svc) || (!options)) + return -1; + svc->memfactor = RPCSVC_DEFAULT_MEMFACTOR; - return 0; + + svc->register_portmap = _gf_true; + if (dict_get (options, "rpc.register-with-portmap")) { + ret = dict_get_str (options, "rpc.register-with-portmap", + &optstr); + if (ret < 0) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to parse " + "dict"); + goto out; + } + + ret = gf_string2boolean (optstr, &svc->register_portmap); + if (ret < 0) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to parse bool " + "string"); + goto out; + } + } + + if (!svc->register_portmap) + gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Portmap registration " + "disabled"); + + ret = 0; +out: + return ret; } int @@ -1789,6 +1851,531 @@ free_svc: } +int +rpcsvc_transport_peer_check_search (dict_t *options, char *pattern, char *clstr) +{ + int ret = -1; + char *addrtok = NULL; + char *addrstr = NULL; + char *svptr = NULL; + + if ((!options) || (!clstr)) + return -1; + + if (!dict_get (options, pattern)) + return -1; + + ret = dict_get_str (options, pattern, &addrstr); + if (ret < 0) { + ret = -1; + goto err; + } + + if (!addrstr) { + ret = -1; + goto err; + } + + addrtok = strtok_r (addrstr, ",", &svptr); + while (addrtok) { + + /* CASEFOLD not present on Solaris */ +#ifdef FNM_CASEFOLD + ret = fnmatch (addrtok, clstr, FNM_CASEFOLD); +#else + ret = fnmatch (addrtok, clstr, 0); +#endif + if (ret == 0) + goto err; + + addrtok = strtok_r (NULL, ",", &svptr); + } + + ret = -1; +err: + + return ret; +} + + +int +rpcsvc_transport_peer_check_allow (dict_t *options, char *volname, char *clstr) +{ + int ret = RPCSVC_AUTH_DONTCARE; + char *srchstr = NULL; + char globalrule[] = "rpc-auth.addr.allow"; + + if ((!options) || (!clstr)) + return ret; + + /* If volname is NULL, then we're searching for the general rule to + * determine the current address in clstr is allowed or not for all + * subvolumes. + */ + if (volname) { + ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.allow", volname); + if (ret == -1) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed"); + ret = RPCSVC_AUTH_DONTCARE; + goto out; + } + } else + srchstr = globalrule; + + ret = rpcsvc_transport_peer_check_search (options, srchstr, clstr); + if (volname) + GF_FREE (srchstr); + + if (ret == 0) + ret = RPCSVC_AUTH_ACCEPT; + else + ret = RPCSVC_AUTH_DONTCARE; +out: + return ret; +} + +int +rpcsvc_transport_peer_check_reject (dict_t *options, char *volname, char *clstr) +{ + int ret = RPCSVC_AUTH_DONTCARE; + char *srchstr = NULL; + char generalrule[] = "rpc-auth.addr.reject"; + + if ((!options) || (!clstr)) + return ret; + + if (volname) { + ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.reject", + volname); + if (ret == -1) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed"); + ret = RPCSVC_AUTH_REJECT; + goto out; + } + } else + srchstr = generalrule; + + ret = rpcsvc_transport_peer_check_search (options, srchstr, clstr); + if (volname) + GF_FREE (srchstr); + + if (ret == 0) + ret = RPCSVC_AUTH_REJECT; + else + ret = RPCSVC_AUTH_DONTCARE; +out: + return ret; +} + + +/* This function tests the results of the allow rule and the reject rule to + * combine them into a single result that can be used to determine if the + * connection should be allowed to proceed. + * Heres the test matrix we need to follow in this function. + * + * A - Allow, the result of the allow test. Never returns R. + * R - Reject, result of the reject test. Never returns A. + * Both can return D or dont care if no rule was given. + * + * | @allow | @reject | Result | + * | A | R | R | + * | D | D | D | + * | A | D | A | + * | D | R | R | + */ +int +rpcsvc_combine_allow_reject_volume_check (int allow, int reject) +{ + int final = RPCSVC_AUTH_REJECT; + + /* If allowed rule allows but reject rule rejects, we stay cautious + * and reject. */ + if ((allow == RPCSVC_AUTH_ACCEPT) && (reject == RPCSVC_AUTH_REJECT)) + final = RPCSVC_AUTH_REJECT; + /* if both are dont care, that is user did not specify for either allow + * or reject, we leave it up to the general rule to apply, in the hope + * that there is one. + */ + else if ((allow == RPCSVC_AUTH_DONTCARE) && + (reject == RPCSVC_AUTH_DONTCARE)) + final = RPCSVC_AUTH_DONTCARE; + /* If one is dont care, the other one applies. */ + else if ((allow == RPCSVC_AUTH_ACCEPT) && + (reject == RPCSVC_AUTH_DONTCARE)) + final = RPCSVC_AUTH_ACCEPT; + else if ((allow == RPCSVC_AUTH_DONTCARE) && + (reject == RPCSVC_AUTH_REJECT)) + final = RPCSVC_AUTH_REJECT; + + return final; +} + + +/* Combines the result of the general rule test against, the specific rule + * to determine final permission for the client's address. + * + * | @gen | @spec | Result | + * | A | A | A | + * | A | R | R | + * | A | D | A | + * | D | A | A | + * | D | R | R | + * | D | D | D | + * | R | A | A | + * | R | D | R | + * | R | R | R | + */ +int +rpcsvc_combine_gen_spec_addr_checks (int gen, int spec) +{ + int final = RPCSVC_AUTH_REJECT; + + if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_ACCEPT)) + final = RPCSVC_AUTH_ACCEPT; + else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_REJECT)) + final = RPCSVC_AUTH_REJECT; + else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_DONTCARE)) + final = RPCSVC_AUTH_ACCEPT; + else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_ACCEPT)) + final = RPCSVC_AUTH_ACCEPT; + else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_REJECT)) + final = RPCSVC_AUTH_REJECT; + else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec== RPCSVC_AUTH_DONTCARE)) + final = RPCSVC_AUTH_DONTCARE; + else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_ACCEPT)) + final = RPCSVC_AUTH_ACCEPT; + else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_DONTCARE)) + final = RPCSVC_AUTH_REJECT; + else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_REJECT)) + final = RPCSVC_AUTH_REJECT; + + return final; +} + + + +/* Combines the result of the general rule test against, the specific rule + * to determine final test for the connection coming in for a given volume. + * + * | @gen | @spec | Result | + * | A | A | A | + * | A | R | R | + * | A | D | A | + * | D | A | A | + * | D | R | R | + * | D | D | R |, special case, we intentionally disallow this. + * | R | A | A | + * | R | D | R | + * | R | R | R | + */ +int +rpcsvc_combine_gen_spec_volume_checks (int gen, int spec) +{ + int final = RPCSVC_AUTH_REJECT; + + if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_ACCEPT)) + final = RPCSVC_AUTH_ACCEPT; + else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_REJECT)) + final = RPCSVC_AUTH_REJECT; + else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_DONTCARE)) + final = RPCSVC_AUTH_ACCEPT; + else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_ACCEPT)) + final = RPCSVC_AUTH_ACCEPT; + else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_REJECT)) + final = RPCSVC_AUTH_REJECT; + /* On no rule, we reject. */ + else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec== RPCSVC_AUTH_DONTCARE)) + final = RPCSVC_AUTH_REJECT; + else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_ACCEPT)) + final = RPCSVC_AUTH_ACCEPT; + else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_DONTCARE)) + final = RPCSVC_AUTH_REJECT; + else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_REJECT)) + final = RPCSVC_AUTH_REJECT; + + return final; +} + + +int +rpcsvc_transport_peer_check_name (dict_t *options, char *volname, + rpc_transport_t *trans) +{ + int ret = RPCSVC_AUTH_REJECT; + int aret = RPCSVC_AUTH_REJECT; + int rjret = RPCSVC_AUTH_REJECT; + char clstr[RPCSVC_PEER_STRLEN]; + + if (!trans) + return ret; + + ret = rpcsvc_transport_peername (trans, clstr, RPCSVC_PEER_STRLEN); + if (ret != 0) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get remote addr: " + "%s", gai_strerror (ret)); + ret = RPCSVC_AUTH_REJECT; + goto err; + } + + aret = rpcsvc_transport_peer_check_allow (options, volname, clstr); + rjret = rpcsvc_transport_peer_check_reject (options, volname, clstr); + + ret = rpcsvc_combine_allow_reject_volume_check (aret, rjret); + +err: + return ret; +} + + +int +rpcsvc_transport_peer_check_addr (dict_t *options, char *volname, + rpc_transport_t *trans) +{ + int ret = RPCSVC_AUTH_REJECT; + int aret = RPCSVC_AUTH_DONTCARE; + int rjret = RPCSVC_AUTH_REJECT; + char clstr[RPCSVC_PEER_STRLEN]; + struct sockaddr_storage sastorage = {0,}; + + if (!trans) + return ret; + + ret = rpcsvc_transport_peeraddr (trans, clstr, RPCSVC_PEER_STRLEN, + &sastorage, sizeof (sastorage)); + if (ret != 0) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get remote addr: " + "%s", gai_strerror (ret)); + ret = RPCSVC_AUTH_REJECT; + goto err; + } + + aret = rpcsvc_transport_peer_check_allow (options, volname, clstr); + rjret = rpcsvc_transport_peer_check_reject (options, volname, clstr); + + ret = rpcsvc_combine_allow_reject_volume_check (aret, rjret); +err: + return ret; +} + + +int +rpcsvc_transport_check_volume_specific (dict_t *options, char *volname, + rpc_transport_t *trans) +{ + int namechk = RPCSVC_AUTH_REJECT; + int addrchk = RPCSVC_AUTH_REJECT; + gf_boolean_t namelookup = _gf_true; + char *namestr = NULL; + int ret = 0; + + if ((!options) || (!volname) || (!trans)) + return RPCSVC_AUTH_REJECT; + + /* Enabled by default */ + if ((dict_get (options, "rpc-auth.addr.namelookup"))) { + ret = dict_get_str (options, "rpc-auth.addr.namelookup" + , &namestr); + if (ret == 0) + ret = gf_string2boolean (namestr, &namelookup); + } + + /* We need two separate checks because the rules with addresses in them + * can be network addresses which can be general and names can be + * specific which will over-ride the network address rules. + */ + if (namelookup) + namechk = rpcsvc_transport_peer_check_name (options, volname, + trans); + addrchk = rpcsvc_transport_peer_check_addr (options, volname, trans); + + if (namelookup) + ret = rpcsvc_combine_gen_spec_addr_checks (addrchk, + namechk); + else + ret = addrchk; + + return ret; +} + + +int +rpcsvc_transport_check_volume_general (dict_t *options, rpc_transport_t *trans) +{ + int addrchk = RPCSVC_AUTH_REJECT; + int namechk = RPCSVC_AUTH_REJECT; + gf_boolean_t namelookup = _gf_true; + char *namestr = NULL; + int ret = 0; + + if ((!options) || (!trans)) + return RPCSVC_AUTH_REJECT; + + /* Enabled by default */ + if ((dict_get (options, "rpc-auth.addr.namelookup"))) { + ret = dict_get_str (options, "rpc-auth.addr.namelookup" + , &namestr); + if (ret == 0) + ret = gf_string2boolean (namestr, &namelookup); + } + + /* We need two separate checks because the rules with addresses in them + * can be network addresses which can be general and names can be + * specific which will over-ride the network address rules. + */ + if (namelookup) + namechk = rpcsvc_transport_peer_check_name (options, NULL, trans); + addrchk = rpcsvc_transport_peer_check_addr (options, NULL, trans); + + if (namelookup) + ret = rpcsvc_combine_gen_spec_addr_checks (addrchk, + namechk); + else + ret = addrchk; + + return ret; +} + +int +rpcsvc_transport_peer_check (dict_t *options, char *volname, + rpc_transport_t *trans) +{ + int general_chk = RPCSVC_AUTH_REJECT; + int specific_chk = RPCSVC_AUTH_REJECT; + + if ((!options) || (!volname) || (!trans)) + return RPCSVC_AUTH_REJECT; + + general_chk = rpcsvc_transport_check_volume_general (options, trans); + specific_chk = rpcsvc_transport_check_volume_specific (options, volname, + trans); + + return rpcsvc_combine_gen_spec_volume_checks (general_chk, + specific_chk); +} + + +int +rpcsvc_transport_privport_check (rpcsvc_t *svc, char *volname, + rpc_transport_t *trans) +{ + struct sockaddr_storage sastorage = {0,}; + struct sockaddr_in *sa = NULL; + int ret = RPCSVC_AUTH_REJECT; + socklen_t sasize = sizeof (sa); + char *srchstr = NULL; + char *valstr = NULL; + int globalinsecure = RPCSVC_AUTH_REJECT; + int exportinsecure = RPCSVC_AUTH_DONTCARE; + uint16_t port = 0; + gf_boolean_t insecure = _gf_false; + + if ((!svc) || (!volname) || (!trans)) + return ret; + + sa = (struct sockaddr_in*) &sastorage; + ret = rpcsvc_transport_peeraddr (trans, NULL, 0, &sastorage, + sasize); + if (ret != 0) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get peer addr: %s", + gai_strerror (ret)); + ret = RPCSVC_AUTH_REJECT; + goto err; + } + + port = ntohs (sa->sin_port); + gf_log (GF_RPCSVC, GF_LOG_TRACE, "Client port: %d", (int)port); + /* If the port is already a privileged one, dont bother with checking + * options. + */ + if (port <= 1024) { + ret = RPCSVC_AUTH_ACCEPT; + goto err; + } + + /* Disabled by default */ + if ((dict_get (svc->options, "rpc-auth.ports.insecure"))) { + ret = dict_get_str (svc->options, "rpc-auth.ports.insecure" + , &srchstr); + if (ret == 0) { + ret = gf_string2boolean (srchstr, &insecure); + if (ret == 0) { + if (insecure == _gf_true) + globalinsecure = RPCSVC_AUTH_ACCEPT; + } else + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to" + " read rpc-auth.ports.insecure value"); + } else + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to" + " read rpc-auth.ports.insecure value"); + } + + /* Disabled by default */ + ret = gf_asprintf (&srchstr, "rpc-auth.ports.%s.insecure", volname); + if (ret == -1) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed"); + ret = RPCSVC_AUTH_REJECT; + goto err; + } + + if (dict_get (svc->options, srchstr)) { + ret = dict_get_str (svc->options, srchstr, &valstr); + if (ret == 0) { + ret = gf_string2boolean (srchstr, &insecure); + if (ret == 0) { + if (insecure == _gf_true) + exportinsecure = RPCSVC_AUTH_ACCEPT; + else + exportinsecure = RPCSVC_AUTH_REJECT; + } else + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to" + " read rpc-auth.ports.insecure value"); + } else + gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to" + " read rpc-auth.ports.insecure value"); + } + + ret = rpcsvc_combine_gen_spec_volume_checks (globalinsecure, + exportinsecure); + if (ret == RPCSVC_AUTH_ACCEPT) + gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Unprivileged port allowed"); + else + gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Unprivileged port not" + " allowed"); + +err: + return ret; +} + + +char * +rpcsvc_volume_allowed (dict_t *options, char *volname) +{ + char globalrule[] = "rpc-auth.addr.allow"; + char *srchstr = NULL; + char *addrstr = NULL; + int ret = -1; + + if ((!options) || (!volname)) + return NULL; + + ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.allow", volname); + if (ret == -1) { + gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed"); + goto out; + } + + if (!dict_get (options, srchstr)) { + GF_FREE (srchstr); + srchstr = globalrule; + ret = dict_get_str (options, srchstr, &addrstr); + } else + ret = dict_get_str (options, srchstr, &addrstr); + +out: + return addrstr; +} + + rpcsvc_actor_t gluster_dump_actors[] = { [GF_DUMP_NULL] = {"NULL", GF_DUMP_NULL, NULL, NULL, NULL }, [GF_DUMP_DUMP] = {"DUMP", GF_DUMP_DUMP, rpcsvc_dump, NULL, NULL }, diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h index 17da800fa9c..7ef6e580c22 100644 --- a/rpc/rpc-lib/src/rpcsvc.h +++ b/rpc/rpc-lib/src/rpcsvc.h @@ -249,7 +249,8 @@ struct rpcsvc_request { }; #define rpcsvc_request_program(req) ((rpcsvc_program_t *)((req)->prog)) -#define rpcsvc_request_program_private(req) (((rpcsvc_program_t *)((req)->program))->private) +#define rpcsvc_request_procnum(req) (((req)->procnum)) +#define rpcsvc_request_program_private(req) (((rpcsvc_program_t *)((req)->prog))->private) #define rpcsvc_request_accepted(req) ((req)->rpc_status == MSG_ACCEPTED) #define rpcsvc_request_accepted_success(req) ((req)->rpc_err == SUCCESS) #define rpcsvc_request_uid(req) ((req)->uid) @@ -257,18 +258,24 @@ struct rpcsvc_request { #define rpcsvc_request_prog_minauth(req) (rpcsvc_request_program(req)->min_auth) #define rpcsvc_request_cred_flavour(req) (rpcsvc_auth_flavour(req->cred)) #define rpcsvc_request_verf_flavour(req) (rpcsvc_auth_flavour(req->verf)) - +#define rpcsvc_request_service(req) ((req)->svc) #define rpcsvc_request_uid(req) ((req)->uid) #define rpcsvc_request_gid(req) ((req)->gid) #define rpcsvc_request_private(req) ((req)->private) #define rpcsvc_request_xid(req) ((req)->xid) #define rpcsvc_request_set_private(req,prv) (req)->private = (void *)(prv) +#define rpcsvc_request_iobref_ref(req) (iobref_ref ((req)->iobref)) #define rpcsvc_request_record_ref(req) (iobuf_ref ((req)->recordiob)) #define rpcsvc_request_record_unref(req) (iobuf_unref ((req)->recordiob)) +#define rpcsvc_request_record_iob(req) ((req)->recordiob) +#define rpcsvc_request_set_vecstate(req, state) ((req)->vecstate = state) +#define rpcsvc_request_vecstate(req) ((req)->vecstate) +#define rpcsvc_request_transport(req) ((req)->trans) #define RPCSVC_ACTOR_SUCCESS 0 #define RPCSVC_ACTOR_ERROR (-1) +#define RPCSVC_ACTOR_IGNORE (-2) /* Functor for every type of protocol actor * must be defined like this. @@ -285,8 +292,7 @@ struct rpcsvc_request { typedef int (*rpcsvc_actor) (rpcsvc_request_t *req); typedef int (*rpcsvc_vector_actor) (rpcsvc_request_t *req, struct iovec *vec, int count, struct iobref *iobref); -typedef int (*rpcsvc_vector_sizer) (rpcsvc_request_t *req, ssize_t *readsize, - int *newiob); +typedef int (*rpcsvc_vector_sizer) (int state, ssize_t *readsize, char *addr); /* Every protocol actor will also need to specify the function the RPC layer * will use to serialize or encode the message into XDR format just before @@ -410,6 +416,9 @@ rpcsvc_listener_destroy (rpcsvc_listener_t *listener); extern int rpcsvc_program_register_portmap (rpcsvc_program_t *newprog, uint32_t port); +extern int +rpcsvc_register_portmap_enabled (rpcsvc_t *svc); + /* Inits the global RPC service data structures. * Called in main. */ @@ -542,4 +551,12 @@ int rpcsvc_transport_unix_options_build (dict_t **options, char *filepath); int rpcsvc_set_allow_insecure (rpcsvc_t *svc, dict_t *options); +int +rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen); +char * +rpcsvc_volume_allowed (dict_t *options, char *volname); +rpcsvc_vector_sizer +rpcsvc_get_program_vector_sizer (rpcsvc_t *svc, uint32_t prognum, + uint32_t progver, uint32_t procnum); + #endif diff --git a/rpc/rpc-lib/src/xdr-common.h b/rpc/rpc-lib/src/xdr-common.h index c69bfa834fb..0014e46ac1a 100644 --- a/rpc/rpc-lib/src/xdr-common.h +++ b/rpc/rpc-lib/src/xdr-common.h @@ -113,8 +113,6 @@ xdr_from_dump_req (struct iovec outmsg, void *rsp); ssize_t xdr_to_dump_rsp (struct iovec inmsg, void *args); -#define XDR_BYTES_PER_UNIT 4 - /* Returns the address of the byte that follows the * last byte used for decoding the previous xdr component. * For eg, once the RPC call for NFS has been decoded, thie macro will return diff --git a/rpc/rpc-transport/socket/src/socket.c b/rpc/rpc-transport/socket/src/socket.c index 23889b52077..51d51bc9e85 100644 --- a/rpc/rpc-transport/socket/src/socket.c +++ b/rpc/rpc-transport/socket/src/socket.c @@ -38,6 +38,8 @@ #include "protocol-common.h" #include "glusterfs3-xdr.h" #include "glusterfs3.h" +#include "xdr-nfs3.h" +#include "rpcsvc.h" #include <fcntl.h> #include <errno.h> @@ -806,9 +808,14 @@ __socket_read_simple_request (rpc_transport_t *this) #define rpc_verf_addr(fragcurrent) (fragcurrent - 4) +#define rpc_msgtype_addr(buf) (buf + 4) + +#define rpc_prognum_addr(buf) (buf + RPC_MSGTYPE_SIZE + 4) +#define rpc_progver_addr(buf) (buf + RPC_MSGTYPE_SIZE + 8) +#define rpc_procnum_addr(buf) (buf + RPC_MSGTYPE_SIZE + 12) inline int -__socket_read_vectored_request (rpc_transport_t *this) +__socket_read_vectored_request (rpc_transport_t *this, rpcsvc_vector_sizer vector_sizer) { socket_private_t *priv = NULL; int ret = 0; @@ -816,8 +823,7 @@ __socket_read_vectored_request (rpc_transport_t *this) char *addr = NULL; struct iobuf *iobuf = NULL; uint32_t remaining_size = 0; - uint32_t gluster_write_proc_len = 0; - gfs3_write_req write_req = {{0,},}; + ssize_t readsize = 0; GF_VALIDATE_OR_GOTO ("socket", this, out); GF_VALIDATE_OR_GOTO ("socket", this->private, out); @@ -826,6 +832,7 @@ __socket_read_vectored_request (rpc_transport_t *this) switch (priv->incoming.frag.call_body.request.vector_state) { case SP_STATE_VECTORED_REQUEST_INIT: + priv->incoming.frag.call_body.request.vector_sizer_state = 0; addr = rpc_cred_addr (iobuf_ptr (priv->incoming.iobuf)); /* also read verf flavour and verflen */ @@ -849,24 +856,13 @@ __socket_read_vectored_request (rpc_transport_t *this) case SP_STATE_READ_CREDBYTES: addr = rpc_verf_addr (priv->incoming.frag.fragcurrent); + verflen = ntoh32 (*((uint32_t *)addr)); - /* FIXME: Also handle procedures other than glusterfs-write - * here - */ - /* also read proc-header */ - gluster_write_proc_len = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req, - &write_req); - - if (gluster_write_proc_len == 0) { - gf_log (this->name, GF_LOG_ERROR, - "xdr_sizeof on gfs3_write_req failed"); - ret = -1; - goto out; + if (verflen == 0) { + priv->incoming.frag.call_body.request.vector_state + = SP_STATE_READ_VERFBYTES; + goto sp_state_read_verfbytes; } - - verflen = ntoh32 (*((uint32_t *)addr)) - + gluster_write_proc_len; - __socket_proto_init_pending (priv, verflen); priv->incoming.frag.call_body.request.vector_state @@ -883,6 +879,34 @@ __socket_read_vectored_request (rpc_transport_t *this) /* fall through */ case SP_STATE_READ_VERFBYTES: +sp_state_read_verfbytes: + priv->incoming.frag.call_body.request.vector_sizer_state = + vector_sizer (priv->incoming.frag.call_body.request.vector_sizer_state, + &readsize, + priv->incoming.frag.fragcurrent); + __socket_proto_init_pending (priv, readsize); + priv->incoming.frag.call_body.request.vector_state + = SP_STATE_READING_PROGHDR; + + /* fall through */ + + case SP_STATE_READING_PROGHDR: + __socket_proto_read (priv, ret); +sp_state_reading_proghdr: + priv->incoming.frag.call_body.request.vector_sizer_state = + vector_sizer (priv->incoming.frag.call_body.request.vector_sizer_state, + &readsize, + priv->incoming.frag.fragcurrent); + if (readsize == 0) { + priv->incoming.frag.call_body.request.vector_state = + SP_STATE_READ_PROGHDR; + } else { + __socket_proto_init_pending (priv, readsize); + __socket_proto_read (priv, ret); + goto sp_state_reading_proghdr; + } + + case SP_STATE_READ_PROGHDR: if (priv->incoming.payload_vector.iov_base == NULL) { iobuf = iobuf_get (this->ctx->iobuf_pool); if (!iobuf) { @@ -941,22 +965,15 @@ out: return ret; } - -#define rpc_msgtype_addr(buf) (buf + 4) - -#define rpc_prognum_addr(buf) (buf + RPC_MSGTYPE_SIZE + 4) - -#define rpc_procnum_addr(buf) (buf + RPC_MSGTYPE_SIZE + 12) - - inline int __socket_read_request (rpc_transport_t *this) { socket_private_t *priv = NULL; - uint32_t prognum = 0, procnum = 0; + uint32_t prognum = 0, procnum = 0, progver = 0; uint32_t remaining_size = 0; int ret = -1; char *buf = NULL; + rpcsvc_vector_sizer vector_sizer = NULL; GF_VALIDATE_OR_GOTO ("socket", this, out); GF_VALIDATE_OR_GOTO ("socket", this->private, out); @@ -986,12 +1003,21 @@ __socket_read_request (rpc_transport_t *this) buf = rpc_prognum_addr (iobuf_ptr (priv->incoming.iobuf)); prognum = ntoh32 (*((uint32_t *)buf)); + buf = rpc_progver_addr (iobuf_ptr (priv->incoming.iobuf)); + progver = ntoh32 (*((uint32_t *)buf)); + buf = rpc_procnum_addr (iobuf_ptr (priv->incoming.iobuf)); procnum = ntoh32 (*((uint32_t *)buf)); - if ((prognum == GLUSTER3_1_FOP_PROGRAM) - && (procnum == GF_FOP_WRITE)) { - ret = __socket_read_vectored_request (this); + if (this->listener) { + /* this check is needed as rpcsvc and rpc-clnt actor structures are + * not same */ + vector_sizer = rpcsvc_get_program_vector_sizer ((rpcsvc_t *)this->mydata, + prognum, progver, procnum); + } + + if (vector_sizer) { + ret = __socket_read_vectored_request (this, vector_sizer); } else { ret = __socket_read_simple_request (this); } @@ -2411,6 +2437,7 @@ socket_getpeeraddr (rpc_transport_t *this, char *peeraddr, int addrlen, if (peeraddr != NULL) { ret = socket_getpeername (this, peeraddr, addrlen); } + ret = 0; out: return ret; diff --git a/rpc/rpc-transport/socket/src/socket.h b/rpc/rpc-transport/socket/src/socket.h index c52026cc829..4cc84a6d187 100644 --- a/rpc/rpc-transport/socket/src/socket.h +++ b/rpc/rpc-transport/socket/src/socket.h @@ -81,6 +81,8 @@ typedef enum { SP_STATE_READ_CREDBYTES, /* read credential data. */ SP_STATE_READING_VERFBYTES, SP_STATE_READ_VERFBYTES, /* read verifier data */ + SP_STATE_READING_PROGHDR, + SP_STATE_READ_PROGHDR, SP_STATE_READING_PROG, } sp_rpcfrag_vectored_request_state_t; @@ -112,6 +114,7 @@ struct ioq { typedef struct { sp_rpcfrag_request_header_state_t header_state; sp_rpcfrag_vectored_request_state_t vector_state; + int vector_sizer_state; } sp_rpcfrag_request_state_t; typedef enum { diff --git a/rpc/xdr/src/Makefile.am b/rpc/xdr/src/Makefile.am index 981f319b3a7..d239700903c 100644 --- a/rpc/xdr/src/Makefile.am +++ b/rpc/xdr/src/Makefile.am @@ -13,10 +13,12 @@ libgfxdr_la_SOURCES = xdr-generic.c \ glusterfs3-xdr.c glusterfs3.c \ cli1-xdr.c cli1.c \ glusterd1-xdr.c glusterd1.c \ - portmap-xdr.c portmap.c + portmap-xdr.c portmap.c \ + xdr-nfs3.c msg-nfs3.c noinst_HEADERS = xdr-generic.h \ glusterfs3-xdr.h glusterfs3.h \ cli1-xdr.h cli1.h \ glusterd1-xdr.h glusterd1.h \ - portmap-xdr.h portmap.h + portmap-xdr.h portmap.h \ + xdr-nfs3.h msg-nfs3.h diff --git a/xlators/nfs/lib/src/msg-nfs3.c b/rpc/xdr/src/msg-nfs3.c index e6e722051ee..78051494b9c 100644 --- a/xlators/nfs/lib/src/msg-nfs3.c +++ b/rpc/xdr/src/msg-nfs3.c @@ -29,6 +29,7 @@ #include "xdr-nfs3.h" #include "msg-nfs3.h" +#include "xdr-generic.h" #include "xdr-common.h" @@ -56,15 +57,15 @@ xdr_to_mountpath (struct iovec outpath, struct iovec inmsg) goto ret; } - ret = nfs_xdr_decoded_length (xdr); + ret = xdr_decoded_length (xdr); ret: return ret; } - +/* ssize_t -nfs_xdr_serialize_generic (struct iovec outmsg, void *res, xdrproc_t proc) +xdr_serialize_generic (struct iovec outmsg, void *res, xdrproc_t proc) { ssize_t ret = -1; XDR xdr; @@ -80,7 +81,7 @@ nfs_xdr_serialize_generic (struct iovec outmsg, void *res, xdrproc_t proc) goto ret; } - ret = nfs_xdr_encoded_length (xdr); + ret = xdr_encoded_length (xdr); ret: return ret; @@ -88,7 +89,7 @@ ret: ssize_t -nfs_xdr_to_generic (struct iovec inmsg, void *args, xdrproc_t proc) +xdr_to_generic (struct iovec inmsg, void *args, xdrproc_t proc) { XDR xdr; ssize_t ret = -1; @@ -104,14 +105,14 @@ nfs_xdr_to_generic (struct iovec inmsg, void *args, xdrproc_t proc) goto ret; } - ret = nfs_xdr_decoded_length (xdr); + ret = xdr_decoded_length (xdr); ret: return ret; } ssize_t -nfs_xdr_to_generic_payload (struct iovec inmsg, void *args, xdrproc_t proc, +xdr_to_generic_payload (struct iovec inmsg, void *args, xdrproc_t proc, struct iovec *pendingpayload) { XDR xdr; @@ -128,17 +129,17 @@ nfs_xdr_to_generic_payload (struct iovec inmsg, void *args, xdrproc_t proc, goto ret; } - ret = nfs_xdr_decoded_length (xdr); + ret = xdr_decoded_length (xdr); if (pendingpayload) { - pendingpayload->iov_base = nfs_xdr_decoded_remaining_addr (xdr); - pendingpayload->iov_len = nfs_xdr_decoded_remaining_len (xdr); + pendingpayload->iov_base = xdr_decoded_remaining_addr (xdr); + pendingpayload->iov_len = xdr_decoded_remaining_len (xdr); } ret: return ret; } - +*/ /* Translate the mountres3 structure in res into XDR format into memory * referenced by outmsg.iov_base. @@ -147,7 +148,7 @@ ret: ssize_t xdr_serialize_mountres3 (struct iovec outmsg, mountres3 *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_mountres3); } @@ -155,14 +156,14 @@ xdr_serialize_mountres3 (struct iovec outmsg, mountres3 *res) ssize_t xdr_serialize_mountbody (struct iovec outmsg, mountbody *mb) { - return nfs_xdr_serialize_generic (outmsg, (void *)mb, + return xdr_serialize_generic (outmsg, (void *)mb, (xdrproc_t)xdr_mountbody); } ssize_t xdr_serialize_mountlist (struct iovec outmsg, mountlist *ml) { - return nfs_xdr_serialize_generic (outmsg, (void *)ml, + return xdr_serialize_generic (outmsg, (void *)ml, (xdrproc_t)xdr_mountlist); } @@ -170,7 +171,7 @@ xdr_serialize_mountlist (struct iovec outmsg, mountlist *ml) ssize_t xdr_serialize_mountstat3 (struct iovec outmsg, mountstat3 *m) { - return nfs_xdr_serialize_generic (outmsg, (void *)m, + return xdr_serialize_generic (outmsg, (void *)m, (xdrproc_t)xdr_mountstat3); } @@ -178,7 +179,7 @@ xdr_serialize_mountstat3 (struct iovec outmsg, mountstat3 *m) ssize_t xdr_to_getattr3args (struct iovec inmsg, getattr3args *ga) { - return nfs_xdr_to_generic (inmsg, (void *)ga, + return xdr_to_generic (inmsg, (void *)ga, (xdrproc_t)xdr_getattr3args); } @@ -186,7 +187,7 @@ xdr_to_getattr3args (struct iovec inmsg, getattr3args *ga) ssize_t xdr_serialize_getattr3res (struct iovec outmsg, getattr3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_getattr3res); } @@ -194,7 +195,7 @@ xdr_serialize_getattr3res (struct iovec outmsg, getattr3res *res) ssize_t xdr_serialize_setattr3res (struct iovec outmsg, setattr3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_setattr3res); } @@ -202,7 +203,7 @@ xdr_serialize_setattr3res (struct iovec outmsg, setattr3res *res) ssize_t xdr_to_setattr3args (struct iovec inmsg, setattr3args *sa) { - return nfs_xdr_to_generic (inmsg, (void *)sa, + return xdr_to_generic (inmsg, (void *)sa, (xdrproc_t)xdr_setattr3args); } @@ -210,7 +211,7 @@ xdr_to_setattr3args (struct iovec inmsg, setattr3args *sa) ssize_t xdr_serialize_lookup3res (struct iovec outmsg, lookup3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_lookup3res); } @@ -218,7 +219,7 @@ xdr_serialize_lookup3res (struct iovec outmsg, lookup3res *res) ssize_t xdr_to_lookup3args (struct iovec inmsg, lookup3args *la) { - return nfs_xdr_to_generic (inmsg, (void *)la, + return xdr_to_generic (inmsg, (void *)la, (xdrproc_t)xdr_lookup3args); } @@ -226,7 +227,7 @@ xdr_to_lookup3args (struct iovec inmsg, lookup3args *la) ssize_t xdr_to_access3args (struct iovec inmsg, access3args *ac) { - return nfs_xdr_to_generic (inmsg,(void *)ac, + return xdr_to_generic (inmsg,(void *)ac, (xdrproc_t)xdr_access3args); } @@ -234,7 +235,7 @@ xdr_to_access3args (struct iovec inmsg, access3args *ac) ssize_t xdr_serialize_access3res (struct iovec outmsg, access3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_access3res); } @@ -242,7 +243,7 @@ xdr_serialize_access3res (struct iovec outmsg, access3res *res) ssize_t xdr_to_readlink3args (struct iovec inmsg, readlink3args *ra) { - return nfs_xdr_to_generic (inmsg, (void *)ra, + return xdr_to_generic (inmsg, (void *)ra, (xdrproc_t)xdr_readlink3args); } @@ -250,7 +251,7 @@ xdr_to_readlink3args (struct iovec inmsg, readlink3args *ra) ssize_t xdr_serialize_readlink3res (struct iovec outmsg, readlink3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_readlink3res); } @@ -258,21 +259,21 @@ xdr_serialize_readlink3res (struct iovec outmsg, readlink3res *res) ssize_t xdr_to_read3args (struct iovec inmsg, read3args *ra) { - return nfs_xdr_to_generic (inmsg, (void *)ra, (xdrproc_t)xdr_read3args); + return xdr_to_generic (inmsg, (void *)ra, (xdrproc_t)xdr_read3args); } ssize_t xdr_serialize_read3res (struct iovec outmsg, read3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_read3res); } ssize_t xdr_serialize_read3res_nocopy (struct iovec outmsg, read3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_read3res_nocopy); } @@ -280,7 +281,7 @@ xdr_serialize_read3res_nocopy (struct iovec outmsg, read3res *res) ssize_t xdr_to_write3args (struct iovec inmsg, write3args *wa) { - return nfs_xdr_to_generic (inmsg, (void *)wa,(xdrproc_t)xdr_write3args); + return xdr_to_generic (inmsg, (void *)wa,(xdrproc_t)xdr_write3args); } @@ -288,7 +289,7 @@ ssize_t xdr_to_write3args_nocopy (struct iovec inmsg, write3args *wa, struct iovec *payload) { - return nfs_xdr_to_generic_payload (inmsg, (void *)wa, + return xdr_to_generic_payload (inmsg, (void *)wa, (xdrproc_t)xdr_write3args, payload); } @@ -296,7 +297,7 @@ xdr_to_write3args_nocopy (struct iovec inmsg, write3args *wa, ssize_t xdr_serialize_write3res (struct iovec outmsg, write3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_write3res); } @@ -304,7 +305,7 @@ xdr_serialize_write3res (struct iovec outmsg, write3res *res) ssize_t xdr_to_create3args (struct iovec inmsg, create3args *ca) { - return nfs_xdr_to_generic (inmsg, (void *)ca, + return xdr_to_generic (inmsg, (void *)ca, (xdrproc_t)xdr_create3args); } @@ -312,7 +313,7 @@ xdr_to_create3args (struct iovec inmsg, create3args *ca) ssize_t xdr_serialize_create3res (struct iovec outmsg, create3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_create3res); } @@ -320,7 +321,7 @@ xdr_serialize_create3res (struct iovec outmsg, create3res *res) ssize_t xdr_serialize_mkdir3res (struct iovec outmsg, mkdir3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_mkdir3res); } @@ -328,7 +329,7 @@ xdr_serialize_mkdir3res (struct iovec outmsg, mkdir3res *res) ssize_t xdr_to_mkdir3args (struct iovec inmsg, mkdir3args *ma) { - return nfs_xdr_to_generic (inmsg, (void *)ma, + return xdr_to_generic (inmsg, (void *)ma, (xdrproc_t)xdr_mkdir3args); } @@ -336,7 +337,7 @@ xdr_to_mkdir3args (struct iovec inmsg, mkdir3args *ma) ssize_t xdr_to_symlink3args (struct iovec inmsg, symlink3args *sa) { - return nfs_xdr_to_generic (inmsg, (void *)sa, + return xdr_to_generic (inmsg, (void *)sa, (xdrproc_t)xdr_symlink3args); } @@ -344,7 +345,7 @@ xdr_to_symlink3args (struct iovec inmsg, symlink3args *sa) ssize_t xdr_serialize_symlink3res (struct iovec outmsg, symlink3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_symlink3res); } @@ -352,7 +353,7 @@ xdr_serialize_symlink3res (struct iovec outmsg, symlink3res *res) ssize_t xdr_to_mknod3args (struct iovec inmsg, mknod3args *ma) { - return nfs_xdr_to_generic (inmsg, (void *)ma, + return xdr_to_generic (inmsg, (void *)ma, (xdrproc_t)xdr_mknod3args); } @@ -360,7 +361,7 @@ xdr_to_mknod3args (struct iovec inmsg, mknod3args *ma) ssize_t xdr_serialize_mknod3res (struct iovec outmsg, mknod3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_mknod3res); } @@ -368,7 +369,7 @@ xdr_serialize_mknod3res (struct iovec outmsg, mknod3res *res) ssize_t xdr_to_remove3args (struct iovec inmsg, remove3args *ra) { - return nfs_xdr_to_generic (inmsg, (void *)ra, + return xdr_to_generic (inmsg, (void *)ra, (xdrproc_t)xdr_remove3args); } @@ -376,7 +377,7 @@ xdr_to_remove3args (struct iovec inmsg, remove3args *ra) ssize_t xdr_serialize_remove3res (struct iovec outmsg, remove3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_remove3res); } @@ -384,7 +385,7 @@ xdr_serialize_remove3res (struct iovec outmsg, remove3res *res) ssize_t xdr_to_rmdir3args (struct iovec inmsg, rmdir3args *ra) { - return nfs_xdr_to_generic (inmsg, (void *)ra, + return xdr_to_generic (inmsg, (void *)ra, (xdrproc_t)xdr_rmdir3args); } @@ -392,7 +393,7 @@ xdr_to_rmdir3args (struct iovec inmsg, rmdir3args *ra) ssize_t xdr_serialize_rmdir3res (struct iovec outmsg, rmdir3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_rmdir3res); } @@ -400,7 +401,7 @@ xdr_serialize_rmdir3res (struct iovec outmsg, rmdir3res *res) ssize_t xdr_serialize_rename3res (struct iovec outmsg, rename3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_rename3res); } @@ -408,7 +409,7 @@ xdr_serialize_rename3res (struct iovec outmsg, rename3res *res) ssize_t xdr_to_rename3args (struct iovec inmsg, rename3args *ra) { - return nfs_xdr_to_generic (inmsg, (void *)ra, + return xdr_to_generic (inmsg, (void *)ra, (xdrproc_t)xdr_rename3args); } @@ -416,7 +417,7 @@ xdr_to_rename3args (struct iovec inmsg, rename3args *ra) ssize_t xdr_serialize_link3res (struct iovec outmsg, link3res *li) { - return nfs_xdr_serialize_generic (outmsg, (void *)li, + return xdr_serialize_generic (outmsg, (void *)li, (xdrproc_t)xdr_link3res); } @@ -424,14 +425,14 @@ xdr_serialize_link3res (struct iovec outmsg, link3res *li) ssize_t xdr_to_link3args (struct iovec inmsg, link3args *la) { - return nfs_xdr_to_generic (inmsg, (void *)la, (xdrproc_t)xdr_link3args); + return xdr_to_generic (inmsg, (void *)la, (xdrproc_t)xdr_link3args); } ssize_t xdr_to_readdir3args (struct iovec inmsg, readdir3args *rd) { - return nfs_xdr_to_generic (inmsg, (void *)rd, + return xdr_to_generic (inmsg, (void *)rd, (xdrproc_t)xdr_readdir3args); } @@ -439,7 +440,7 @@ xdr_to_readdir3args (struct iovec inmsg, readdir3args *rd) ssize_t xdr_serialize_readdir3res (struct iovec outmsg, readdir3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_readdir3res); } @@ -447,7 +448,7 @@ xdr_serialize_readdir3res (struct iovec outmsg, readdir3res *res) ssize_t xdr_to_readdirp3args (struct iovec inmsg, readdirp3args *rp) { - return nfs_xdr_to_generic (inmsg, (void *)rp, + return xdr_to_generic (inmsg, (void *)rp, (xdrproc_t)xdr_readdirp3args); } @@ -455,7 +456,7 @@ xdr_to_readdirp3args (struct iovec inmsg, readdirp3args *rp) ssize_t xdr_serialize_readdirp3res (struct iovec outmsg, readdirp3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_readdirp3res); } @@ -463,7 +464,7 @@ xdr_serialize_readdirp3res (struct iovec outmsg, readdirp3res *res) ssize_t xdr_to_fsstat3args (struct iovec inmsg, fsstat3args *fa) { - return nfs_xdr_to_generic (inmsg, (void *)fa, + return xdr_to_generic (inmsg, (void *)fa, (xdrproc_t)xdr_fsstat3args); } @@ -471,14 +472,14 @@ xdr_to_fsstat3args (struct iovec inmsg, fsstat3args *fa) ssize_t xdr_serialize_fsstat3res (struct iovec outmsg, fsstat3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_fsstat3res); } ssize_t xdr_to_fsinfo3args (struct iovec inmsg, fsinfo3args *fi) { - return nfs_xdr_to_generic (inmsg, (void *)fi, + return xdr_to_generic (inmsg, (void *)fi, (xdrproc_t)xdr_fsinfo3args); } @@ -486,7 +487,7 @@ xdr_to_fsinfo3args (struct iovec inmsg, fsinfo3args *fi) ssize_t xdr_serialize_fsinfo3res (struct iovec outmsg, fsinfo3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_fsinfo3res); } @@ -494,14 +495,14 @@ xdr_serialize_fsinfo3res (struct iovec outmsg, fsinfo3res *res) ssize_t xdr_to_pathconf3args (struct iovec inmsg, pathconf3args *pc) { - return nfs_xdr_to_generic (inmsg, (void *)pc, + return xdr_to_generic (inmsg, (void *)pc, (xdrproc_t)xdr_pathconf3args);} ssize_t xdr_serialize_pathconf3res (struct iovec outmsg, pathconf3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_pathconf3res); } @@ -509,7 +510,7 @@ xdr_serialize_pathconf3res (struct iovec outmsg, pathconf3res *res) ssize_t xdr_to_commit3args (struct iovec inmsg, commit3args *ca) { - return nfs_xdr_to_generic (inmsg, (void *)ca, + return xdr_to_generic (inmsg, (void *)ca, (xdrproc_t)xdr_commit3args); } @@ -517,7 +518,7 @@ xdr_to_commit3args (struct iovec inmsg, commit3args *ca) ssize_t xdr_serialize_commit3res (struct iovec outmsg, commit3res *res) { - return nfs_xdr_serialize_generic (outmsg, (void *)res, + return xdr_serialize_generic (outmsg, (void *)res, (xdrproc_t)xdr_commit3res); } @@ -537,7 +538,7 @@ xdr_serialize_exports (struct iovec outmsg, exports *elist) if (!xdr_exports (&xdr, elist)) goto ret; - ret = nfs_xdr_decoded_length (xdr); + ret = xdr_decoded_length (xdr); ret: return ret; @@ -547,7 +548,7 @@ ret: ssize_t xdr_serialize_nfsstat3 (struct iovec outmsg, nfsstat3 *s) { - return nfs_xdr_serialize_generic (outmsg, (void *)s, + return xdr_serialize_generic (outmsg, (void *)s, (xdrproc_t)xdr_nfsstat3); } diff --git a/xlators/nfs/lib/src/msg-nfs3.h b/rpc/xdr/src/msg-nfs3.h index f0d57c64632..f0d57c64632 100644 --- a/xlators/nfs/lib/src/msg-nfs3.h +++ b/rpc/xdr/src/msg-nfs3.h diff --git a/rpc/xdr/src/xdr-generic.c b/rpc/xdr/src/xdr-generic.c index f7e09482b45..caea7e9ce0d 100644 --- a/rpc/xdr/src/xdr-generic.c +++ b/rpc/xdr/src/xdr-generic.c @@ -96,3 +96,39 @@ xdr_to_generic_payload (struct iovec inmsg, void *args, xdrproc_t proc, ret: return ret; } + +ssize_t +xdr_length_round_up (size_t len, size_t bufsize) +{ + int roundup = 0; + + roundup = len % XDR_BYTES_PER_UNIT; + if (roundup > 0) + roundup = XDR_BYTES_PER_UNIT - roundup; + + if ((roundup > 0) && ((roundup + len) <= bufsize)) + len += roundup; + + return len; +} + +int +xdr_bytes_round_up (struct iovec *vec, size_t bufsize) +{ + vec->iov_len = xdr_length_round_up (vec->iov_len, bufsize); + return 0; +} + + +void +xdr_vector_round_up (struct iovec *vec, int vcount, uint32_t count) +{ + uint32_t round_count = 0; + + round_count = xdr_length_round_up (count, 1048576); + round_count -= count; + if (round_count == 0) + return; + + vec[vcount-1].iov_len += round_count; +} diff --git a/rpc/xdr/src/xdr-generic.h b/rpc/xdr/src/xdr-generic.h index 9b8019637e3..963c6185b69 100644 --- a/rpc/xdr/src/xdr-generic.h +++ b/rpc/xdr/src/xdr-generic.h @@ -31,6 +31,7 @@ #define xdr_encoded_length(xdr) (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base)) #define xdr_decoded_length(xdr) (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base)) +#define XDR_BYTES_PER_UNIT 4 ssize_t xdr_serialize_generic (struct iovec outmsg, void *res, xdrproc_t proc); @@ -42,4 +43,14 @@ ssize_t xdr_to_generic_payload (struct iovec inmsg, void *args, xdrproc_t proc, struct iovec *pendingpayload); + +extern int +xdr_bytes_round_up (struct iovec *vec, size_t bufsize); + +extern ssize_t +xdr_length_round_up (size_t len, size_t bufsize); + +void +xdr_vector_round_up (struct iovec *vec, int vcount, uint32_t count); + #endif /* !_XDR_GENERIC_H */ diff --git a/xlators/nfs/lib/src/xdr-nfs3.c b/rpc/xdr/src/xdr-nfs3.c index febc6a69597..febc6a69597 100644 --- a/xlators/nfs/lib/src/xdr-nfs3.c +++ b/rpc/xdr/src/xdr-nfs3.c diff --git a/xlators/nfs/lib/src/xdr-nfs3.h b/rpc/xdr/src/xdr-nfs3.h index 0530876a8de..0530876a8de 100644 --- a/xlators/nfs/lib/src/xdr-nfs3.h +++ b/rpc/xdr/src/xdr-nfs3.h diff --git a/xlators/nfs/lib/src/auth-null.c b/xlators/nfs/lib/src/auth-null.c deleted file mode 100644 index 0c8e335dba9..00000000000 --- a/xlators/nfs/lib/src/auth-null.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "rpcsvc.h" -#include "list.h" -#include "dict.h" - - -int -nfs_auth_null_request_init (rpcsvc_request_t *req, void *priv) -{ - if (!req) - return -1; - - memset (req->cred.authdata, 0, RPCSVC_MAX_AUTH_BYTES); - req->cred.datalen = 0; - - memset (req->verf.authdata, 0, RPCSVC_MAX_AUTH_BYTES); - req->verf.datalen = 0; - - return 0; -} - -int -nfs_auth_null_authenticate (rpcsvc_request_t *req, void *priv) -{ - /* Always succeed. */ - return RPCSVC_AUTH_ACCEPT; -} - -rpcsvc_auth_ops_t nfs_auth_null_ops = { - .conn_init = NULL, - .request_init = nfs_auth_null_request_init, - .authenticate = nfs_auth_null_authenticate -}; - -rpcsvc_auth_t nfs_rpcsvc_auth_null = { - .authname = "AUTH_NULL", - .authnum = AUTH_NULL, - .authops = &nfs_auth_null_ops, - .authprivate = NULL -}; - - -rpcsvc_auth_t * -nfs_rpcsvc_auth_null_init (rpcsvc_t *svc, dict_t *options) -{ - return &nfs_rpcsvc_auth_null; -} - diff --git a/xlators/nfs/lib/src/auth-unix.c b/xlators/nfs/lib/src/auth-unix.c deleted file mode 100644 index 50ca381ec85..00000000000 --- a/xlators/nfs/lib/src/auth-unix.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - - - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "rpcsvc.h" -#include "list.h" -#include "dict.h" -#include "xdr-rpc.h" - - -int -nfs_auth_unix_request_init (rpcsvc_request_t *req, void *priv) -{ - if (!req) - return -1; - memset (req->verf.authdata, 0, RPCSVC_MAX_AUTH_BYTES); - req->verf.datalen = 0; - req->verf.flavour = AUTH_NULL; - - return 0; -} - -int -nfs_auth_unix_authenticate (rpcsvc_request_t *req, void *priv) -{ - int ret = RPCSVC_AUTH_REJECT; - struct authunix_parms aup; - char machname[MAX_MACHINE_NAME]; - - if (!req) - return ret; - - ret = nfs_xdr_to_auth_unix_cred (req->cred.authdata, req->cred.datalen, - &aup, machname, req->auxgids); - if (ret == -1) { - ret = RPCSVC_AUTH_REJECT; - goto err; - } - - if (aup.aup_len > 16) { - ret = RPCSVC_AUTH_REJECT; - goto err; - } - - req->uid = aup.aup_uid; - req->gid = aup.aup_gid; - req->auxgidcount = aup.aup_len; - - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Auth Info: machine name: %s, uid: %d" - ", gid: %d", machname, req->uid, req->gid); - ret = RPCSVC_AUTH_ACCEPT; -err: - return ret; -} - -rpcsvc_auth_ops_t nfs_auth_unix_ops = { - .conn_init = NULL, - .request_init = nfs_auth_unix_request_init, - .authenticate = nfs_auth_unix_authenticate -}; - -rpcsvc_auth_t nfs_rpcsvc_auth_unix = { - .authname = "AUTH_UNIX", - .authnum = AUTH_UNIX, - .authops = &nfs_auth_unix_ops, - .authprivate = NULL -}; - - -rpcsvc_auth_t * -nfs_rpcsvc_auth_unix_init (rpcsvc_t *svc, dict_t *options) -{ - return &nfs_rpcsvc_auth_unix; -} - diff --git a/xlators/nfs/lib/src/rpc-socket.c b/xlators/nfs/lib/src/rpc-socket.c deleted file mode 100644 index d2b4bfeb2f0..00000000000 --- a/xlators/nfs/lib/src/rpc-socket.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "rpc-socket.h" -#include "rpcsvc.h" -#include "dict.h" -#include "logging.h" -#include "byte-order.h" -#include "common-utils.h" -#include "compat-errno.h" - -#include <fcntl.h> -#include <errno.h> -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#include <netinet/tcp.h> - -#ifndef AI_ADDRCONFIG -#define AI_ADDRCONFIG 0 -#endif /* AI_ADDRCONFIG */ - -static int -nfs_rpcsvc_socket_server_get_local_socket (int addrfam, char *listenhost, - uint16_t listenport, - struct sockaddr *addr, - socklen_t *addr_len) -{ - struct addrinfo hints, *res = 0; - char service[NI_MAXSERV]; - int ret = -1; - - memset (service, 0, sizeof (service)); - sprintf (service, "%d", listenport); - - memset (&hints, 0, sizeof (hints)); - addr->sa_family = hints.ai_family = addrfam; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; - - ret = getaddrinfo(listenhost, service, &hints, &res); - if (ret != 0) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, - "getaddrinfo failed for host %s, service %s (%s)", - listenhost, service, gai_strerror (ret)); - ret = -1; - goto err; - } - - memcpy (addr, res->ai_addr, res->ai_addrlen); - *addr_len = res->ai_addrlen; - - freeaddrinfo (res); - ret = 0; - -err: - return ret; -} - - -int -nfs_rpcsvc_socket_listen (int addrfam, char *listenhost, uint16_t listenport) -{ - int sock = -1; - socklen_t sockaddr_len; - int flags = 0; - int ret = -1; - int opt = 1; - union gf_sock_union sock_union; - - ret = nfs_rpcsvc_socket_server_get_local_socket (addrfam, listenhost, - listenport, - &sock_union.sa, - &sockaddr_len); - - if (ret == -1) - return ret; - - sock = socket (sock_union.sa.sa_family, SOCK_STREAM, 0); - if (sock == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "socket creation failed" - " (%s)", strerror (errno)); - goto err; - } - - flags = fcntl (sock, F_GETFL); - if (flags == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "cannot get socket flags" - " (%s)", strerror(errno)); - goto close_err; - } - - ret = fcntl (sock, F_SETFL, flags | O_NONBLOCK); - if (ret == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "cannot set socket " - "non-blocking (%s)", strerror (errno)); - goto close_err; - } - - ret = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); - if (ret == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "setsockopt() for " - "SO_REUSEADDR failed (%s)", strerror (errno)); - goto close_err; - } - - ret = bind (sock, &sock_union.sa, sockaddr_len); - if (ret == -1) { - if (errno != EADDRINUSE) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "binding socket " - "failed: %s", strerror (errno)); - goto close_err; - } - } - - ret = listen (sock, 10); - if (ret == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "could not listen on" - " socket (%s)", strerror (errno)); - goto close_err; - } - - return sock; - -close_err: - close (sock); - sock = -1; - -err: - return sock; -} - - -int -nfs_rpcsvc_socket_accept (int listenfd) -{ - int new_sock = -1; - struct sockaddr_storage new_sockaddr = {0, }; - socklen_t addrlen = sizeof (new_sockaddr); - int flags = 0; - int ret = -1; - int on = 1; - - new_sock = accept (listenfd, SA (&new_sockaddr), &addrlen); - if (new_sock == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR,"accept on socket failed"); - goto err; - } - - flags = fcntl (new_sock, F_GETFL); - if (flags == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "cannot get socket flags" - " (%s)", strerror(errno)); - goto close_err; - } - - ret = fcntl (new_sock, F_SETFL, flags | O_NONBLOCK); - if (ret == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "cannot set socket " - "non-blocking (%s)", strerror (errno)); - goto close_err; - } - -#ifdef TCP_NODELAY - ret = setsockopt(new_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)); - if (ret == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "cannot set no-delay " - " socket option"); - } -#endif - - return new_sock; - -close_err: - close (new_sock); - new_sock = -1; - -err: - return new_sock; -} - -ssize_t -nfs_rpcsvc_socket_read (int sockfd, char *readaddr, size_t readsize) -{ - ssize_t dataread = 0; - ssize_t readlen = -1; - - if (!readaddr) - return -1; - - while (readsize > 0) { - readlen = read (sockfd, readaddr, readsize); - if (readlen == -1) { - if (errno != EAGAIN) { - dataread = -1; - break; - } else - break; - } else if (readlen == 0) - break; - - dataread += readlen; - readaddr += readlen; - readsize -= readlen; - } - - return dataread; -} - - -ssize_t -nfs_rpcsvc_socket_write (int sockfd, char *buffer, size_t size, int *eagain) -{ - size_t writelen = -1; - ssize_t written = 0; - - if (!buffer) - return -1; - - while (size > 0) { - writelen = write (sockfd, buffer, size); - if (writelen == -1) { - if (errno != EAGAIN) { - written = -1; - break; - } else { - *eagain = 1; - break; - } - } else if (writelen == 0) - break; - - written += writelen; - size -= writelen; - buffer += writelen; - } - - return written; -} - - -int -nfs_rpcsvc_socket_peername (int sockfd, char *hostname, int hostlen) -{ - struct sockaddr sa; - socklen_t sl = sizeof (sa); - int ret = EAI_FAIL; - - if (!hostname) - return ret; - - ret = getpeername (sockfd, &sa, &sl); - if (ret == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "Failed to get peer name:" - " %s", strerror (errno)); - ret = EAI_FAIL; - goto err; - } - - ret = getnameinfo (&sa, sl, hostname, hostlen, NULL, 0, 0); - if (ret != 0) - goto err; - -err: - return ret; -} - - -int -nfs_rpcsvc_socket_peeraddr (int sockfd, char *addrstr, int addrlen, - struct sockaddr *returnsa, socklen_t sasize) -{ - struct sockaddr sa; - int ret = EAI_FAIL; - - if (returnsa) - ret = getpeername (sockfd, returnsa, &sasize); - else { - sasize = sizeof (sa); - ret = getpeername (sockfd, &sa, &sasize); - } - - if (ret == -1) { - gf_log (GF_RPCSVC_SOCK, GF_LOG_ERROR, "Failed to get peer addr:" - " %s", strerror (errno)); - ret = EAI_FAIL; - goto err; - } - - /* If caller did not specify a string into which the address can be - * stored, dont bother getting it. - */ - if (!addrstr) { - ret = 0; - goto err; - } - - if (returnsa) - ret = getnameinfo (returnsa, sasize, addrstr, addrlen, NULL, 0, - NI_NUMERICHOST); - else - ret = getnameinfo (&sa, sasize, addrstr, addrlen, NULL, 0, - NI_NUMERICHOST); - -err: - return ret; -} - - -int -nfs_rpcsvc_socket_block_tx (int sockfd) -{ - - int ret = -1; - int on = 1; - -#ifdef TCP_CORK - ret = setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, &on, sizeof(on)); -#endif - -#ifdef TCP_NOPUSH - ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, &on, sizeof(on)); -#endif - - return ret; -} - - -int -nfs_rpcsvc_socket_unblock_tx (int sockfd) -{ - int ret = -1; - int off = 0; - -#ifdef TCP_CORK - ret = setsockopt(sockfd, IPPROTO_TCP, TCP_CORK, &off, sizeof(off)); -#endif - -#ifdef TCP_NOPUSH - ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NOPUSH, &off, sizeof(off)); -#endif - return ret; -} - diff --git a/xlators/nfs/lib/src/rpc-socket.h b/xlators/nfs/lib/src/rpc-socket.h deleted file mode 100644 index 8662df0a741..00000000000 --- a/xlators/nfs/lib/src/rpc-socket.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - -#ifndef _NFS_RPCSVC_SOCKET_H_ -#define _NFS_RPCSVC_SOCKET_H_ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "rpcsvc.h" -#include "dict.h" -#include "logging.h" -#include "byte-order.h" -#include "common-utils.h" -#include "compat-errno.h" - -#include <fcntl.h> -#include <errno.h> -#include <sys/socket.h> -#include <netdb.h> - -#define SA(ptr) ((struct sockaddr *)ptr) -#define GF_RPCSVC_SOCK "rpc-socket" -extern int -nfs_rpcsvc_socket_listen (int addrfam, char *listenhost, uint16_t listenport); - -extern int -nfs_rpcsvc_socket_accept (int listenfd); - -extern ssize_t -nfs_rpcsvc_socket_read (int sockfd, char *readaddr, size_t readsize); - -extern ssize_t -nfs_rpcsvc_socket_write (int sockfd, char *buffer, size_t size, int *eagain); - -extern int -nfs_rpcsvc_socket_peername (int sockfd, char *hostname, int hostlen); - -extern int -nfs_rpcsvc_socket_peeraddr (int sockfd, char *addrstr, int addrlen, - struct sockaddr *returnsa, socklen_t sasize); -extern int -nfs_rpcsvc_socket_block_tx (int sockfd); - -extern int -nfs_rpcsvc_socket_unblock_tx (int sockfd); -#endif diff --git a/xlators/nfs/lib/src/rpcsvc-auth.c b/xlators/nfs/lib/src/rpcsvc-auth.c deleted file mode 100644 index 6c8d30ec009..00000000000 --- a/xlators/nfs/lib/src/rpcsvc-auth.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - -#include "rpcsvc.h" -#include "logging.h" -#include "dict.h" - -extern rpcsvc_auth_t * -nfs_rpcsvc_auth_null_init (rpcsvc_t *svc, dict_t *options); - -extern rpcsvc_auth_t * -nfs_rpcsvc_auth_unix_init (rpcsvc_t *svc, dict_t *options); - -int -nfs_rpcsvc_auth_add_initer (struct list_head *list, char *idfier, - rpcsvc_auth_initer_t init) -{ - struct rpcsvc_auth_list *new = NULL; - - if ((!list) || (!init) || (!idfier)) - return -1; - - new = GF_CALLOC (1, sizeof (*new), gf_common_mt_rpcsvc_auth_list); - if (!new) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Memory allocation failed"); - return -1; - } - - new->init = init; - strcpy (new->name, idfier); - INIT_LIST_HEAD (&new->authlist); - list_add_tail (&new->authlist, list); - return 0; -} - - - -int -nfs_rpcsvc_auth_add_initers (rpcsvc_t *svc) -{ - int ret = -1; - - ret = nfs_rpcsvc_auth_add_initer (&svc->authschemes, "auth-null", - (rpcsvc_auth_initer_t) - nfs_rpcsvc_auth_null_init); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to add AUTH_NULL"); - goto err; - } - - ret = nfs_rpcsvc_auth_add_initer (&svc->authschemes, "auth-unix", - (rpcsvc_auth_initer_t) - nfs_rpcsvc_auth_unix_init); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to add AUTH_UNIX"); - goto err; - } - -err: - return ret; -} - - -int -nfs_rpcsvc_auth_init_auth (rpcsvc_t *svc, dict_t *options, - struct rpcsvc_auth_list *authitem) -{ - int ret = -1; - - if ((!svc) || (!options) || (!authitem)) - return -1; - - if (!authitem->init) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "No init function defined"); - ret = -1; - goto err; - } - - authitem->auth = authitem->init (svc, options); - if (!authitem->auth) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Registration of auth failed:" - " %s", authitem->name); - ret = -1; - goto err; - } - - authitem->enable = 1; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Authentication enabled: %s", - authitem->auth->authname); - - ret = 0; -err: - return ret; -} - - -int -nfs_rpcsvc_auth_init_auths (rpcsvc_t *svc, dict_t *options) -{ - int ret = -1; - struct rpcsvc_auth_list *auth = NULL; - struct rpcsvc_auth_list *tmp = NULL; - - if (!svc) - return -1; - - if (list_empty (&svc->authschemes)) { - gf_log (GF_RPCSVC, GF_LOG_WARNING, "No authentication!"); - ret = 0; - goto err; - } - - /* If auth null and sys are not disabled by the user, we must enable - * it by default. This is a globally default rule, the user is still - * allowed to disable the two for particular subvolumes. - */ - if (!dict_get (options, "rpc-auth.auth-null")) { - ret = dict_set_dynstr (options, "rpc-auth.auth-null", "on"); - if (ret < 0) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, - "Failed to set dict value."); - goto err; - } - } - - if (!dict_get (options, "rpc-auth.auth-unix")) { - ret = dict_set_dynstr (options, "rpc-auth.auth-unix", "on"); - if (ret < 0) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, - "Failed to set dict value."); - goto err; - } - } - - list_for_each_entry_safe (auth, tmp, &svc->authschemes, authlist) { - ret = nfs_rpcsvc_auth_init_auth (svc, options, auth); - if (ret == -1) - goto err; - } - - ret = 0; -err: - return ret; - -} - -int -nfs_rpcsvc_auth_init (rpcsvc_t *svc, dict_t *options) -{ - int ret = -1; - - if ((!svc) || (!options)) - return -1; - - ret = nfs_rpcsvc_auth_add_initers (svc); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to add initers"); - goto out; - } - - ret = nfs_rpcsvc_auth_init_auths (svc, options); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to init auth schemes"); - goto out; - } - -out: - return ret; -} - - -rpcsvc_auth_t * -__nfs_rpcsvc_auth_get_handler (rpcsvc_request_t *req) -{ - struct rpcsvc_auth_list *auth = NULL; - struct rpcsvc_auth_list *tmp = NULL; - rpcsvc_t *svc = NULL; - - if (!req) - return NULL; - - svc = nfs_rpcsvc_request_service (req); - if (list_empty (&svc->authschemes)) { - gf_log (GF_RPCSVC, GF_LOG_WARNING, "No authentication!"); - goto err; - } - - list_for_each_entry_safe (auth, tmp, &svc->authschemes, authlist) { - if (!auth->enable) - continue; - if (auth->auth->authnum == req->cred.flavour) - goto err; - - } - - auth = NULL; -err: - if (auth) - return auth->auth; - else - return NULL; -} - -rpcsvc_auth_t * -nfs_rpcsvc_auth_get_handler (rpcsvc_request_t *req) -{ - rpcsvc_auth_t *auth = NULL; - - auth = __nfs_rpcsvc_auth_get_handler (req); - if (auth) - goto ret; - - gf_log (GF_RPCSVC, GF_LOG_TRACE, "No auth handler: %d", - req->cred.flavour); - - /* The requested scheme was not available so fall back the to one - * scheme that will always be present. - */ - req->cred.flavour = AUTH_NULL; - req->verf.flavour = AUTH_NULL; - auth = __nfs_rpcsvc_auth_get_handler (req); -ret: - return auth; -} - - -int -nfs_rpcsvc_auth_request_init (rpcsvc_request_t *req) -{ - int ret = -1; - rpcsvc_auth_t *auth = NULL; - - if (!req) - return -1; - - auth = nfs_rpcsvc_auth_get_handler (req); - if (!auth) - goto err; - ret = 0; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Auth handler: %s", auth->authname); - if (!auth->authops->request_init) - ret = auth->authops->request_init (req, auth->authprivate); - -err: - return ret; -} - - -int -nfs_rpcsvc_authenticate (rpcsvc_request_t *req) -{ - int ret = RPCSVC_AUTH_REJECT; - rpcsvc_auth_t *auth = NULL; - int minauth = 0; - - if (!req) - return ret; - - minauth = nfs_rpcsvc_request_prog_minauth (req); - if (minauth > nfs_rpcsvc_request_cred_flavour (req)) { - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Auth too weak"); - nfs_rpcsvc_request_set_autherr (req, AUTH_TOOWEAK); - goto err; - } - - auth = nfs_rpcsvc_auth_get_handler (req); - if (!auth) { - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "No auth handler found"); - goto err; - } - - if (auth->authops->authenticate) - ret = auth->authops->authenticate (req, auth->authprivate); - -err: - return ret; -} - - -int -nfs_rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen) -{ - int count = 0; - int gen = RPCSVC_AUTH_REJECT; - int spec = RPCSVC_AUTH_REJECT; - int final = RPCSVC_AUTH_REJECT; - char *srchstr = NULL; - char *valstr = NULL; - gf_boolean_t boolval = _gf_false; - int ret = 0; - - struct rpcsvc_auth_list *auth = NULL; - struct rpcsvc_auth_list *tmp = NULL; - - if ((!svc) || (!autharr) || (!volname)) - return -1; - - memset (autharr, 0, arrlen * sizeof(int)); - if (list_empty (&svc->authschemes)) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "No authentication!"); - goto err; - } - - list_for_each_entry_safe (auth, tmp, &svc->authschemes, authlist) { - if (count >= arrlen) - break; - - gen = gf_asprintf (&srchstr, "rpc-auth.%s", auth->name); - if (gen == -1) { - count = -1; - goto err; - } - - gen = RPCSVC_AUTH_REJECT; - if (dict_get (svc->options, srchstr)) { - ret = dict_get_str (svc->options, srchstr, &valstr); - if (ret == 0) { - ret = gf_string2boolean (valstr, &boolval); - if (ret == 0) { - if (boolval == _gf_true) - gen = RPCSVC_AUTH_ACCEPT; - } else - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile" - "d to read auth val"); - } else - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile" - "d to read auth val"); - } - - GF_FREE (srchstr); - spec = gf_asprintf (&srchstr, "rpc-auth.%s.%s", auth->name, - volname); - if (spec == -1) { - count = -1; - goto err; - } - - spec = RPCSVC_AUTH_DONTCARE; - if (dict_get (svc->options, srchstr)) { - ret = dict_get_str (svc->options, srchstr, &valstr); - if (ret == 0) { - ret = gf_string2boolean (valstr, &boolval); - if (ret == 0) { - if (boolval == _gf_true) - spec = RPCSVC_AUTH_ACCEPT; - else - spec = RPCSVC_AUTH_REJECT; - } else - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile" - "d to read auth val"); - } else - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Faile" - "d to read auth val"); - } - - GF_FREE (srchstr); - final = nfs_rpcsvc_combine_gen_spec_volume_checks (gen, spec); - if (final == RPCSVC_AUTH_ACCEPT) { - autharr[count] = auth->auth->authnum; - ++count; - } - } - -err: - return count; -} - - -gid_t * -nfs_rpcsvc_auth_unix_auxgids (rpcsvc_request_t *req, int *arrlen) -{ - if ((!req) || (!arrlen)) - return NULL; - - if (req->cred.flavour != AUTH_UNIX) - return NULL; - - *arrlen = req->auxgidcount; - if (*arrlen == 0) - return NULL; - - return &req->auxgids[0]; -} - diff --git a/xlators/nfs/lib/src/rpcsvc.c b/xlators/nfs/lib/src/rpcsvc.c deleted file mode 100644 index 0831cf49ab6..00000000000 --- a/xlators/nfs/lib/src/rpcsvc.c +++ /dev/null @@ -1,2923 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "rpcsvc.h" -#include "rpc-socket.h" -#include "dict.h" -#include "logging.h" -#include "byte-order.h" -#include "common-utils.h" -#include "compat-errno.h" -#include "list.h" -#include "xdr-rpc.h" -#include "iobuf.h" -#include "globals.h" - -#include <errno.h> -#include <pthread.h> -#include <stdlib.h> -#include <rpc/rpc.h> -#include <rpc/pmap_clnt.h> -#include <arpa/inet.h> -#include <rpc/xdr.h> -#include <fnmatch.h> -#include <stdarg.h> -#include <stdio.h> - - -#define nfs_rpcsvc_alloc_request(con, request) \ - do { \ - request = (rpcsvc_request_t *) mem_get ((con)->rxpool); \ - memset (request, 0, sizeof (rpcsvc_request_t)); \ - } while (0) \ - -/* The generic event handler for every stage */ -void * -nfs_rpcsvc_stage_proc (void *arg) -{ - rpcsvc_stage_t *stg = (rpcsvc_stage_t *)arg; - - if (!stg) - return NULL; - - event_dispatch (stg->eventpool); - return NULL; -} - - -rpcsvc_stage_t * -nfs_rpcsvc_stage_init (rpcsvc_t *svc) -{ - rpcsvc_stage_t *stg = NULL; - int ret = -1; - size_t stacksize = RPCSVC_THREAD_STACK_SIZE; - pthread_attr_t stgattr; - unsigned int eventpoolsize = 0; - - if (!svc) - return NULL; - - stg = GF_CALLOC (1, sizeof(*stg), gf_common_mt_rpcsvc_stage_t); - if (!stg) - return NULL; - - eventpoolsize = svc->memfactor * RPCSVC_EVENTPOOL_SIZE_MULT; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "event pool size: %d", eventpoolsize); - stg->eventpool = event_pool_new (eventpoolsize); - if (!stg->eventpool) - goto free_stg; - - pthread_attr_init (&stgattr); - ret = pthread_attr_setstacksize (&stgattr, stacksize); - if (ret == EINVAL) - gf_log (GF_RPCSVC, GF_LOG_WARNING, - "Using default thread stack size"); - - ret = pthread_create (&stg->tid, &stgattr, nfs_rpcsvc_stage_proc, - (void *)stg); - if (ret != 0) { - ret = -1; - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Stage creation failed"); - goto free_stg; - } - - stg->svc = svc; - ret = 0; -free_stg: - if (ret == -1) { - GF_FREE (stg); - stg = NULL; - } - - return stg; -} - - -int -nfs_rpcsvc_init_options (rpcsvc_t *svc, dict_t *options) -{ - char *optstr = NULL; - int ret = -1; - - if ((!svc) || (!options)) - return -1; - - svc->memfactor = RPCSVC_DEFAULT_MEMFACTOR; - - svc->register_portmap = _gf_true; - if (dict_get (options, "rpc.register-with-portmap")) { - ret = dict_get_str (options, "rpc.register-with-portmap", - &optstr); - if (ret < 0) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to parse " - "dict"); - goto out; - } - - ret = gf_string2boolean (optstr, &svc->register_portmap); - if (ret < 0) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to parse bool " - "string"); - goto out; - } - } - - if (!svc->register_portmap) - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Portmap registration " - "disabled"); - - ret = 0; -out: - return ret; -} - - -/* The global RPC service initializer. - * Starts up the stages and then waits for RPC program registrations - * to come in. - */ -rpcsvc_t * -nfs_rpcsvc_init (glusterfs_ctx_t *ctx, dict_t *options) -{ - rpcsvc_t *svc = NULL; - int ret = -1; - - if ((!ctx) || (!options)) - return NULL; - - svc = GF_CALLOC (1, sizeof (*svc), gf_common_mt_rpcsvc_t); - if (!svc) - return NULL; - - pthread_mutex_init (&svc->rpclock, NULL); - INIT_LIST_HEAD (&svc->stages); - INIT_LIST_HEAD (&svc->authschemes); - INIT_LIST_HEAD (&svc->allprograms); - - ret = nfs_rpcsvc_init_options (svc, options); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to init options"); - goto free_svc; - } - - ret = nfs_rpcsvc_auth_init (svc, options); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to init " - "authentication"); - goto free_svc; - } - - ret = -1; - svc->defaultstage = nfs_rpcsvc_stage_init (svc); - if (!svc->defaultstage) { - gf_log (GF_RPCSVC, GF_LOG_ERROR,"RPC service init failed."); - goto free_svc; - } - svc->options = options; - svc->ctx = ctx; - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC service inited."); - - ret = 0; -free_svc: - if (ret == -1) { - GF_FREE (svc); - svc = NULL; - } - - return svc; -} - - -/* Once multi-threaded support is complete, we'll be able to round-robin - * the various incoming connections over the many available stages. This - * function selects one from among all the stages. - */ -rpcsvc_stage_t * -nfs_rpcsvc_select_stage (rpcsvc_t *rpcservice) -{ - if (!rpcservice) - return NULL; - - return rpcservice->defaultstage; -} - - -int -nfs_rpcsvc_conn_peer_check_search (dict_t *options, char *pattern, char *clstr) -{ - int ret = -1; - char *addrtok = NULL; - char *addrstr = NULL; - char *svptr = NULL; - - if ((!options) || (!clstr)) - return -1; - - if (!dict_get (options, pattern)) - return -1; - - ret = dict_get_str (options, pattern, &addrstr); - if (ret < 0) { - ret = -1; - goto err; - } - - if (!addrstr) { - ret = -1; - goto err; - } - - addrtok = strtok_r (addrstr, ",", &svptr); - while (addrtok) { - - /* CASEFOLD not present on Solaris */ -#ifdef FNM_CASEFOLD - ret = fnmatch (addrtok, clstr, FNM_CASEFOLD); -#else - ret = fnmatch (addrtok, clstr, 0); -#endif - if (ret == 0) - goto err; - - addrtok = strtok_r (NULL, ",", &svptr); - } - - ret = -1; -err: - - return ret; -} - - -int -nfs_rpcsvc_conn_peer_check_allow (dict_t *options, char *volname, char *clstr) -{ - int ret = RPCSVC_AUTH_DONTCARE; - char *srchstr = NULL; - char globalrule[] = "rpc-auth.addr.allow"; - - if ((!options) || (!clstr)) - return ret; - - /* If volname is NULL, then we're searching for the general rule to - * determine the current address in clstr is allowed or not for all - * subvolumes. - */ - if (volname) { - ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.allow", volname); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed"); - ret = RPCSVC_AUTH_DONTCARE; - goto out; - } - } else - srchstr = globalrule; - - ret = nfs_rpcsvc_conn_peer_check_search (options, srchstr, clstr); - if (volname) - GF_FREE (srchstr); - - if (ret == 0) - ret = RPCSVC_AUTH_ACCEPT; - else - ret = RPCSVC_AUTH_DONTCARE; -out: - return ret; -} - -int -nfs_rpcsvc_conn_peer_check_reject (dict_t *options, char *volname, char *clstr) -{ - int ret = RPCSVC_AUTH_DONTCARE; - char *srchstr = NULL; - char generalrule[] = "rpc-auth.addr.reject"; - - if ((!options) || (!clstr)) - return ret; - - if (volname) { - ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.reject", - volname); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed"); - ret = RPCSVC_AUTH_REJECT; - goto out; - } - } else - srchstr = generalrule; - - ret = nfs_rpcsvc_conn_peer_check_search (options, srchstr, clstr); - if (volname) - GF_FREE (srchstr); - - if (ret == 0) - ret = RPCSVC_AUTH_REJECT; - else - ret = RPCSVC_AUTH_DONTCARE; -out: - return ret; -} - - -/* This function tests the results of the allow rule and the reject rule to - * combine them into a single result that can be used to determine if the - * connection should be allowed to proceed. - * Heres the test matrix we need to follow in this function. - * - * A - Allow, the result of the allow test. Never returns R. - * R - Reject, result of the reject test. Never returns A. - * Both can return D or dont care if no rule was given. - * - * | @allow | @reject | Result | - * | A | R | R | - * | D | D | D | - * | A | D | A | - * | D | R | R | - */ -int -nfs_rpcsvc_combine_allow_reject_volume_check (int allow, int reject) -{ - int final = RPCSVC_AUTH_REJECT; - - /* If allowed rule allows but reject rule rejects, we stay cautious - * and reject. */ - if ((allow == RPCSVC_AUTH_ACCEPT) && (reject == RPCSVC_AUTH_REJECT)) - final = RPCSVC_AUTH_REJECT; - /* if both are dont care, that is user did not specify for either allow - * or reject, we leave it up to the general rule to apply, in the hope - * that there is one. - */ - else if ((allow == RPCSVC_AUTH_DONTCARE) && - (reject == RPCSVC_AUTH_DONTCARE)) - final = RPCSVC_AUTH_DONTCARE; - /* If one is dont care, the other one applies. */ - else if ((allow == RPCSVC_AUTH_ACCEPT) && - (reject == RPCSVC_AUTH_DONTCARE)) - final = RPCSVC_AUTH_ACCEPT; - else if ((allow == RPCSVC_AUTH_DONTCARE) && - (reject == RPCSVC_AUTH_REJECT)) - final = RPCSVC_AUTH_REJECT; - - return final; -} - - -/* Combines the result of the general rule test against, the specific rule - * to determine final permission for the client's address. - * - * | @gen | @spec | Result | - * | A | A | A | - * | A | R | R | - * | A | D | A | - * | D | A | A | - * | D | R | R | - * | D | D | D | - * | R | A | A | - * | R | D | R | - * | R | R | R | - */ -int -nfs_rpcsvc_combine_gen_spec_addr_checks (int gen, int spec) -{ - int final = RPCSVC_AUTH_REJECT; - - if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_ACCEPT)) - final = RPCSVC_AUTH_ACCEPT; - else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_REJECT)) - final = RPCSVC_AUTH_REJECT; - else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_DONTCARE)) - final = RPCSVC_AUTH_ACCEPT; - else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_ACCEPT)) - final = RPCSVC_AUTH_ACCEPT; - else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_REJECT)) - final = RPCSVC_AUTH_REJECT; - else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec== RPCSVC_AUTH_DONTCARE)) - final = RPCSVC_AUTH_DONTCARE; - else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_ACCEPT)) - final = RPCSVC_AUTH_ACCEPT; - else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_DONTCARE)) - final = RPCSVC_AUTH_REJECT; - else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_REJECT)) - final = RPCSVC_AUTH_REJECT; - - return final; -} - - - -/* Combines the result of the general rule test against, the specific rule - * to determine final test for the connection coming in for a given volume. - * - * | @gen | @spec | Result | - * | A | A | A | - * | A | R | R | - * | A | D | A | - * | D | A | A | - * | D | R | R | - * | D | D | R |, special case, we intentionally disallow this. - * | R | A | A | - * | R | D | R | - * | R | R | R | - */ -int -nfs_rpcsvc_combine_gen_spec_volume_checks (int gen, int spec) -{ - int final = RPCSVC_AUTH_REJECT; - - if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_ACCEPT)) - final = RPCSVC_AUTH_ACCEPT; - else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_REJECT)) - final = RPCSVC_AUTH_REJECT; - else if ((gen == RPCSVC_AUTH_ACCEPT) && (spec == RPCSVC_AUTH_DONTCARE)) - final = RPCSVC_AUTH_ACCEPT; - else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_ACCEPT)) - final = RPCSVC_AUTH_ACCEPT; - else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec == RPCSVC_AUTH_REJECT)) - final = RPCSVC_AUTH_REJECT; - /* On no rule, we reject. */ - else if ((gen == RPCSVC_AUTH_DONTCARE) && (spec== RPCSVC_AUTH_DONTCARE)) - final = RPCSVC_AUTH_REJECT; - else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_ACCEPT)) - final = RPCSVC_AUTH_ACCEPT; - else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_DONTCARE)) - final = RPCSVC_AUTH_REJECT; - else if ((gen == RPCSVC_AUTH_REJECT) && (spec == RPCSVC_AUTH_REJECT)) - final = RPCSVC_AUTH_REJECT; - - return final; -} - - -int -nfs_rpcsvc_conn_peer_check_name (dict_t *options, char *volname, - rpcsvc_conn_t *conn) -{ - int ret = RPCSVC_AUTH_REJECT; - int aret = RPCSVC_AUTH_REJECT; - int rjret = RPCSVC_AUTH_REJECT; - char clstr[RPCSVC_PEER_STRLEN]; - - if (!conn) - return ret; - - ret = nfs_rpcsvc_conn_peername (conn, clstr, RPCSVC_PEER_STRLEN); - if (ret != 0) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get remote addr: " - "%s", gai_strerror (ret)); - ret = RPCSVC_AUTH_REJECT; - goto err; - } - - aret = nfs_rpcsvc_conn_peer_check_allow (options, volname, clstr); - rjret = nfs_rpcsvc_conn_peer_check_reject (options, volname, clstr); - - ret = nfs_rpcsvc_combine_allow_reject_volume_check (aret, rjret); - -err: - return ret; -} - - -int -nfs_rpcsvc_conn_peer_check_addr (dict_t *options, char *volname, - rpcsvc_conn_t *conn) -{ - int ret = RPCSVC_AUTH_REJECT; - int aret = RPCSVC_AUTH_DONTCARE; - int rjret = RPCSVC_AUTH_REJECT; - char clstr[RPCSVC_PEER_STRLEN]; - - if (!conn) - return ret; - - ret = nfs_rpcsvc_conn_peeraddr (conn, clstr, RPCSVC_PEER_STRLEN, NULL, - 0); - if (ret != 0) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get remote addr: " - "%s", gai_strerror (ret)); - ret = RPCSVC_AUTH_REJECT; - goto err; - } - - aret = nfs_rpcsvc_conn_peer_check_allow (options, volname, clstr); - rjret = nfs_rpcsvc_conn_peer_check_reject (options, volname, clstr); - - ret = nfs_rpcsvc_combine_allow_reject_volume_check (aret, rjret); -err: - return ret; -} - - -int -nfs_rpcsvc_conn_check_volume_specific (dict_t *options, char *volname, - rpcsvc_conn_t *conn) -{ - int namechk = RPCSVC_AUTH_REJECT; - int addrchk = RPCSVC_AUTH_REJECT; - gf_boolean_t namelookup = _gf_true; - char *namestr = NULL; - int ret = 0; - - if ((!options) || (!volname) || (!conn)) - return RPCSVC_AUTH_REJECT; - - /* Enabled by default */ - if ((dict_get (options, "rpc-auth.addr.namelookup"))) { - ret = dict_get_str (options, "rpc-auth.addr.namelookup" - , &namestr); - if (ret == 0) - ret = gf_string2boolean (namestr, &namelookup); - } - - /* We need two separate checks because the rules with addresses in them - * can be network addresses which can be general and names can be - * specific which will over-ride the network address rules. - */ - if (namelookup) - namechk = nfs_rpcsvc_conn_peer_check_name (options, volname, - conn); - addrchk = nfs_rpcsvc_conn_peer_check_addr (options, volname, conn); - - if (namelookup) - ret = nfs_rpcsvc_combine_gen_spec_addr_checks (addrchk, - namechk); - else - ret = addrchk; - - return ret; -} - - -int -nfs_rpcsvc_conn_check_volume_general (dict_t *options, rpcsvc_conn_t *conn) -{ - int addrchk = RPCSVC_AUTH_REJECT; - int namechk = RPCSVC_AUTH_REJECT; - gf_boolean_t namelookup = _gf_true; - char *namestr = NULL; - int ret = 0; - - if ((!options) || (!conn)) - return RPCSVC_AUTH_REJECT; - - /* Enabled by default */ - if ((dict_get (options, "rpc-auth.addr.namelookup"))) { - ret = dict_get_str (options, "rpc-auth.addr.namelookup" - , &namestr); - if (ret == 0) - ret = gf_string2boolean (namestr, &namelookup); - } - - /* We need two separate checks because the rules with addresses in them - * can be network addresses which can be general and names can be - * specific which will over-ride the network address rules. - */ - if (namelookup) - namechk = nfs_rpcsvc_conn_peer_check_name (options, NULL, conn); - addrchk = nfs_rpcsvc_conn_peer_check_addr (options, NULL, conn); - - if (namelookup) - ret = nfs_rpcsvc_combine_gen_spec_addr_checks (addrchk, - namechk); - else - ret = addrchk; - - return ret; -} - -int -nfs_rpcsvc_conn_peer_check (dict_t *options, char *volname, rpcsvc_conn_t *conn) -{ - int general_chk = RPCSVC_AUTH_REJECT; - int specific_chk = RPCSVC_AUTH_REJECT; - - if ((!options) || (!volname) || (!conn)) - return RPCSVC_AUTH_REJECT; - - general_chk = nfs_rpcsvc_conn_check_volume_general (options, conn); - specific_chk = nfs_rpcsvc_conn_check_volume_specific (options, volname, - conn); - - return nfs_rpcsvc_combine_gen_spec_volume_checks (general_chk, - specific_chk); -} - - -char * -nfs_rpcsvc_volume_allowed (dict_t *options, char *volname) -{ - char globalrule[] = "rpc-auth.addr.allow"; - char *srchstr = NULL; - char *addrstr = NULL; - int ret = -1; - - if ((!options) || (!volname)) - return NULL; - - ret = gf_asprintf (&srchstr, "rpc-auth.addr.%s.allow", volname); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed"); - goto out; - } - - if (!dict_get (options, srchstr)) { - GF_FREE (srchstr); - srchstr = globalrule; - ret = dict_get_str (options, srchstr, &addrstr); - } else - ret = dict_get_str (options, srchstr, &addrstr); - -out: - return addrstr; -} - - -/* Initialize the core of a connection */ -rpcsvc_conn_t * -nfs_rpcsvc_conn_init (rpcsvc_t *svc, int sockfd) -{ - rpcsvc_conn_t *conn = NULL; - int ret = -1; - unsigned int poolcount = 0; - - conn = GF_CALLOC (1, sizeof(*conn), gf_common_mt_rpcsvc_conn_t); - if (!conn) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "memory allocation failed"); - return NULL; - } - - conn->sockfd = sockfd; - INIT_LIST_HEAD (&conn->txbufs); - poolcount = RPCSVC_POOLCOUNT_MULT * svc->memfactor; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "tx pool: %d", poolcount); - conn->txpool = mem_pool_new (rpcsvc_txbuf_t, poolcount); - if (!conn->txpool) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "mem pool allocation failed"); - goto free_conn; - } - - gf_log (GF_RPCSVC, GF_LOG_TRACE, "rx pool: %d", poolcount); - conn->rxpool = mem_pool_new (rpcsvc_request_t, poolcount); - if (!conn->rxpool) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "mem pool allocation failed"); - goto free_txp; - } - - /* Cannot consider a connection connected unless the user of this - * connection decides it is ready to use. It is possible that we have - * to free this connection soon after. That free will not happpen - * unless the state is disconnected. - */ - conn->connstate = RPCSVC_CONNSTATE_DISCONNECTED; - pthread_mutex_init (&conn->connlock, NULL); - conn->connref = 0; - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "New connection inited: sockfd: %d", - sockfd); - - ret = 0; -free_txp: - if (ret == -1) - mem_pool_destroy (conn->txpool); - -free_conn: - if (ret == -1) { - GF_FREE (conn); - conn = NULL; - } - - return conn; -} - - -void -nfs_rpcsvc_conn_destroy (rpcsvc_conn_t *conn) -{ - mem_pool_destroy (conn->txpool); - mem_pool_destroy (conn->rxpool); - - /* Need to destory record state, txlists etc. */ - GF_FREE (conn); - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Connection destroyed"); -} - - -int -__nfs_rpcsvc_conn_unref (rpcsvc_conn_t *conn) -{ - --conn->connref; - return conn->connref; -} - - -void -__nfs_rpcsvc_conn_deinit (rpcsvc_conn_t *conn) -{ - if (!conn) - return; - - if ((conn->stage) && (conn->stage->eventpool)) { - event_unregister (conn->stage->eventpool, conn->sockfd, - conn->eventidx); - } - - if (nfs_rpcsvc_conn_check_active (conn)) { - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Connection de-activated:" - " sockfd: %d", conn->sockfd); - conn->connstate = RPCSVC_CONNSTATE_DISCONNECTED; - } - - if (conn->sockfd != -1) { - close (conn->sockfd); - conn->sockfd = -1; - } -} - - -void -nfs_rpcsvc_conn_deinit (rpcsvc_conn_t *conn) -{ - int ref = 0; - - if (!conn) - return; - - pthread_mutex_lock (&conn->connlock); - { - __nfs_rpcsvc_conn_deinit (conn); - ref = __nfs_rpcsvc_conn_unref (conn); - } - pthread_mutex_unlock (&conn->connlock); - - if (ref == 0) - nfs_rpcsvc_conn_destroy (conn); - - return; -} - - -void -nfs_rpcsvc_conn_unref (rpcsvc_conn_t *conn) -{ - int ref = 0; - if (!conn) - return; - - pthread_mutex_lock (&conn->connlock); - { - ref = __nfs_rpcsvc_conn_unref (conn); - } - pthread_mutex_unlock (&conn->connlock); - - if (ref == 0) - nfs_rpcsvc_conn_destroy (conn); -} - - -int -nfs_rpcsvc_conn_active (rpcsvc_conn_t *conn) -{ - int status = 0; - - if (!conn) - return 0; - - pthread_mutex_lock (&conn->connlock); - { - status = nfs_rpcsvc_conn_check_active (conn); - } - pthread_mutex_unlock (&conn->connlock); - - return status; -} - - - -void -nfs_rpcsvc_conn_ref (rpcsvc_conn_t *conn) -{ - if (!conn) - return; - - pthread_mutex_lock (&conn->connlock); - { - ++conn->connref; - } - pthread_mutex_unlock (&conn->connlock); - - return; -} - - -void -nfs_rpcsvc_conn_state_init (rpcsvc_conn_t *conn) -{ - if (!conn) - return; - - ++conn->connref; - conn->connstate = RPCSVC_CONNSTATE_CONNECTED; -} - -/* Builds a rpcsvc_conn_t with the aim of listening on it. - */ -rpcsvc_conn_t * -nfs_rpcsvc_conn_listen_init (rpcsvc_t *svc, rpcsvc_program_t *newprog) -{ - rpcsvc_conn_t *conn = NULL; - int sock = -1; - - if (!newprog) - return NULL; - - sock = nfs_rpcsvc_socket_listen (newprog->progaddrfamily, - newprog->proghost, newprog->progport); - if (sock == -1) - goto err; - - conn = nfs_rpcsvc_conn_init (svc, sock); - if (!conn) - goto sock_close_err; - - nfs_rpcsvc_conn_state_init (conn); -sock_close_err: - if (!conn) - close (sock); - -err: - return conn; -} - -void -nfs_rpcsvc_record_init (rpcsvc_record_state_t *rs, struct iobuf_pool *pool) -{ - if (!rs) - return; - - rs->state = RPCSVC_READ_FRAGHDR; - rs->vecstate = 0; - rs->remainingfraghdr = RPCSVC_FRAGHDR_SIZE; - rs->remainingfrag = 0; - rs->fragsize = 0; - rs->recordsize = 0; - rs->islastfrag = 0; - - /* If the rs preserves a ref to the iob used by the previous request, - * we must unref it here to prevent memory leak. - * If program actor wanted to keep that memory around, it should've - * refd it on entry into the actor. - */ - if (rs->activeiob) - iobuf_unref (rs->activeiob); - - if (rs->vectoriob) { - iobuf_unref (rs->vectoriob); - rs->vectoriob = NULL; - } - - rs->activeiob = iobuf_get (pool); - rs->fragcurrent = iobuf_ptr (rs->activeiob); - - memset (rs->fragheader, 0, RPCSVC_FRAGHDR_SIZE); - rs->hdrcurrent = &rs->fragheader[0]; - -} - - -int -nfs_rpcsvc_conn_privport_check (rpcsvc_t *svc, char *volname, - rpcsvc_conn_t *conn) -{ - struct sockaddr_in sa; - int ret = RPCSVC_AUTH_REJECT; - socklen_t sasize = sizeof (sa); - char *srchstr = NULL; - char *valstr = NULL; - int globalinsecure = RPCSVC_AUTH_REJECT; - int exportinsecure = RPCSVC_AUTH_DONTCARE; - uint16_t port = 0; - gf_boolean_t insecure = _gf_false; - - if ((!svc) || (!volname) || (!conn)) - return ret; - - ret = nfs_rpcsvc_conn_peeraddr (conn, NULL, 0, (struct sockaddr *)&sa, - sasize); - if (ret != 0) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get peer addr: %s", - gai_strerror (ret)); - ret = RPCSVC_AUTH_REJECT; - goto err; - } - - port = ntohs (sa.sin_port); - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Client port: %d", (int)port); - /* If the port is already a privileged one, dont bother with checking - * options. - */ - if (port <= 1024) { - ret = RPCSVC_AUTH_ACCEPT; - goto err; - } - - /* Disabled by default */ - if ((dict_get (svc->options, "rpc-auth.ports.insecure"))) { - ret = dict_get_str (svc->options, "rpc-auth.ports.insecure" - , &srchstr); - if (ret == 0) { - ret = gf_string2boolean (srchstr, &insecure); - if (ret == 0) { - if (insecure == _gf_true) - globalinsecure = RPCSVC_AUTH_ACCEPT; - } else - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to" - " read rpc-auth.ports.insecure value"); - } else - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to" - " read rpc-auth.ports.insecure value"); - } - - /* Disabled by default */ - ret = gf_asprintf (&srchstr, "rpc-auth.ports.%s.insecure", volname); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "asprintf failed"); - ret = RPCSVC_AUTH_REJECT; - goto err; - } - - if (dict_get (svc->options, srchstr)) { - ret = dict_get_str (svc->options, srchstr, &valstr); - if (ret == 0) { - ret = gf_string2boolean (srchstr, &insecure); - if (ret == 0) { - if (insecure == _gf_true) - exportinsecure = RPCSVC_AUTH_ACCEPT; - else - exportinsecure = RPCSVC_AUTH_REJECT; - } else - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to" - " read rpc-auth.ports.insecure value"); - } else - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to" - " read rpc-auth.ports.insecure value"); - } - - ret = nfs_rpcsvc_combine_gen_spec_volume_checks (globalinsecure, - exportinsecure); - if (ret == RPCSVC_AUTH_ACCEPT) - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Unprivileged port allowed"); - else - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Unprivileged port not" - " allowed"); - -err: - return ret; -} - -/* Inits a rpcsvc_conn_t after accepting the connection. - */ -rpcsvc_conn_t * -nfs_rpcsvc_conn_accept_init (rpcsvc_t *svc, int listenfd) -{ - rpcsvc_conn_t *newconn = NULL; - int sock = -1; - int ret = -1; - - sock = nfs_rpcsvc_socket_accept (listenfd); - if (sock == -1) - goto err; - - newconn = nfs_rpcsvc_conn_init (svc, sock); - if (!newconn) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to init conn object"); - ret = -1; - goto err; - } - - nfs_rpcsvc_record_init (&newconn->rstate, svc->ctx->iobuf_pool); - nfs_rpcsvc_conn_state_init (newconn); - ret = 0; - -err: - if (ret == -1) - close (sock); - - return newconn; -} - - -/* Once the connection has been created, we need to associate it with - * a stage so that the selected stage will handle the event on this connection. - * This function also allows the caller to decide which handler should - * be executed in the context of the stage, and also which specific events - * should be handed to the handler when running in this particular stage. - */ -int -nfs_rpcsvc_stage_conn_associate (rpcsvc_stage_t *stg, rpcsvc_conn_t *conn, - event_handler_t handler, void *data) -{ - int ret = -1; - - if ((!stg) || (!conn)) - return -1; - - conn->stage = stg; - conn->eventidx = event_register (stg->eventpool, conn->sockfd, handler, - data, 1, 0); - if (conn->eventidx == -1) - goto err; - - ret = 0; -err: - return ret; -} - - -/* Depending on the state we're in, return the size of the next read request. */ -size_t -nfs_rpcsvc_record_read_size (rpcsvc_record_state_t *rs) -{ - size_t toread = -1; - - if (!rs) - return -1; - - if (nfs_rpcsvc_record_readfraghdr (rs)) - toread = rs->remainingfraghdr; - else if (nfs_rpcsvc_record_readfrag (rs)) - toread = rs->remainingfrag; - else - toread = RPCSVC_CONN_READ; - - return toread; -} - - -uint32_t -nfs_rpcsvc_record_extract_fraghdr (char *fraghdr) -{ - uint32_t hdr = 0; - if (!fraghdr) - return 0; - - memcpy ((void *)&hdr, fraghdr, sizeof (hdr)); - - hdr = ntohl (hdr); - return hdr; -} - - -ssize_t -nfs_rpcsvc_record_read_complete_fraghdr (rpcsvc_record_state_t *rs, - ssize_t dataread) -{ - uint32_t remhdr = 0; - char *fraghdrstart = NULL; - uint32_t fraghdr = 0; - - fraghdrstart = &rs->fragheader[0]; - remhdr = rs->remainingfraghdr; - fraghdr = nfs_rpcsvc_record_extract_fraghdr (fraghdrstart); - rs->fragsize = RPCSVC_FRAGSIZE (fraghdr); - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Received fragment size: %d", - rs->fragsize); - if (nfs_rpcsvc_record_vectored (rs)) { - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC header," - " remaining: %d", RPCSVC_BARERPC_MSGSZ); - rs->remainingfrag = RPCSVC_BARERPC_MSGSZ; - } else { - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Regular RPC header," - " remaining: %d", rs->fragsize); - rs->remainingfrag = rs->fragsize; - } - - rs->state = RPCSVC_READ_FRAG; - dataread -= remhdr; - rs->remainingfraghdr -= remhdr; - rs->islastfrag = RPCSVC_LASTFRAG (fraghdr); - - return dataread; -} - - -ssize_t -nfs_rpcsvc_record_read_partial_fraghdr (rpcsvc_record_state_t *rs, - ssize_t dataread) -{ - - /* In case we got less than even the remaining header size, - * we need to consume it all and wait for remaining frag hdr - * bytes to come in. - */ - rs->remainingfraghdr -= dataread; - nfs_rpcsvc_record_update_currenthdr (rs, dataread); - dataread = 0; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Fragment header remaining: %d", - rs->remainingfraghdr); - - return dataread; -} - - -ssize_t -nfs_rpcsvc_record_update_fraghdr (rpcsvc_record_state_t *rs, ssize_t dataread) -{ - if ((!rs) || (dataread <= 0)) - return -1; - - /* Why are we even here, we're not supposed to be in the fragment - * header processing state. - */ - if (!nfs_rpcsvc_record_readfraghdr(rs)) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "record state inconsistent" - ": request to update frag header when state is not" - "RPCSVC_READ_FRAGHDR"); - return -1; - } - - /* Again, if header has been read then the state member above should've - * been different, this is crazy. We should not be here. - */ - if (rs->remainingfraghdr == 0) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "record state inconsistent" - ": request to update frag header when frag header" - "remaining is 0."); - return -1; - } - - /* We've definitely got the full header now and may be even more. */ - if (dataread >= rs->remainingfraghdr) - dataread = nfs_rpcsvc_record_read_complete_fraghdr (rs, - dataread); - else - dataread = nfs_rpcsvc_record_read_partial_fraghdr (rs, - dataread); - - return dataread; -} - -ssize_t -nfs_rpcsvc_record_read_complete_frag (rpcsvc_record_state_t *rs, - ssize_t dataread) -{ - uint32_t remfrag; - - /* Since the frag is now complete, change the state to the next - * one, i.e. to read the header of the next fragment. - */ - remfrag = rs->remainingfrag; - rs->state = RPCSVC_READ_FRAGHDR; - dataread -= remfrag; - - /* This will be 0 now. */ - rs->remainingfrag -= remfrag; - - /* Now that the fragment is complete, we must update the - * record size. Recall that fragsize was got from the frag - * header. - */ - rs->recordsize += rs->fragsize; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Fragment remaining: %d", - rs->remainingfrag); - - return dataread; -} - - -ssize_t -nfs_rpcsvc_record_read_partial_frag (rpcsvc_record_state_t *rs, - ssize_t dataread) -{ - /* Just take whatever has come through the current network buffer. */ - rs->remainingfrag -= dataread; - - nfs_rpcsvc_record_update_currentfrag (rs, dataread); - /* Since we know we're consuming the whole buffer from dataread - * simply setting to 0 zero is fine. - */ - dataread = 0; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Fragment remaining: %d", - rs->remainingfrag); - return dataread; -} - - -ssize_t -nfs_rpcsvc_record_update_frag (rpcsvc_record_state_t *rs, ssize_t dataread) -{ - if ((!rs) || (dataread <= 0)) - return -1; - - if (!nfs_rpcsvc_record_readfrag (rs)) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "record state inconsistent" - ": request to update fragment when record state is not" - "RPCSVC_READ_FRAG."); - return -1; - } - - if (rs->remainingfrag == 0) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "record state inconsistent" - ": request to update fragment when there is no fragment" - " data remaining to be read."); - return -1; - } - - /* We've read in more data than the current fragment requires. */ - if (dataread >= rs->remainingfrag) - dataread = nfs_rpcsvc_record_read_complete_frag (rs, dataread); - else - dataread = nfs_rpcsvc_record_read_partial_frag (rs, dataread); - - return dataread; -} - - - -/* This needs to change to returning errors, since - * we need to return RPC specific error messages when some - * of the pointers below are NULL. - */ -int -__nfs_rpcsvc_program_actor (rpcsvc_request_t *req, rpcsvc_program_t **prg) -{ - rpcsvc_program_t *program = NULL; - int ret = PROG_UNAVAIL; - rpcsvc_actor_t *actor = NULL; - struct list_head *prglist = NULL; - - if (!req) - return ret; - - prglist = &((nfs_rpcsvc_request_service (req))->allprograms); - if (list_empty (prglist)) - goto err; - - list_for_each_entry (program, prglist, proglist) { - ret = PROG_UNAVAIL; - if (req->prognum != program->prognum) - continue; - - if (!program->actors) { - ret = SYSTEM_ERR; - goto err; - } - - ret = PROG_MISMATCH; - if (req->progver != program->progver) - continue; - - ret = PROC_UNAVAIL; - if ((req->procnum < 0) || (req->procnum >= program->numactors)) - goto err; - - actor = &program->actors[req->procnum]; - if (!actor->actor) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "RPC Program procedure" - " not defined"); - actor = NULL; - goto err; - } else { - ret = SUCCESS; - break; - } - } - - *prg = program; -err: - switch (ret) { - - case PROG_UNAVAIL: - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC program not available"); - break; - - case PROG_MISMATCH: - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC program version " - "not available"); - break; - - case PROC_UNAVAIL: - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC Program procedure" - " not available"); - break; - - case SUCCESS: - gf_log (GF_RPCSVC, GF_LOG_TRACE, "RPC Program found"); - break; - - default: - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "System error"); - break; - } - - /* If the error is not RPC_MISMATCH, we consider the call as accepted - * since we are not handling authentication failures for now. - */ - req->rpc_stat = MSG_ACCEPTED; - req->rpc_err = ret; - - return ret; -} - -/* This needs to change to returning errors, since - * we need to return RPC specific error messages when some - * of the pointers below are NULL. - */ -rpcsvc_actor_t * -nfs_rpcsvc_program_actor (rpcsvc_request_t *req) -{ - int err = SYSTEM_ERR; - rpcsvc_actor_t *actor = NULL; - - if (!req) - goto err; - - actor = &req->program->actors[req->procnum]; - err = SUCCESS; - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Actor found: %s - %s", - req->program->progname, actor->procname); -err: - if (req) - req->rpc_err = err; - - return actor; -} - - -rpcsvc_txbuf_t * -nfs_rpcsvc_init_txbuf (rpcsvc_conn_t *conn, struct iovec msg, struct iobuf *iob, - struct iobref *iobref, int txflags) -{ - rpcsvc_txbuf_t *txbuf = NULL; - - txbuf = (rpcsvc_txbuf_t *) mem_get(conn->txpool); - if (!txbuf) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get txbuf"); - return NULL; - } - - memset (txbuf, 0, sizeof (*txbuf)); - INIT_LIST_HEAD (&txbuf->txlist); - txbuf->buf = msg; - - /* If it was required, this iob must've been ref'd already - * so I dont have to bother here. - */ - txbuf->iob = iob; - txbuf->iobref = iobref; - txbuf->offset = 0; - txbuf->txbehave = txflags; - - return txbuf; -} - - -int -nfs_rpcsvc_conn_append_txlist (rpcsvc_conn_t *conn, struct iovec msg, - struct iobuf *iob, int txflags) -{ - rpcsvc_txbuf_t *txbuf = NULL; - - if ((!conn) || (!msg.iov_base) || (!iob)) - return -1; - - txbuf = nfs_rpcsvc_init_txbuf (conn, msg, iob, NULL, txflags); - if (!txbuf) - return -1; - - list_add_tail (&txbuf->txlist, &conn->txbufs); - return 0; -} - - -void -nfs_rpcsvc_set_lastfrag (uint32_t *fragsize) { - (*fragsize) |= 0x80000000U; -} - -void -nfs_rpcsvc_set_frag_header_size (uint32_t size, char *haddr) -{ - size = htonl (size); - memcpy (haddr, &size, sizeof (size)); -} - -void -nfs_rpcsvc_set_last_frag_header_size (uint32_t size, char *haddr) -{ - nfs_rpcsvc_set_lastfrag (&size); - nfs_rpcsvc_set_frag_header_size (size, haddr); -} - - -/* Given the RPC reply structure and the payload handed by the RPC program, - * encode the RPC record header into the buffer pointed by recordstart. - */ -struct iovec -nfs_rpcsvc_record_build_header (char *recordstart, size_t rlen, - struct rpc_msg reply, size_t payload) -{ - struct iovec replyhdr; - struct iovec txrecord = {0, 0}; - size_t fraglen = 0; - int ret = -1; - - /* After leaving aside the 4 bytes for the fragment header, lets - * encode the RPC reply structure into the buffer given to us. - */ - ret = nfs_rpc_reply_to_xdr (&reply,(recordstart + RPCSVC_FRAGHDR_SIZE), - rlen, &replyhdr); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to create RPC reply"); - goto err; - } - - fraglen = payload + replyhdr.iov_len; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Reply fraglen %zu, payload: %zu, " - "rpc hdr: %zu", fraglen, payload, replyhdr.iov_len); - - /* Since we're not spreading RPC records over mutiple fragments - * we just set this fragment as the first and last fragment for this - * record. - */ - nfs_rpcsvc_set_last_frag_header_size (fraglen, recordstart); - - /* Even though the RPC record starts at recordstart+RPCSVC_FRAGHDR_SIZE - * we need to transmit the record with the fragment header, which starts - * at recordstart. - */ - txrecord.iov_base = recordstart; - - /* Remember, this is only the vec for the RPC header and does not - * include the payload above. We needed the payload only to calculate - * the size of the full fragment. This size is sent in the fragment - * header. - */ - txrecord.iov_len = RPCSVC_FRAGHDR_SIZE + replyhdr.iov_len; - -err: - return txrecord; -} - - -int -nfs_rpcsvc_conn_submit (rpcsvc_conn_t *conn, struct iovec hdr, - struct iobuf *hdriob, struct iovec msgvec, - struct iobuf *msgiob) -{ - int ret = -1; - - if ((!conn) || (!hdr.iov_base) || (!hdriob)) - return -1; - - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Tx Header: %zu, payload: %zu", - hdr.iov_len, msgvec.iov_len); - /* Now that we have both the RPC and Program buffers in xdr format - * lets hand it to the transmission layer. - */ - pthread_mutex_lock (&conn->connlock); - { - if (!nfs_rpcsvc_conn_check_active (conn)) { - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Connection inactive"); - goto unlock_err; - } - - ret = nfs_rpcsvc_conn_append_txlist (conn, hdr, hdriob, - RPCSVC_TXB_FIRST); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to append " - "header to transmission list"); - goto unlock_err; - } - - /* It is possible that this RPC reply is an error reply. In that - * case we might not have been handed a payload. - */ - ret = 0; - if (msgiob) - ret = nfs_rpcsvc_conn_append_txlist (conn, msgvec, - msgiob, - RPCSVC_TXB_LAST); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to append" - " payload to transmission list"); - goto unlock_err; - } - } -unlock_err: - pthread_mutex_unlock (&conn->connlock); - - if (ret == -1) - goto err; - - /* Tell event pool, we're interested in poll_out to trigger flush - * of our tx buffers. - */ - conn->eventidx = event_select_on (conn->stage->eventpool, conn->sockfd, - conn->eventidx, -1, 1); - ret = 0; -err: - - return ret; -} - - -int -nfs_rpcsvc_fill_reply (rpcsvc_request_t *req, struct rpc_msg *reply) -{ - rpcsvc_program_t *prog = NULL; - if ((!req) || (!reply)) - return -1; - - prog = nfs_rpcsvc_request_program (req); - nfs_rpc_fill_empty_reply (reply, req->xid); - - if (req->rpc_stat == MSG_DENIED) - nfs_rpc_fill_denied_reply (reply, req->rpc_err, req->auth_err); - else if (req->rpc_stat == MSG_ACCEPTED) { - if (!prog) - nfs_rpc_fill_accepted_reply (reply, req->rpc_err, 0, 0, - req->verf.flavour, - req->verf.datalen, - req->verf.authdata); - else - nfs_rpc_fill_accepted_reply (reply, req->rpc_err, - prog->proglowvers, - prog->proghighvers, - req->verf.flavour, - req->verf.datalen, - req->verf.authdata); - - } else - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Invalid rpc_stat value"); - - return 0; -} - - -/* Given a request and the reply payload, build a reply and encodes the reply - * into a record header. This record header is encoded into the vector pointed - * to be recbuf. - * msgvec is the buffer that points to the payload of the RPC program. - * This buffer can be NULL, if an RPC error reply is being constructed. - * The only reason it is needed here is that in case the buffer is provided, - * we should account for the length of that buffer in the RPC fragment header. - */ -struct iobuf * -nfs_rpcsvc_record_build_record (rpcsvc_request_t *req, size_t payload, - struct iovec *recbuf) -{ - struct rpc_msg reply; - struct iobuf *replyiob = NULL; - char *record = NULL; - struct iovec recordhdr = {0, }; - size_t pagesize = 0; - rpcsvc_conn_t *conn = NULL; - rpcsvc_t *svc = NULL; - - if ((!req) || (!req->conn) || (!recbuf)) - return NULL; - - /* First, try to get a pointer into the buffer which the RPC - * layer can use. - */ - conn = req->conn; - svc = nfs_rpcsvc_conn_rpcsvc (conn); - replyiob = iobuf_get (svc->ctx->iobuf_pool); - pagesize = iobpool_pagesize ((struct iobuf_pool *)svc->ctx->iobuf_pool); - if (!replyiob) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get iobuf"); - goto err_exit; - } - - record = iobuf_ptr (replyiob); /* Now we have it. */ - - /* Fill the rpc structure and XDR it into the buffer got above. */ - nfs_rpcsvc_fill_reply (req, &reply); - recordhdr = nfs_rpcsvc_record_build_header (record, pagesize, reply, - payload); - if (!recordhdr.iov_base) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to build record " - " header"); - iobuf_unref (replyiob); - replyiob = NULL; - recbuf->iov_base = NULL; - goto err_exit; - } - - recbuf->iov_base = recordhdr.iov_base; - recbuf->iov_len = recordhdr.iov_len; -err_exit: - return replyiob; -} - - -/* - * The function to submit a program message to the RPC service. - * This message is added to the transmission queue of the - * conn. - * - * Program callers are not expected to use the msgvec->iov_base - * address for anything else. - * Nor are they expected to free it once this function returns. - * Once the transmission of the buffer is completed by the RPC service, - * the memory area as referenced through @msg will be unrefed. - * If a higher layer does not want anything to do with this iobuf - * after this function returns, it should call unref on it. For keeping - * it around till the transmission is actually complete, rpcsvc also refs it. - * * - * If this function returns an error by returning -1, the - * higher layer programs should assume that a disconnection happened - * and should know that the conn memory area as well as the req structure - * has been freed internally. - * - * For now, this function assumes that a submit is always called - * to send a new record. Later, if there is a situation where different - * buffers for the same record come from different sources, then we'll - * need to change this code to account for multiple submit calls adding - * the buffers into a single record. - */ - -int -nfs_rpcsvc_submit_generic (rpcsvc_request_t *req, struct iovec msgvec, - struct iobuf *msg) -{ - int ret = -1; - struct iobuf *replyiob = NULL; - struct iovec recordhdr = {0, }; - rpcsvc_conn_t *conn = NULL; - int rpc_status = 0; - int rpc_error = 0; - - if ((!req) || (!req->conn)) - return -1; - - conn = req->conn; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Tx message: %zu", msgvec.iov_len); - /* Build the buffer containing the encoded RPC reply. */ - replyiob = nfs_rpcsvc_record_build_record (req, msgvec.iov_len, - &recordhdr); - if (!replyiob) { - gf_log (GF_RPCSVC, GF_LOG_ERROR,"Reply record creation failed"); - goto disconnect_exit; - } - - /* Must ref the iobuf got from higher layer so that the higher layer - * can rest assured that it can unref it and leave the final freeing - * of the buffer to us. Note msg can be NULL if an RPC-only message - * was being sent. Happens when an RPC error reply is being sent. - */ - if (msg) - iobuf_ref (msg); - ret = nfs_rpcsvc_conn_submit (conn, recordhdr, replyiob, msgvec, msg); - - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to submit message"); - iobuf_unref (replyiob); - } - -disconnect_exit: - /* Note that a unref is called everytime a reply is sent. This is in - * response to the ref that is performed on the conn when a request is - * handed to the RPC program. - * - * The catch, however, is that if the reply is an rpc error, we must - * not unref. This is because the ref only contains - * references for the actors to which the request was handed plus one - * reference maintained by the RPC layer. By unrefing for a case where - * no actor was called, we will be losing the ref held for the RPC - * layer. - */ - - /* If the request succeeded and was handed to the actor, then unref the - * conn. - */ - - rpc_status = req->rpc_stat; - rpc_error = req->rpc_err; - /* Must mem_put req back to rxpool before the possibility of destroying - * conn in conn_unref, where the rxpool itself is destroyed. - */ - mem_put (conn->rxpool, req); - if ((rpc_status == MSG_ACCEPTED) && (rpc_error == SUCCESS)) - nfs_rpcsvc_conn_unref (conn); - - return ret; -} - - -int -nfs_rpcsvc_request_attach_vector (rpcsvc_request_t *req, struct iovec msgvec, - struct iobuf *iob, struct iobref *iobref, - int finalvector) -{ - rpcsvc_txbuf_t *txb = NULL; - int txflags = 0; - - if ((!req) || (!msgvec.iov_base)) - return -1; - - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Tx Vector: %zu", msgvec.iov_len); - if (finalvector) - txflags |= RPCSVC_TXB_LAST; - /* We only let the user decide whether this is the last vector for the - * record, since the first vector is always the RPC header. - */ - txb = nfs_rpcsvc_init_txbuf (req->conn, msgvec, iob, iobref, txflags); - if (!txb) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Could not init tx buf"); - return -1; - } - - req->payloadsize += msgvec.iov_len; - if (iob) - iobuf_ref (iob); - if (iobref) - iobref_ref (iobref); - list_add_tail (&txb->txlist, &req->txlist); - - return 0; -} - - -int -nfs_rpcsvc_request_attach_vectors (rpcsvc_request_t *req, struct iovec *payload, - int vcount, struct iobref *piobref) -{ - int c = 0; - int ret = -1; - - for (;c < (vcount-1); c++) { - ret = nfs_rpcsvc_request_attach_vector (req, payload[c], NULL, - piobref, 0); - if (ret < 0) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to attach " - "vector"); - goto out; - } - } - - ret = nfs_rpcsvc_request_attach_vector (req, payload[vcount-1], NULL, - piobref, 1); - if (ret < 0) - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to attach final vec"); - -out: - return ret; -} - - -int -nfs_rpcsvc_submit_vectors (rpcsvc_request_t *req) -{ - int ret = -1; - struct iobuf *replyiob = NULL; - struct iovec recordhdr = {0, }; - rpcsvc_txbuf_t *rpctxb = NULL; - rpcsvc_conn_t *conn = NULL; - - if ((!req) || (!req->conn)) - return -1; - - /* Build the buffer containing the encoded RPC reply. */ - replyiob = nfs_rpcsvc_record_build_record (req, req->payloadsize, - &recordhdr); - if (!replyiob) { - gf_log (GF_RPCSVC, GF_LOG_ERROR,"Reply record creation failed"); - goto disconnect_exit; - } - - rpctxb = nfs_rpcsvc_init_txbuf (req->conn, recordhdr, replyiob, NULL, - RPCSVC_TXB_FIRST); - if (!rpctxb) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to create tx buf"); - goto disconnect_exit; - } - - pthread_mutex_lock (&req->conn->connlock); - { - list_add_tail (&rpctxb->txlist, &req->conn->txbufs); - list_append_init (&req->txlist, &req->conn->txbufs); - } - pthread_mutex_unlock (&req->conn->connlock); - - ret = 0; - req->conn->eventidx = event_select_on (req->conn->stage->eventpool, - req->conn->sockfd, - req->conn->eventidx, -1, 1); -disconnect_exit: - /* Note that a unref is called everytime a reply is sent. This is in - * response to the ref that is performed on the conn when a request is - * handed to the RPC program. - */ - conn = req->conn; - /* Must mem_put req back to rxpool before the possibility of destroying - * conn in conn_unref, where the rxpool itself is destroyed. - */ - mem_put (conn->rxpool, req); - - nfs_rpcsvc_conn_unref (conn); - if (ret == -1) - iobuf_unref (replyiob); - - return ret; -} - - -int -nfs_rpcsvc_error_reply (rpcsvc_request_t *req) -{ - struct iovec dummyvec = {0, }; - - if (!req) - return -1; - - /* At this point the req should already have been filled with the - * appropriate RPC error numbers. - */ - return nfs_rpcsvc_submit_generic (req, dummyvec, NULL); -} - - -rpcsvc_request_t * -nfs_rpcsvc_request_init (rpcsvc_conn_t *conn, struct rpc_msg *callmsg, - struct iovec progmsg, rpcsvc_request_t *req) -{ - if ((!conn) || (!callmsg)|| (!req)) - return NULL; - - - /* We start a RPC request as always denied. */ - req->rpc_stat = MSG_DENIED; - req->xid = nfs_rpc_call_xid (callmsg); - req->prognum = nfs_rpc_call_program (callmsg); - req->progver = nfs_rpc_call_progver (callmsg); - req->procnum = nfs_rpc_call_progproc (callmsg); - req->conn = conn; - req->msg = progmsg; - req->recordiob = conn->rstate.activeiob; - INIT_LIST_HEAD (&req->txlist); - req->payloadsize = 0; - - /* By this time, the data bytes for the auth scheme would have already - * been copied into the required sections of the req structure, - * we just need to fill in the meta-data about it now. - */ - req->cred.flavour = nfs_rpc_call_cred_flavour (callmsg); - req->cred.datalen = nfs_rpc_call_cred_len (callmsg); - req->verf.flavour = nfs_rpc_call_verf_flavour (callmsg); - req->verf.datalen = nfs_rpc_call_verf_len (callmsg); - - /* AUTH */ - nfs_rpcsvc_auth_request_init (req); - return req; -} - - -rpcsvc_request_t * -nfs_rpcsvc_request_create (rpcsvc_conn_t *conn) -{ - char *msgbuf = NULL; - struct rpc_msg rpcmsg; - struct iovec progmsg; /* RPC Program payload */ - rpcsvc_request_t *req = NULL; - int ret = -1; - rpcsvc_program_t *program = NULL; - - if (!conn) - return NULL; - - /* We need to allocate the request before actually calling - * rpcsvc_request_init on the request so that we, can fill the auth - * data directly into the request structure from the message iobuf. - * This avoids a need to keep a temp buffer into which the auth data - * would've been copied otherwise. - */ - nfs_rpcsvc_alloc_request (conn, req); - if (!req) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to alloc request"); - goto err; - } - - msgbuf = iobuf_ptr (conn->rstate.activeiob); - ret = nfs_xdr_to_rpc_call (msgbuf, conn->rstate.recordsize, &rpcmsg, - &progmsg, req->cred.authdata, - req->verf.authdata); - - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "RPC call decoding failed"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); - req->conn = conn; - goto err; - } - - ret = -1; - nfs_rpcsvc_request_init (conn, &rpcmsg, progmsg, req); - - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "RPC XID: %lx, Ver: %ld, Program: %ld," - " ProgVers: %ld, Proc: %ld", nfs_rpc_call_xid (&rpcmsg), - nfs_rpc_call_rpcvers (&rpcmsg), nfs_rpc_call_program (&rpcmsg), - nfs_rpc_call_progver (&rpcmsg), - nfs_rpc_call_progproc (&rpcmsg)); - - if (nfs_rpc_call_rpcvers (&rpcmsg) != 2) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "RPC version not supported"); - nfs_rpcsvc_request_seterr (req, RPC_MISMATCH); - goto err; - } - - ret = __nfs_rpcsvc_program_actor (req, &program); - if (ret != SUCCESS) { - ret = -1; - goto err; - } - - req->program = program; - ret = nfs_rpcsvc_authenticate (req); - if (ret == RPCSVC_AUTH_REJECT) { - /* No need to set auth_err, that is the responsibility of - * the authentication handler since only that know what exact - * error happened. - */ - nfs_rpcsvc_request_seterr (req, AUTH_ERROR); - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed authentication"); - ret = -1; - goto err; - } - - ret = 0; -err: - if (ret == -1) { - ret = nfs_rpcsvc_error_reply (req); - req = NULL; - } - - return req; -} - - -int -nfs_rpcsvc_handle_rpc_call (rpcsvc_conn_t *conn) -{ - rpcsvc_actor_t *actor = NULL; - rpcsvc_request_t *req = NULL; - int ret = -1; - - if (!conn) - return -1; - - req = nfs_rpcsvc_request_create (conn); - if (!req) - goto err; - - if (!nfs_rpcsvc_request_accepted (req)) - goto err_reply; - - actor = nfs_rpcsvc_program_actor (req); - if (!actor) - goto err_reply; - - if ((actor) && (actor->actor)) { - THIS = nfs_rpcsvc_request_actorxl (req); - nfs_rpcsvc_conn_ref (conn); - ret = actor->actor (req); - } - -err_reply: - if (ret == RPCSVC_ACTOR_ERROR) - ret = nfs_rpcsvc_error_reply (req); - else if (ret == RPCSVC_ACTOR_IGNORE) - mem_put (conn->rxpool, req); - - /* No need to propagate error beyond this function since the reply - * has now been queued. */ - ret = 0; -err: - return ret; -} - -#define nfs_rpc_call_cred_addr(rs) (iobuf_ptr ((rs)->activeiob) + RPCSVC_BARERPC_MSGSZ - 4) - -uint32_t -nfs_rpcsvc_call_credlen (rpcsvc_record_state_t *rs) -{ - char *credaddr = NULL; - uint32_t credlen_nw = 0; - uint32_t credlen_host = 0; - - /* Position to the start of the credential length field. */ - credaddr = nfs_rpc_call_cred_addr (rs); - credlen_nw = *(uint32_t *)credaddr; - credlen_host = ntohl (credlen_nw); - - return credlen_host; -} - -uint32_t -nfs_rpcsvc_call_verflen (rpcsvc_record_state_t *rs) -{ - char *verfaddr = NULL; - uint32_t verflen_nw = 0; - uint32_t verflen_host = 0; - uint32_t credlen = 0; - - /* Position to the start of the verifier length field. */ - credlen = nfs_rpcsvc_call_credlen (rs); - verfaddr = (nfs_rpc_call_cred_addr (rs) + 4 + credlen); - verflen_nw = *(uint32_t *)verfaddr; - verflen_host = ntohl (verflen_nw); - - return verflen_host; -} - - -void -nfs_rpcsvc_update_vectored_verf (rpcsvc_record_state_t *rs) -{ - if (!rs) - return; - - rs->recordsize += nfs_rpcsvc_call_verflen (rs); - return; -} - - -void -nfs_rpcsvc_handle_vectored_prep_rpc_call (rpcsvc_conn_t *conn) -{ - rpcsvc_actor_t *actor = NULL; - rpcsvc_request_t *req = NULL; - rpcsvc_record_state_t *rs = NULL; - rpcsvc_t *svc = NULL; - int ret = -1; - ssize_t remfrag = RPCSVC_ACTOR_ERROR; - int newbuf = 0; - - if (!conn) - return; - - rs = &conn->rstate; - - /* In case one of the steps below fails, we need to make sure that the - * remaining frag in the kernel's buffers are read-out so that the - * requests that follow can be served. - */ - rs->remainingfrag = rs->fragsize - rs->recordsize; - rs->vecstate = RPCSVC_VECTOR_IGNORE; - req = nfs_rpcsvc_request_create (conn); - svc = nfs_rpcsvc_conn_rpcsvc (conn); - if (!req) - goto err; - - if (!nfs_rpcsvc_request_accepted (req)) - goto err_reply; - - actor = nfs_rpcsvc_program_actor (req); - if (!actor) - goto err_reply; - - if (!actor->vector_sizer) { - ret = -1; - nfs_rpcsvc_request_seterr (req, PROC_UNAVAIL); - goto err_reply; - } - - nfs_rpcsvc_conn_ref (conn); - THIS = nfs_rpcsvc_request_actorxl (req); - ret = actor->vector_sizer (req, &remfrag, &newbuf); - nfs_rpcsvc_conn_unref (conn); - - if (ret == RPCSVC_ACTOR_ERROR) { - ret = -1; - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); - goto err_reply; - } - - rs->remainingfrag = remfrag; - rs->vecstate = RPCSVC_VECTOR_READPROCHDR; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC proc header remaining:" - " %d", rs->remainingfrag); - conn->vectoredreq = req; - - /* Store the reference to the current frag pointer. This is where the - * proc header will be read into. - */ - req->msg.iov_base = rs->fragcurrent; - req->msg.iov_len = rs->remainingfrag; - ret = 0; - -err_reply: - if (ret == -1) - ret = nfs_rpcsvc_error_reply (req); - - /* No need to propagate error beyond this function since the reply - * has now been queued. */ - ret = 0; -err: - return; -} - - -void -nfs_rpcsvc_update_vectored_verfsz (rpcsvc_conn_t *conn) -{ - rpcsvc_record_state_t *rs = NULL; - uint32_t verflen = 0; - - if (!conn) - return; - - rs = &conn->rstate; - - verflen = nfs_rpcsvc_call_verflen (rs); - rs->recordsize += 8; - if (verflen > 0) { - rs->remainingfrag = verflen; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC verf remaining: " - " %d", rs->remainingfrag); - rs->vecstate = RPCSVC_VECTOR_READVERF; - } else { - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC preparing call"); - nfs_rpcsvc_handle_vectored_prep_rpc_call (conn); - } - - return; -} - - -void -nfs_rpcsvc_update_vectored_cred (rpcsvc_record_state_t *rs) -{ - uint32_t credlen = 0; - - if (!rs) - return; - - credlen = nfs_rpcsvc_call_credlen (rs); - /* Update remainingfrag to read the 8 bytes needed for - * reading verf flavour and verf len. - */ - rs->remainingfrag = (2 * sizeof (uint32_t)); - rs->vecstate = RPCSVC_VECTOR_READVERFSZ; - rs->recordsize += credlen; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC verfsz remaining: %d", - rs->remainingfrag); - - return; -} - -void -nfs_rpcsvc_update_vectored_barerpc (rpcsvc_record_state_t *rs) -{ - uint32_t credlen = 0; - - if (!rs) - return; - - credlen = nfs_rpcsvc_call_credlen (rs); - rs->recordsize = RPCSVC_BARERPC_MSGSZ; - if (credlen == 0) { - rs->remainingfrag = 8; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC verfsz remaining" - ": %d", rs->remainingfrag); - rs->vecstate = RPCSVC_VECTOR_READVERFSZ; - } else { - rs->remainingfrag = credlen; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC cred remaining: " - "%d", rs->remainingfrag); - rs->vecstate = RPCSVC_VECTOR_READCRED; - } - - return; -} - - -void -nfs_rpcsvc_handle_vectored_rpc_call (rpcsvc_conn_t *conn) -{ - rpcsvc_actor_t *actor = NULL; - rpcsvc_request_t *req = NULL; - rpcsvc_record_state_t *rs = NULL; - rpcsvc_t *svc = NULL; - int ret = -1; - ssize_t remfrag = -1; - int newbuf = 0; - - if (!conn) - return; - - rs = &conn->rstate; - - req = conn->vectoredreq; - svc = nfs_rpcsvc_conn_rpcsvc (conn); - - if (!req) - goto err; - - actor = nfs_rpcsvc_program_actor (req); - if (!actor) - goto err_reply; - - if (!actor->vector_sizer) { - ret = -1; - nfs_rpcsvc_request_seterr (req, PROC_UNAVAIL); - goto err_reply; - } - - req->msg.iov_len = (unsigned long)((long)rs->fragcurrent - (long)req->msg.iov_base); - nfs_rpcsvc_conn_ref (conn); - THIS = nfs_rpcsvc_request_actorxl (req); - ret = actor->vector_sizer (req, &remfrag, &newbuf); - nfs_rpcsvc_conn_unref (conn); - if (ret == RPCSVC_ACTOR_ERROR) { - ret = -1; - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); - goto err_reply; - } - - if (newbuf) { - rs->vectoriob = iobuf_get (svc->ctx->iobuf_pool); - rs->fragcurrent = iobuf_ptr (rs->vectoriob); - rs->vecstate = RPCSVC_VECTOR_READVEC; - rs->remainingfrag = remfrag; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC buf remaining:" - " %d", rs->remainingfrag); - } else { - rs->remainingfrag = remfrag; - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC proc remaining:" - " %d", rs->remainingfrag); - } - - ret = 0; -err_reply: - if (ret == -1) - ret = nfs_rpcsvc_error_reply (req); - - /* No need to propagate error beyond this function since the reply - * has now been queued. */ - ret = 0; -err: - return; -} - - - -void -nfs_rpcsvc_record_vectored_call_actor (rpcsvc_conn_t *conn) -{ - rpcsvc_actor_t *actor = NULL; - rpcsvc_request_t *req = NULL; - rpcsvc_record_state_t *rs = NULL; - rpcsvc_t *svc = NULL; - int ret = -1; - - if (!conn) - return; - - rs = &conn->rstate; - req = conn->vectoredreq; - svc = nfs_rpcsvc_conn_rpcsvc (conn); - - if (!req) - goto err; - - actor = nfs_rpcsvc_program_actor (req); - if (!actor) - goto err_reply; - - if (actor->vector_actor) { - nfs_rpcsvc_conn_ref (conn); - THIS = nfs_rpcsvc_request_actorxl (req); - ret = actor->vector_actor (req, rs->vectoriob); - } else { - nfs_rpcsvc_request_seterr (req, PROC_UNAVAIL); - gf_log (GF_RPCSVC, GF_LOG_ERROR, "No vectored handler present"); - ret = RPCSVC_ACTOR_ERROR; - } - -err_reply: - if (ret == RPCSVC_ACTOR_ERROR) - ret = nfs_rpcsvc_error_reply (req); - else if (ret == RPCSVC_ACTOR_IGNORE) - mem_put (conn->rxpool, req); - - /* No need to propagate error beyond this function since the reply - * has now been queued. */ - ret = 0; -err: - return; -} - - - -ssize_t -nfs_rpcsvc_update_vectored_state (rpcsvc_conn_t *conn) -{ - rpcsvc_record_state_t *rs = NULL; - rpcsvc_t *svc = NULL; - - if (!conn) - return 0; - - /* At this point, we can be confident that the activeiob contains - * exactly the first RPCSVC_BARERPC_MSGSZ bytes needed in order to - * determine the program and actor. So the next state will be - * to read the credentials. - * - * But first, try to determine how many more bytes do we need from the - * network to complete the RPC message including the credentials. - */ - - rs = &conn->rstate; - if (nfs_rpcsvc_record_vectored_baremsg (rs)) - nfs_rpcsvc_update_vectored_barerpc (rs); - else if (nfs_rpcsvc_record_vectored_cred (rs)) - nfs_rpcsvc_update_vectored_cred (rs); - else if (nfs_rpcsvc_record_vectored_verfsz (rs)) - nfs_rpcsvc_update_vectored_verfsz (conn); - else if (nfs_rpcsvc_record_vectored_verfread (rs)) { - nfs_rpcsvc_update_vectored_verf (rs); - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC preparing call"); - nfs_rpcsvc_handle_vectored_prep_rpc_call (conn); - } else if (nfs_rpcsvc_record_vectored_readprochdr (rs)) - nfs_rpcsvc_handle_vectored_rpc_call (conn); - else if (nfs_rpcsvc_record_vectored_ignore (rs)) { - svc = nfs_rpcsvc_conn_rpcsvc (conn); - nfs_rpcsvc_record_init (rs, svc->ctx->iobuf_pool); - } else if (nfs_rpcsvc_record_vectored_readvec (rs)) { - svc = nfs_rpcsvc_conn_rpcsvc (conn); - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored RPC vector read"); - nfs_rpcsvc_record_vectored_call_actor (conn); - nfs_rpcsvc_record_init (rs, svc->ctx->iobuf_pool); - } - - return 0; -} - - -ssize_t -nfs_rpcsvc_record_read_partial_frag (rpcsvc_record_state_t *rs, - ssize_t dataread); - -ssize_t -nfs_rpcsvc_update_vectored_msg (rpcsvc_conn_t *conn, ssize_t dataread) -{ - - if (!conn) - return dataread; - - /* find out how much of the bare msg is pending and set that up to be - * read into the updated fragcurrent along with the updated size into - * remainingfrag. - */ - - - /* Incidently, the logic needed here is similar to a regular partial - * fragment read since we've already set the remainingfrag member in - * rstate to be RPCSVC_BARERPC_MSGSZ for the purpose of a vectored - * fragment. - */ - return nfs_rpcsvc_record_read_partial_frag (&conn->rstate, dataread); -} - -/* FIX: As a first version of vectored reading, I am assuming dataread will - * always be equal to RPCSVC_BARERPC_MSGSZ for the sake of simplicity on the - * belief that we're never actually reading more bytes than needed in each - * poll_in. - */ -ssize_t -nfs_rpcsvc_handle_vectored_frag (rpcsvc_conn_t *conn, ssize_t dataread) -{ - if (!conn) - return dataread; - - /* At this point we can be confident that only the frag size has been - * read from the network. Now it is up to us to have the remaining RPC - * fields given to us here. - */ - - /* Since the poll_in handler uses the remainingfrag field to determine - * how much to read from the network, we'll hack this scheme to tell - * the poll_in to read at most RPCSVC_BARERPC_MSGSZ bytes. This is done - * to, as a first step, identify which (program, actor) we need to call. - */ - - dataread = nfs_rpcsvc_update_vectored_msg (conn, dataread); - - if (conn->rstate.remainingfrag == 0) { - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored frag complete"); - dataread = nfs_rpcsvc_update_vectored_state (conn); - } - - return dataread; -} - - -int -nfs_rpcsvc_record_update_state (rpcsvc_conn_t *conn, ssize_t dataread) -{ - rpcsvc_record_state_t *rs = NULL; - rpcsvc_t *svc = NULL; - - if (!conn) - return -1; - - rs = &conn->rstate; - /* At entry into this function, fragcurrent will be pointing to the\ - * start of the area into which dataread number of bytes were read. - */ - - if (nfs_rpcsvc_record_readfraghdr(rs)) - dataread = nfs_rpcsvc_record_update_fraghdr (rs, dataread); - - if (nfs_rpcsvc_record_readfrag(rs)) { - /* The minimum needed for triggering the vectored handler is - * the frag size field. The fragsize member remains set to this - * size till this request is completely extracted from the - * network. Once all the data has been read from the network, - * the request structure would've been created. The point being - * that even if it takes multiple calls to network IO for - * getting the vectored fragment, we can continue to use this - * condition as the flag to tell us that this is a vectored - * fragment. - */ - if ((dataread > 0) && (nfs_rpcsvc_record_vectored (rs))) { - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Vectored frag"); - dataread = nfs_rpcsvc_handle_vectored_frag (conn, - dataread); - } else if (dataread > 0) { - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Regular frag"); - dataread = nfs_rpcsvc_record_update_frag (rs, dataread); - } - } - - /* This should not happen. We are never reading more than the current - * fragment needs. Something is seriously wrong. - */ - if (dataread > 0) { - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Data Left: %zd", dataread); - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Unwanted data read from " - " connection."); - } - - /* If we're now supposed to wait for a new fragment header and if the - * fragment that we just completed in the previous call to - * rpcsvc_record_update_frag was the last fragment for the current - * RPC record, then, it is time to perform the translation from - * XDR formatted buffer in activeiob followed by the upcall to the - * protocol actor. - */ - if ((nfs_rpcsvc_record_readfraghdr(rs)) && (rs->islastfrag)) { - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Full Record Received."); - nfs_rpcsvc_handle_rpc_call (conn); - svc = nfs_rpcsvc_conn_rpcsvc (conn); - nfs_rpcsvc_record_init (rs, svc->ctx->iobuf_pool); - } - - return 0; -} - - -char * -nfs_rpcsvc_record_read_addr (rpcsvc_record_state_t *rs) -{ - - if (nfs_rpcsvc_record_readfraghdr (rs)) - return nfs_rpcsvc_record_currenthdr_addr (rs); - else if (nfs_rpcsvc_record_readfrag (rs)) - return nfs_rpcsvc_record_currentfrag_addr (rs); - - return NULL; -} - - -int -nfs_rpcsvc_conn_data_poll_in (rpcsvc_conn_t *conn) -{ - ssize_t dataread = -1; - size_t readsize = 0; - char *readaddr = NULL; - int ret = -1; - - readaddr = nfs_rpcsvc_record_read_addr (&conn->rstate); - if (!readaddr) - goto err; - - readsize = nfs_rpcsvc_record_read_size (&conn->rstate); - if (readsize == -1) - goto err; - - dataread = nfs_rpcsvc_socket_read (conn->sockfd, readaddr, readsize); - gf_log (GF_RPCSVC, GF_LOG_TRACE, "conn: 0x%lx, readsize: %zu, dataread:" - "%zd", (long)conn, readsize, dataread); - - if (dataread > 0) - ret = nfs_rpcsvc_record_update_state (conn, dataread); - -err: - return ret; -} - - -int -nfs_rpcsvc_conn_data_poll_err (rpcsvc_conn_t *conn) -{ - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Received error event"); - nfs_rpcsvc_conn_deinit (conn); - return 0; -} - - -int -__nfs_rpcsvc_conn_data_poll_out (rpcsvc_conn_t *conn) -{ - rpcsvc_txbuf_t *txbuf = NULL; - rpcsvc_txbuf_t *tmp = NULL; - ssize_t written = -1; - char *writeaddr = NULL; - size_t writesize = -1; - int eagain = 0; - - if (!conn) - return -1; - - /* Attempt transmission of each of the pending buffers */ - list_for_each_entry_safe (txbuf, tmp, &conn->txbufs, txlist) { -tx_remaining: - eagain = 0; - writeaddr = (char *)(txbuf->buf.iov_base + txbuf->offset); - writesize = (txbuf->buf.iov_len - txbuf->offset); - - if (txbuf->txbehave & RPCSVC_TXB_FIRST) { - gf_log (GF_RPCSVC, GF_LOG_TRACE, "First Tx Buf"); - nfs_rpcsvc_socket_block_tx (conn->sockfd); - } - - written = nfs_rpcsvc_socket_write (conn->sockfd, writeaddr, - writesize, &eagain); - if (txbuf->txbehave & RPCSVC_TXB_LAST) { - gf_log (GF_RPCSVC, GF_LOG_TRACE, "Last Tx Buf"); - nfs_rpcsvc_socket_unblock_tx (conn->sockfd); - } - gf_log (GF_RPCSVC, GF_LOG_TRACE, "conn: 0x%lx, Tx request: %zu," - " Tx sent: %zd", (long)conn, writesize, written); - - /* There was an error transmitting this buffer */ - if (written == -1) - break; - - if (written >= 0) - txbuf->offset += written; - - /* If the current buffer has been completely transmitted, - * delete it from the list and move on to the next buffer. - */ - if (txbuf->offset == txbuf->buf.iov_len) { - /* It doesnt matter who ref'ed this iobuf, rpcsvc for - * its own header or a RPC program. - */ - if (txbuf->iob) - iobuf_unref (txbuf->iob); - if (txbuf->iobref) - iobref_unref (txbuf->iobref); - - list_del (&txbuf->txlist); - mem_put (conn->txpool, txbuf); - } else { - /* If the current buffer is incompletely tx'd, do not - * go to the head of the loop, since that moves us to - * the next buffer. - * - * BUT, if the current transmission exited due to EAGAIN - * we need to leave the buffers where they are and come - * back later for retransmission. - */ - if (!eagain) - goto tx_remaining; - else - break; - } - - } - - /* If we've broken out of the loop above then we must unblock - * the transmission now. - */ - nfs_rpcsvc_socket_unblock_tx (conn->sockfd); - if (list_empty (&conn->txbufs)) - conn->eventidx = event_select_on (conn->stage->eventpool, - conn->sockfd, conn->eventidx, - -1, 0); - - return 0; -} - - -int -nfs_rpcsvc_conn_data_poll_out (rpcsvc_conn_t *conn) -{ - if (!conn) - return -1; - - - pthread_mutex_lock (&conn->connlock); - { - __nfs_rpcsvc_conn_data_poll_out (conn); - } - pthread_mutex_unlock (&conn->connlock); - - return 0; -} - - -int -nfs_rpcsvc_conn_data_handler (int fd, int idx, void *data, int poll_in, - int poll_out, int poll_err) -{ - rpcsvc_conn_t *conn = NULL; - int ret = 0; - - if (!data) - return 0; - - conn = (rpcsvc_conn_t *)data; - - if (poll_out) - ret = nfs_rpcsvc_conn_data_poll_out (conn); - - if (poll_err) { - ret = nfs_rpcsvc_conn_data_poll_err (conn); - return 0; - } - - if (poll_in) { - ret = 0; - ret = nfs_rpcsvc_conn_data_poll_in (conn); - } - - if (ret == -1) - nfs_rpcsvc_conn_data_poll_err (conn); - - return 0; -} - - -int -nfs_rpcsvc_conn_listening_handler (int fd, int idx, void *data, int poll_in, - int poll_out, int poll_err) -{ - rpcsvc_conn_t *newconn = NULL; - rpcsvc_stage_t *selectedstage = NULL; - int ret = -1; - rpcsvc_conn_t *conn = NULL; - rpcsvc_t *svc = NULL; - - if (!poll_in) - return 0; - - conn = (rpcsvc_conn_t *)data; - svc = nfs_rpcsvc_conn_rpcsvc (conn); - newconn = nfs_rpcsvc_conn_accept_init (svc, fd); - if (!newconn) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "failed to accept connection"); - goto err; - } - - selectedstage = nfs_rpcsvc_select_stage (svc); - if (!selectedstage) - goto close_err; - - /* Now that we've accepted the connection, we need to associate - * its events to a stage. - */ - ret = nfs_rpcsvc_stage_conn_associate (selectedstage, newconn, - nfs_rpcsvc_conn_data_handler, - newconn); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "could not associated stage " - " with new connection"); - goto close_err; - } - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "New Connection"); - ret = 0; -close_err: - if (ret == -1) - nfs_rpcsvc_conn_unref (newconn); - -err: - return ret; -} - - -/* Register the program with the local portmapper service. */ -int -nfs_rpcsvc_program_register_portmap (rpcsvc_t *svc, rpcsvc_program_t *newprog) -{ - if (!newprog) - return -1; - - if (!svc->register_portmap) - return 0; - - if (!(pmap_set(newprog->prognum, newprog->progver, IPPROTO_TCP, - newprog->progport))) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Could not register with" - " portmap"); - return -1; - } - - return 0; -} - - -int -nfs_rpcsvc_program_unregister_portmap (rpcsvc_t *svc, rpcsvc_program_t *prog) -{ - if (!prog) - return -1; - - if (!svc->register_portmap) - return 0; - - if (!(pmap_unset(prog->prognum, prog->progver))) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Could not unregister with" - " portmap"); - return -1; - } - - return 0; -} - - -int -nfs_rpcsvc_stage_program_register (rpcsvc_stage_t *stg, - rpcsvc_program_t *newprog) -{ - rpcsvc_conn_t *newconn = NULL; - rpcsvc_t *svc = NULL; - - if ((!stg) || (!newprog)) - return -1; - - svc = nfs_rpcsvc_stage_service (stg); - /* Create a listening socket */ - newconn = nfs_rpcsvc_conn_listen_init (svc, newprog); - if (!newconn) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "could not create listening" - " connection"); - return -1; - } - - if ((nfs_rpcsvc_stage_conn_associate (stg, newconn, - nfs_rpcsvc_conn_listening_handler, - newconn)) == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR,"could not associate stage with" - " listening connection"); - return -1; - } - - return 0; -} - - -int -nfs_rpcsvc_program_register (rpcsvc_t *svc, rpcsvc_program_t program) -{ - rpcsvc_program_t *newprog = NULL; - rpcsvc_stage_t *selectedstage = NULL; - int ret = -1; - - if (!svc) - return -1; - - newprog = GF_CALLOC (1, sizeof(*newprog),gf_common_mt_rpcsvc_program_t); - if (!newprog) - return -1; - - if (!program.actors) - goto free_prog; - - memcpy (newprog, &program, sizeof (program)); - INIT_LIST_HEAD (&newprog->proglist); - list_add_tail (&newprog->proglist, &svc->allprograms); - selectedstage = nfs_rpcsvc_select_stage (svc); - - ret = nfs_rpcsvc_stage_program_register (selectedstage, newprog); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "stage registration of program" - " failed"); - goto free_prog; - } - - ret = nfs_rpcsvc_program_register_portmap (svc, newprog); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "portmap registration of" - " program failed"); - goto free_prog; - } - - ret = 0; - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "New program registered: %s, Num: %d," - " Ver: %d, Port: %d", newprog->progname, newprog->prognum, - newprog->progver, newprog->progport); - -free_prog: - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Program registration failed:" - " %s, Num: %d, Ver: %d, Port: %d", newprog->progname, - newprog->prognum, newprog->progver, newprog->progport); - list_del (&newprog->proglist); - GF_FREE (newprog); - } - - return ret; -} - -/* The only difference between the generic submit and this one is that the - * generic submit is also used for submitting RPC error replies in where there - * are no payloads so the msgvec and msgbuf can be NULL. - * Since RPC programs should be using this function along with their payloads - * we must perform NULL checks before calling the generic submit. - */ -int -nfs_rpcsvc_submit_message (rpcsvc_request_t *req, struct iovec msgvec, - struct iobuf *msg) -{ - if ((!req) || (!req->conn) || (!msg) || (!msgvec.iov_base)) - return -1; - - return nfs_rpcsvc_submit_generic (req, msgvec, msg); -} - - -int -nfs_rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t prog) -{ - int ret = -1; - - if (!svc) - return -1; - - /* TODO: De-init the listening connection for this program. */ - ret = nfs_rpcsvc_program_unregister_portmap (svc, &prog); - if (ret == -1) { - gf_log (GF_RPCSVC, GF_LOG_ERROR, "portmap unregistration of" - " program failed"); - goto err; - } - - ret = 0; - gf_log (GF_RPCSVC, GF_LOG_DEBUG, "Program unregistered: %s, Num: %d," - " Ver: %d, Port: %d", prog.progname, prog.prognum, - prog.progver, prog.progport); - -err: - if (ret == -1) - gf_log (GF_RPCSVC, GF_LOG_ERROR, "Program unregistration failed" - ": %s, Num: %d, Ver: %d, Port: %d", prog.progname, - prog.prognum, prog.progver, prog.progport); - - return ret; -} - - -int -nfs_rpcsvc_conn_peername (rpcsvc_conn_t *conn, char *hostname, int hostlen) -{ - if (!conn) - return -1; - - return nfs_rpcsvc_socket_peername (conn->sockfd, hostname, hostlen); -} - - -int -nfs_rpcsvc_conn_peeraddr (rpcsvc_conn_t *conn, char *addrstr, int addrlen, - struct sockaddr *sa, socklen_t sasize) -{ - if (!conn) - return -1; - - return nfs_rpcsvc_socket_peeraddr (conn->sockfd, addrstr, addrlen, sa, - sasize); -} - diff --git a/xlators/nfs/lib/src/rpcsvc.h b/xlators/nfs/lib/src/rpcsvc.h deleted file mode 100644 index 4e7c8184547..00000000000 --- a/xlators/nfs/lib/src/rpcsvc.h +++ /dev/null @@ -1,728 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - -#ifndef _NFS_RPCSVC_H -#define _NFS_RPCSVC_H - - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include "event.h" -#include "logging.h" -#include "dict.h" -#include "mem-pool.h" -#include "list.h" -#include "iobuf.h" -#include "xdr-rpc.h" -#include "glusterfs.h" -#include "xlator.h" - -#include <pthread.h> -#include <sys/uio.h> - -#ifdef GF_DARWIN_HOST_OS -#include <nfs/rpcv2.h> -#define NGRPS RPCAUTH_UNIXGIDS -#endif - -#define GF_RPCSVC "nfsrpc" -#define RPCSVC_THREAD_STACK_SIZE ((size_t)(1024 * GF_UNIT_KB)) - -#define RPCSVC_DEFAULT_MEMFACTOR 15 -#define RPCSVC_EVENTPOOL_SIZE_MULT 1024 -#define RPCSVC_POOLCOUNT_MULT 35 -#define RPCSVC_CONN_READ (128 * GF_UNIT_KB) -#define RPCSVC_PAGE_SIZE (128 * GF_UNIT_KB) - -/* Defines for RPC record and fragment assembly */ - -#define RPCSVC_FRAGHDR_SIZE 4 /* 4-byte RPC fragment header size */ - -/* Given the 4-byte fragment header, returns non-zero if this fragment - * is the last fragment for the RPC record being assemebled. - * RPC Record marking standard defines a 32 bit value as the fragment - * header with the MSB signifying whether the fragment is the last - * fragment for the record being asembled. - */ -#define RPCSVC_LASTFRAG(fraghdr) ((uint32_t)(fraghdr & 0x80000000U)) - -/* Given the 4-byte fragment header, extracts the bits that contain - * the fragment size. - */ -#define RPCSVC_FRAGSIZE(fraghdr) ((uint32_t)(fraghdr & 0x7fffffffU)) - -/* RPC Record States */ -#define RPCSVC_READ_FRAGHDR 1 -#define RPCSVC_READ_FRAG 2 -/* The size in bytes, if crossed by a fragment will be handed over to the - * vectored actor so that it can allocate its buffers the way it wants. - * In our RPC layer, we assume that vectored RPC requests/records are never - * spread over multiple RPC fragments since that prevents us from determining - * whether the record should be handled in RPC layer completely or handed to - * the vectored handler. - */ -#define RPCSVC_VECTORED_FRAGSZ 4096 -#define RPCSVC_VECTOR_READCRED 1003 -#define RPCSVC_VECTOR_READVERFSZ 1004 -#define RPCSVC_VECTOR_READVERF 1005 -#define RPCSVC_VECTOR_IGNORE 1006 -#define RPCSVC_VECTOR_READVEC 1007 -#define RPCSVC_VECTOR_READPROCHDR 1008 - -#define nfs_rpcsvc_record_vectored_baremsg(rs) (((rs)->state == RPCSVC_READ_FRAG) && (rs)->vecstate == 0) -#define nfs_rpcsvc_record_vectored_cred(rs) ((rs)->vecstate == RPCSVC_VECTOR_READCRED) -#define nfs_rpcsvc_record_vectored_verfsz(rs) ((rs)->vecstate == RPCSVC_VECTOR_READVERFSZ) -#define nfs_rpcsvc_record_vectored_verfread(rs) ((rs)->vecstate == RPCSVC_VECTOR_READVERF) -#define nfs_rpcsvc_record_vectored_ignore(rs) ((rs)->vecstate == RPCSVC_VECTOR_IGNORE) -#define nfs_rpcsvc_record_vectored_readvec(rs) ((rs)->vecstate == RPCSVC_VECTOR_READVEC) -#define nfs_rpcsvc_record_vectored_readprochdr(rs) ((rs)->vecstate == RPCSVC_VECTOR_READPROCHDR) -#define nfs_rpcsvc_record_vectored(rs) ((rs)->fragsize > RPCSVC_VECTORED_FRAGSZ) -/* Includes bytes up to and including the credential length field. The credlen - * will be followed by @credlen bytes of credential data which will have to be - * read separately by the vectored reader. After the credentials comes the - * verifier which will also have to be read separately including the 8 bytes of - * verf flavour and verflen. - */ -#define RPCSVC_BARERPC_MSGSZ 32 -#define nfs_rpcsvc_record_readfraghdr(rs) ((rs)->state == RPCSVC_READ_FRAGHDR) -#define nfs_rpcsvc_record_readfrag(rs) ((rs)->state == RPCSVC_READ_FRAG) - -#define nfs_rpcsvc_conn_rpcsvc(conn) ((conn)->stage->svc) -#define RPCSVC_LOWVERS 2 -#define RPCSVC_HIGHVERS 2 - -typedef struct rpc_svc_program rpcsvc_program_t; -/* A Stage is the event handler thread together with - * the connections being served by this thread. - * It is called a stage because all the actors, i.e, protocol actors, - * defined by higher level users of the RPC layer, are executed here. - */ -typedef struct rpc_svc_stage_context { - pthread_t tid; - struct event_pool *eventpool; /* Per-stage event-pool */ - void *svc; /* Ref to the rpcsvc_t */ -} rpcsvc_stage_t; - - -/* RPC Records and Fragments assembly state. - * This is per-connection state that is used to determine - * how much data has come in, how much more needs to be read - * and where it needs to be read. - * - * All this state is then used to re-assemble network buffers into - * RPC fragments, which are then re-assembled into RPC records. - * - * See RFC 1831: "RPC: Remote Procedure Call Protocol Specification Version 2", - * particularly the section on Record Marking Standard. - */ -typedef struct rpcsvc_record_state { - - /* Pending messages storage - * This memory area is currently being used to assemble - * the latest RPC record. - * - * Note that this buffer contains the data other than the - * fragment headers received from the network. This is so that we can - * directly pass this buffer to higher layers without requiring to - * perform memory copies and marshalling of data. - */ - struct iobuf *activeiob; - - struct iobuf *vectoriob; - /* The pointer into activeiob memory, into which will go the - * contents from the next read from the network. - */ - char *fragcurrent; - - /* Size of the currently incomplete RPC fragment. - * This is filled in when the fragment header comes in. - * Even though only the 31 least significant bits are used from the - * fragment header, we use a 32 bit variable to store the size. - */ - uint32_t fragsize; - - /* The fragment header is always read in here so that - * the RPC messages contained in a RPC records can be processed - * separately without copying them out of the activeiob above. - */ - char fragheader[RPCSVC_FRAGHDR_SIZE]; - char *hdrcurrent; - - /* Bytes remaining to come in for the current fragment. */ - uint32_t remainingfrag; - - /* It is possible for the frag header to be split over separate - * read calls, so we need to keep track of how much is left. - */ - uint32_t remainingfraghdr; - - /* Record size, the total size of the RPC record, i.e. the total - * of all fragment sizes received till now. Does not include the size - * of a partial fragment which is continuing to be assembled right now. - */ - int recordsize; - - /* Current state of the record */ - int state; - - /* Current state of the vectored reading process. */ - int vecstate; - - /* Set to non-zero when the currently partial or complete fragment is - * the last fragment being received for the current RPC record. - */ - uint32_t islastfrag; - -} rpcsvc_record_state_t; - - -#define RPCSVC_CONNSTATE_CONNECTED 1 -#define RPCSVC_CONNSTATE_DISCONNECTED 2 - -#define nfs_rpcsvc_conn_check_active(conn) ((conn)->connstate==RPCSVC_CONNSTATE_CONNECTED) - -typedef struct rpcsvc_request rpcsvc_request_t; -/* Contains the state for each connection that is used for transmitting and - * receiving RPC messages. - * - * There is also an eventidx because each connection's fd is added to the event - * pool of the stage to which a connection belongs. - * Anything that can be accessed by a RPC program must be synced through - * connlock. - */ -typedef struct rpc_conn_state { - - /* Transport or connection state */ - - /* Once we start working on RDMA support, this TCP specific state will - * have to be abstracted away. - */ - int sockfd; - int eventidx; - int windowsize; - - /* Reference to the stage which is handling this - * connection. - */ - rpcsvc_stage_t *stage; - - /* RPC Records and Fragments assembly state. - * All incoming data is staged here before being - * called a full RPC message. - */ - rpcsvc_record_state_t rstate; - - /* It is possible that a client disconnects while - * the higher layer RPC service is busy in a call. - * In this case, we cannot just free the conn - * structure, since the higher layer service could - * still have a reference to it. - * The refcount avoids freeing until all references - * have been given up, although the connection is clos()ed at the first - * call to unref. - */ - int connref; - pthread_mutex_t connlock; - int connstate; - - /* List of buffers awaiting transmission */ - /* Accesses to txbufs between multiple threads calling - * rpcsvc_submit is synced through connlock. Prefer spinlock over - * mutex because this is a low overhead op that needs simple - * appending to the tx list. - */ - struct list_head txbufs; - - /* Mem pool for the txbufs above. */ - struct mem_pool *txpool; - - /* Memory pool for rpcsvc_request_t */ - struct mem_pool *rxpool; - - /* The request which hasnt yet been handed to the RPC program because - * this request is being treated as a vector request and so needs some - * more data to be got from the network. - */ - rpcsvc_request_t *vectoredreq; -} rpcsvc_conn_t; - - -#define RPCSVC_MAX_AUTH_BYTES 400 -typedef struct rpcsvc_auth_data { - int flavour; - int datalen; - char authdata[RPCSVC_MAX_AUTH_BYTES]; -} rpcsvc_auth_data_t; - -#define nfs_rpcsvc_auth_flavour(au) ((au).flavour) - -/* The container for the RPC call handed up to an actor. - * Dynamically allocated. Lives till the call reply is completely - * transmitted. - * */ -struct rpcsvc_request { - /* Connection over which this request came. */ - rpcsvc_conn_t *conn; - - /* The identifier for the call from client. - * Needed to pair the reply with the call. - */ - uint32_t xid; - - int prognum; - - int progver; - - int procnum; - /* Uid and gid filled by the rpc-auth module during the authentication - * phase. - */ - uid_t uid; - gid_t gid; - - /* Might want to move this to AUTH_UNIX specifix state since this array - * is not available for every authenticatino scheme. - */ - gid_t auxgids[NGRPS]; - int auxgidcount; - - - /* The RPC message payload, contains the data required - * by the program actors. This is the buffer that will need to - * be de-xdred by the actor. - */ - struct iovec msg; - - /* The full message buffer allocated to store the RPC headers. - * This buffer is ref'd when allocated why RPC svc and unref'd after - * the buffer is handed to the actor. That means if the actor or any - * higher layer wants to keep this buffer around, they too must ref it - * right after entering the program actor. - */ - struct iobuf *recordiob; - - /* Status of the RPC call, whether it was accepted or denied. */ - int rpc_stat; - - /* In case, the call was denied, the RPC error is stored here - * till the reply is sent. - */ - int rpc_err; - - /* In case the failure happened because of an authentication problem - * , this value needs to be assigned the correct auth error number. - */ - int auth_err; - - /* There can be cases of RPC requests where the reply needs to - * be built from multiple sources. For eg. where even the NFS reply can - * contain a payload, as in the NFSv3 read reply. Here the RPC header - * ,NFS header and the read data are brought together separately from - * different buffers, so we need to stage the buffers temporarily here - * before all of them get added to the connection's transmission list. - */ - struct list_head txlist; - - /* While the reply record is being built, this variable keeps track - * of how many bytes have been added to the record. - */ - size_t payloadsize; - - /* The credentials extracted from the rpc request */ - rpcsvc_auth_data_t cred; - - /* The verified extracted from the rpc request. In request side - * processing this contains the verifier sent by the client, on reply - * side processing, it is filled with the verified that will be - * sent to the client. - */ - rpcsvc_auth_data_t verf; - - /* Container for a RPC program wanting to store a temp - * request-specific item. - */ - void *private; - - /* To save a ref to the program for which this request is. */ - rpcsvc_program_t *program; -}; - -#define nfs_rpcsvc_request_program(req) ((rpcsvc_program_t *)((req)->program)) -#define nfs_rpcsvc_request_program_private(req) ((req)->program->private) -#define nfs_rpcsvc_request_conn(req) (req)->conn -#define nfs_rpcsvc_program_xlator(prg) ((prg)->actorxl) -#define nfs_rpcsvc_request_actorxl(rq) (nfs_rpcsvc_request_program(rq))->actorxl -#define nfs_rpcsvc_request_accepted(req) ((req)->rpc_stat == MSG_ACCEPTED) -#define nfs_rpcsvc_request_accepted_success(req) ((req)->rpc_err == SUCCESS) -#define nfs_rpcsvc_request_uid(req) ((req)->uid) -#define nfs_rpcsvc_request_gid(req) ((req)->gid) -#define nfs_rpcsvc_stage_service(stg) ((rpcsvc_t *)((stg)->svc)) -#define nfs_rpcsvc_conn_stage(conn) ((conn)->stage) -#define nfs_rpcsvc_request_service(req) (nfs_rpcsvc_stage_service(nfs_rpcsvc_conn_stage(nfs_rpcsvc_request_conn(req)))) -#define nfs_rpcsvc_request_prog_minauth(req) (nfs_rpcsvc_request_program(req)->min_auth) -#define nfs_rpcsvc_request_cred_flavour(req) (nfs_rpcsvc_auth_flavour(req->cred)) -#define nfs_rpcsvc_request_verf_flavour(req) (nfs_rpcsvc_auth_flavour(req->verf)) - -#define nfs_rpcsvc_request_uid(req) ((req)->uid) -#define nfs_rpcsvc_request_gid(req) ((req)->gid) -#define nfs_rpcsvc_request_private(req) ((req)->private) -#define nfs_rpcsvc_request_xid(req) ((req)->xid) -#define nfs_rpcsvc_request_set_private(req,prv) (req)->private = (void *)(prv) -#define nfs_rpcsvc_request_record_iob(rq) ((rq)->recordiob) -#define nfs_rpcsvc_request_record_ref(req) (iobuf_ref ((req)->recordiob)) -#define nfs_rpcsvc_request_record_unref(req) (iobuf_unref ((req)->recordiob)) -#define nfs_rpcsvc_request_procnum(rq) ((rq)->procnum) - - -#define RPCSVC_ACTOR_SUCCESS 0 -#define RPCSVC_ACTOR_ERROR (-1) -#define RPCSVC_ACTOR_IGNORE (-2) - -/* Functor for every type of protocol actor - * must be defined like this. - * - * See the request structure for info on how to handle the request - * in the program actor. - * - * On successful santify checks inside the actor, it should return - * RPCSVC_ACTOR_SUCCESS. - * On an error, on which the RPC layer is expected to return a reply, the actor - * should return RPCSVC_ACTOR_ERROR. - * - */ -typedef int (*rpcsvc_actor) (rpcsvc_request_t *req); -typedef int (*rpcsvc_vector_actor) (rpcsvc_request_t *req, struct iobuf *iob); -typedef int (*rpcsvc_vector_sizer) (rpcsvc_request_t *req, ssize_t *readsize, - int *newiob); - -/* Every protocol actor will also need to specify the function the RPC layer - * will use to serialize or encode the message into XDR format just before - * transmitting on the connection. - */ -typedef void *(*rpcsvc_encode_reply) (void *msg); - -/* Once the reply has been transmitted, the message will have to be de-allocated - * , so every actor will need to provide a function that deallocates the message - * it had allocated as a response. - */ -typedef void (*rpcsvc_deallocate_reply) (void *msg); - - -#define RPCSVC_NAME_MAX 32 -/* The descriptor for each procedure/actor that runs - * over the RPC service. - */ -typedef struct rpc_svc_actor_desc { - char procname[RPCSVC_NAME_MAX]; - int procnum; - rpcsvc_actor actor; - - /* Handler for cases where the RPC requests fragments are large enough - * to benefit from being decoded into aligned memory addresses. While - * decoding the request in a non-vectored manner, due to the nature of - * the XDR scheme, RPC cannot guarantee memory aligned addresses for - * the resulting message-specific structures. Allowing a specialized - * handler for letting the RPC program read the data from the network - * directly into its alligned buffers. - */ - rpcsvc_vector_actor vector_actor; - rpcsvc_vector_sizer vector_sizer; - -} rpcsvc_actor_t; - -/* Describes a program and its version along with the function pointers - * required to handle the procedures/actors of each program/version. - * Never changed ever by any thread so no need for a lock. - */ -struct rpc_svc_program { - struct list_head proglist; - char progname[RPCSVC_NAME_MAX]; - int prognum; - int progver; - uint16_t progport; /* Registered with portmap */ - int progaddrfamily; /* AF_INET or AF_INET6 */ - char *proghost; /* Bind host, can be NULL */ - rpcsvc_actor_t *actors; /* All procedure handlers */ - int numactors; /* Num actors in actor array */ - int proghighvers; /* Highest ver for program - supported by the system. */ - int proglowvers; /* Lowest ver */ - - /* Program specific state handed to actors */ - void *private; - - /* An integer that identifies the min auth strength that is required - * by this protocol, for eg. MOUNT3 needs AUTH_UNIX at least. - * See RFC 1813, Section 5.2.1. - */ - int min_auth; - - /* The translator in whose context the actor must execute. This is - * needed to setup THIS for memory accounting to work correctly. - */ - xlator_t *actorxl; -}; - - -/* Contains global state required for all the RPC services. - */ -typedef struct rpc_svc_state { - - /* Contains the list of rpcsvc_stage_t - * list of (program, version) handlers. - * other options. - */ - - /* At this point, lock is not used to protect anything. Later, it'll - * be used for protecting stages. - */ - pthread_mutex_t rpclock; - - /* This is the first stage that is inited, so that any RPC based - * services that do not need multi-threaded support can just use the - * service right away. This is not added to the stages list - * declared later. - * This is also the stage over which all service listeners are run. - */ - rpcsvc_stage_t *defaultstage; - - /* When we have multi-threaded RPC support, we'll use this to link - * to the multiple Stages. - */ - struct list_head stages; /* All stages */ - - unsigned int memfactor; - - /* List of the authentication schemes available. */ - struct list_head authschemes; - - /* Reference to the options */ - dict_t *options; - - /* Allow insecure ports. */ - int allow_insecure; - - glusterfs_ctx_t *ctx; - - gf_boolean_t register_portmap; - - struct list_head allprograms; -} rpcsvc_t; - - -/* All users of RPC services should use this API to register their - * procedure handlers. - */ -extern int -nfs_rpcsvc_program_register (rpcsvc_t *svc, rpcsvc_program_t program); - -extern int -nfs_rpcsvc_program_unregister (rpcsvc_t *svc, rpcsvc_program_t program); - -/* Inits the global RPC service data structures. - * Called in main. - */ -extern rpcsvc_t * -nfs_rpcsvc_init (glusterfs_ctx_t *ctx, dict_t *options); - - -extern int -nfs_rpcsvc_submit_message (rpcsvc_request_t * req, struct iovec msg, - struct iobuf *iob); - -int -nfs_rpcsvc_submit_generic (rpcsvc_request_t *req, struct iovec msgvec, - struct iobuf *msg); -#define nfs_rpcsvc_record_currentfrag_addr(rs) ((rs)->fragcurrent) -#define nfs_rpcsvc_record_currenthdr_addr(rs) ((rs)->hdrcurrent) - -#define nfs_rpcsvc_record_update_currentfrag(rs, size) \ - do { \ - (rs)->fragcurrent += size; \ - } while (0) \ - -#define nfs_rpcsvc_record_update_currenthdr(rs, size) \ - do { \ - (rs)->hdrcurrent += size; \ - } while (0) \ - - -/* These are used to differentiate between multiple txbufs which form - * a single RPC record. For eg, one purpose we use these for is to - * prevent dividing a RPC record over multiple TCP segments. Multiple - * TCP segments are possible for a single RPC record because we generally do not - * have control over how the kernel's TCP segments the buffers when putting - * them on the wire. So, on Linux, we use these to set TCP_CORK to create - * a single TCP segment from multiple txbufs that are part of the same RPC - * record. This improves network performance by reducing tiny message - * transmissions. - */ -#define RPCSVC_TXB_FIRST 0x1 -#define RPCSVC_TXB_LAST 0x2 - -/* The list of buffers appended to a connection's pending - * transmission list. - */ -typedef struct rpcsvc_txbuf { - struct list_head txlist; - /* The iobuf which contains the full message to be transmitted */ - struct iobuf *iob; - - /* For vectored messages from an RPC program, we need to be able - * maintain a ref to an iobuf which we do not have access to directly - * except through the iobref which in turn could've been passed to - * the RPC program by a higher layer. - * - * So either the iob is defined or iobref is defined for a reply, - * never both. - */ - struct iobref *iobref; - /* In order to handle non-blocking writes, we'll need to keep track of - * how much data from an iobuf has been written and where the next - * transmission needs to start from. This iov.base points to the base of - * the iobuf, iov.len is the size of iobuf being used for the message - * from the total size in the iobuf. - */ - struct iovec buf; - /* offset is the point from where the next transmission for this buffer - * should start. - */ - size_t offset; - - /* This is a special field that tells us what kind of transmission - * behaviour to provide to a particular buffer. - * See the RPCSVC_TXB_* defines for more info. - */ - int txbehave; -} rpcsvc_txbuf_t; - -extern int -nfs_rpcsvc_error_reply (rpcsvc_request_t *req); - -#define RPCSVC_PEER_STRLEN 1024 -#define RPCSVC_AUTH_ACCEPT 1 -#define RPCSVC_AUTH_REJECT 2 -#define RPCSVC_AUTH_DONTCARE 3 - -extern int -nfs_rpcsvc_conn_peername (rpcsvc_conn_t *conn, char *hostname, int hostlen); - -extern int -nfs_rpcsvc_conn_peeraddr (rpcsvc_conn_t *conn, char *addrstr, int addrlen, - struct sockaddr *returnsa, socklen_t sasize); - -extern int -nfs_rpcsvc_conn_peer_check (dict_t *options, char *volname,rpcsvc_conn_t *conn); - -extern int -nfs_rpcsvc_conn_privport_check (rpcsvc_t *svc, char *volname, - rpcsvc_conn_t *conn); -#define nfs_rpcsvc_request_seterr(req, err) (req)->rpc_err = err -#define nfs_rpcsvc_request_set_autherr(req, err) \ - do { \ - (req)->auth_err = err; \ - (req)->rpc_stat = MSG_DENIED; \ - } while (0) \ - -extern void -nfs_rpcsvc_conn_deinit (rpcsvc_conn_t *conn); -extern void nfs_rpcsvc_conn_ref (rpcsvc_conn_t *conn); -extern void nfs_rpcsvc_conn_unref (rpcsvc_conn_t *conn); - -extern int nfs_rpcsvc_submit_vectors (rpcsvc_request_t *req); - -extern int nfs_rpcsvc_request_attach_vector (rpcsvc_request_t *req, - struct iovec msgvec, - struct iobuf *iob, - struct iobref *ioref, - int finalvector); -extern int -nfs_rpcsvc_request_attach_vectors (rpcsvc_request_t *req, struct iovec *payload, - int vcount, struct iobref *piobref); - -typedef int (*auth_init_conn) (rpcsvc_conn_t *conn, void *priv); -typedef int (*auth_init_request) (rpcsvc_request_t *req, void *priv); -typedef int (*auth_request_authenticate) (rpcsvc_request_t *req, void *priv); - -/* This structure needs to be registered by every authentication scheme. - * Our authentication schemes are stored per connection because - * each connection will end up using a different authentication scheme. - */ -typedef struct rpcsvc_auth_ops { - auth_init_conn conn_init; - auth_init_request request_init; - auth_request_authenticate authenticate; -} rpcsvc_auth_ops_t; - -typedef struct rpcsvc_auth_flavour_desc { - char authname[RPCSVC_NAME_MAX]; - int authnum; - rpcsvc_auth_ops_t *authops; - void *authprivate; -} rpcsvc_auth_t; - -typedef void * (*rpcsvc_auth_initer_t) (rpcsvc_t *svc, dict_t *options); - -struct rpcsvc_auth_list { - struct list_head authlist; - rpcsvc_auth_initer_t init; - /* Should be the name with which we identify the auth scheme given - * in the volfile options. - * This should be different from the authname in rpc_auth_t - * in way that makes it easier to specify this scheme in the volfile. - * This is because the technical names of the schemes can be a bit - * arcane. - */ - char name[RPCSVC_NAME_MAX]; - rpcsvc_auth_t *auth; - int enable; -}; - -extern int -nfs_rpcsvc_auth_request_init (rpcsvc_request_t *req); - -extern int -nfs_rpcsvc_auth_init (rpcsvc_t *svc, dict_t *options); - -extern int -nfs_rpcsvc_auth_conn_init (rpcsvc_conn_t *conn); - -extern int -nfs_rpcsvc_authenticate (rpcsvc_request_t *req); - -extern int -nfs_rpcsvc_auth_array (rpcsvc_t *svc, char *volname, int *autharr, int arrlen); - -/* If the request has been sent using AUTH_UNIX, this function returns the - * auxiliary gids as an array, otherwise, it returns NULL. - * Move to auth-unix specific source file when we need to modularize the - * authentication code even further to support mode auth schemes. - */ -extern gid_t * -nfs_rpcsvc_auth_unix_auxgids (rpcsvc_request_t *req, int *arrlen); - -extern int -nfs_rpcsvc_combine_gen_spec_volume_checks (int gen, int spec); - -extern char * -nfs_rpcsvc_volume_allowed (dict_t *options, char *volname); -#endif diff --git a/xlators/nfs/lib/src/xdr-common.h b/xlators/nfs/lib/src/xdr-common.h deleted file mode 100644 index b3992ab0503..00000000000 --- a/xlators/nfs/lib/src/xdr-common.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - -#ifndef _NFS_XDR_COMMON_H_ -#define _NFS_XDR_COMMON_H_ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <rpc/rpc.h> -#define NFS_XDR_BYTES_PER_UNIT 4 - -/* Returns the address of the byte that follows the - * last byte used for decoding the previous xdr component. - * For eg, once the RPC call for NFS has been decoded, thie macro will return - * the address from which the NFS header starts. - */ -#define nfs_xdr_decoded_remaining_addr(xdr) ((&xdr)->x_private) - -/* Returns the length of the remaining record after the previous decode - * operation completed. - */ -#define nfs_xdr_decoded_remaining_len(xdr) ((&xdr)->x_handy) - -/* Returns the number of bytes used by the last encode operation. */ -#define nfs_xdr_encoded_length(xdr) (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base)) - -#define nfs_xdr_decoded_length(xdr) (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base)) - -#endif diff --git a/xlators/nfs/lib/src/xdr-rpc.c b/xlators/nfs/lib/src/xdr-rpc.c deleted file mode 100644 index 274e118a3c0..00000000000 --- a/xlators/nfs/lib/src/xdr-rpc.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <string.h> -#include <rpc/rpc.h> -#include <rpc/pmap_clnt.h> -#include <arpa/inet.h> -#include <rpc/xdr.h> -#include <sys/uio.h> -#include <rpc/auth_unix.h> - -#include "mem-pool.h" -#include "xdr-rpc.h" -#include "xdr-common.h" -#include "logging.h" - -/* Decodes the XDR format in msgbuf into rpc_msg. - * The remaining payload is returned into payload. - */ -int -nfs_xdr_to_rpc_call (char *msgbuf, size_t len, struct rpc_msg *call, - struct iovec *payload, char *credbytes, char *verfbytes) -{ - XDR xdr; - char opaquebytes[MAX_AUTH_BYTES]; - struct opaque_auth *oa = NULL; - - if ((!msgbuf) || (!call)) - return -1; - - memset (call, 0, sizeof (*call)); - - oa = &call->rm_call.cb_cred; - if (!credbytes) - oa->oa_base = opaquebytes; - else - oa->oa_base = credbytes; - - oa = &call->rm_call.cb_verf; - if (!verfbytes) - oa->oa_base = opaquebytes; - else - oa->oa_base = verfbytes; - - xdrmem_create (&xdr, msgbuf, len, XDR_DECODE); - if (!xdr_callmsg (&xdr, call)) - return -1; - - if (payload) { - payload->iov_base = nfs_xdr_decoded_remaining_addr (xdr); - payload->iov_len = nfs_xdr_decoded_remaining_len (xdr); - } - - return 0; -} - - -bool_t -nfs_true_func (XDR *s, caddr_t *a) -{ - return TRUE; -} - - -int -nfs_rpc_fill_empty_reply (struct rpc_msg *reply, uint32_t xid) -{ - if (!reply) - return -1; - - /* Setting to 0 also results in reply verifier flavor to be - * set to AUTH_NULL which is what we want right now. - */ - memset (reply, 0, sizeof (*reply)); - reply->rm_xid = xid; - reply->rm_direction = REPLY; - - return 0; -} - -int -nfs_rpc_fill_denied_reply (struct rpc_msg *reply, int rjstat, int auth_err) -{ - if (!reply) - return -1; - - reply->rm_reply.rp_stat = MSG_DENIED; - reply->rjcted_rply.rj_stat = rjstat; - if (rjstat == RPC_MISMATCH) { - /* No problem with hardocoding - * RPC version numbers. We only support - * v2 anyway. - */ - reply->rjcted_rply.rj_vers.low = 2; - reply->rjcted_rply.rj_vers.high = 2; - } else if (rjstat == AUTH_ERROR) - reply->rjcted_rply.rj_why = auth_err; - - return 0; -} - - -int -nfs_rpc_fill_accepted_reply (struct rpc_msg *reply, int arstat, int proglow, - int proghigh, int verf, int len, char *vdata) -{ - if (!reply) - return -1; - - reply->rm_reply.rp_stat = MSG_ACCEPTED; - reply->acpted_rply.ar_stat = arstat; - - reply->acpted_rply.ar_verf.oa_flavor = verf; - reply->acpted_rply.ar_verf.oa_length = len; - reply->acpted_rply.ar_verf.oa_base = vdata; - if (arstat == PROG_MISMATCH) { - reply->acpted_rply.ar_vers.low = proglow; - reply->acpted_rply.ar_vers.high = proghigh; - } else if (arstat == SUCCESS) { - - /* This is a hack. I'd really like to build a custom - * XDR library because Sun RPC interface is not very flexible. - */ - reply->acpted_rply.ar_results.proc = (xdrproc_t)nfs_true_func; - reply->acpted_rply.ar_results.where = NULL; - } - - return 0; -} - -int -nfs_rpc_reply_to_xdr (struct rpc_msg *reply, char *dest, size_t len, - struct iovec *dst) -{ - XDR xdr; - - if ((!dest) || (!reply) || (!dst)) - return -1; - - xdrmem_create (&xdr, dest, len, XDR_ENCODE); - if (!xdr_replymsg(&xdr, reply)) - return -1; - - dst->iov_base = dest; - dst->iov_len = nfs_xdr_encoded_length (xdr); - - return 0; -} - - -int -nfs_xdr_to_auth_unix_cred (char *msgbuf, int msglen, struct authunix_parms *au, - char *machname, gid_t *gids) -{ - XDR xdr; - - if ((!msgbuf) || (!machname) || (!gids) || (!au)) - return -1; - - au->aup_machname = machname; -#ifdef GF_DARWIN_HOST_OS - au->aup_gids = (int *)gids; -#else - au->aup_gids = gids; -#endif - - xdrmem_create (&xdr, msgbuf, msglen, XDR_DECODE); - - if (!xdr_authunix_parms (&xdr, au)) - return -1; - - return 0; -} - -ssize_t -nfs_xdr_length_round_up (size_t len, size_t bufsize) -{ - int roundup = 0; - - roundup = len % NFS_XDR_BYTES_PER_UNIT; - if (roundup > 0) - roundup = NFS_XDR_BYTES_PER_UNIT - roundup; - - if ((roundup > 0) && ((roundup + len) <= bufsize)) - len += roundup; - - return len; -} - -int -nfs_xdr_bytes_round_up (struct iovec *vec, size_t bufsize) -{ - vec->iov_len = nfs_xdr_length_round_up (vec->iov_len, bufsize); - return 0; -} - -void -nfs_xdr_vector_round_up (struct iovec *vec, int vcount, uint32_t count) -{ - uint32_t round_count = 0; - - round_count = nfs_xdr_length_round_up (count, 1048576); - round_count -= count; - if (round_count == 0) - return; - - vec[vcount-1].iov_len += round_count; -} diff --git a/xlators/nfs/lib/src/xdr-rpc.h b/xlators/nfs/lib/src/xdr-rpc.h deleted file mode 100644 index ddcbe6655d8..00000000000 --- a/xlators/nfs/lib/src/xdr-rpc.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - -#ifndef _NFS_XDR_RPC_H -#define _NFS_XDR_RPC_H_ - -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - -#include <rpc/rpc.h> -#include <rpc/pmap_clnt.h> -#include <arpa/inet.h> -#include <rpc/xdr.h> -#include <sys/uio.h> - -/* Converts a given network buffer from its XDR format to a structure - * that contains everything an RPC call needs to work. - */ -extern int -nfs_xdr_to_rpc_call (char *msgbuf, size_t len, struct rpc_msg *call, - struct iovec *payload, char *credbytes, char *verfbytes); - -extern int -nfs_rpc_fill_empty_reply (struct rpc_msg *reply, uint32_t xid); - -extern int -nfs_rpc_fill_denied_reply (struct rpc_msg *reply, int rjstat, int auth_err); - -extern int -nfs_rpc_fill_accepted_reply (struct rpc_msg *reply, int arstat, int proglow, - int proghigh, int verf, int len, char *vdata); -extern int -nfs_rpc_reply_to_xdr (struct rpc_msg *reply, char *dest, size_t len, - struct iovec *dst); - -extern int -nfs_xdr_to_auth_unix_cred (char *msgbuf, int msglen, struct authunix_parms *au, - char *machname, gid_t *gids); -/* Macros that simplify accesing the members of an RPC call structure. */ -#define nfs_rpc_call_xid(call) ((call)->rm_xid) -#define nfs_rpc_call_direction(call) ((call)->rm_direction) -#define nfs_rpc_call_rpcvers(call) ((call)->ru.RM_cmb.cb_rpcvers) -#define nfs_rpc_call_program(call) ((call)->ru.RM_cmb.cb_prog) -#define nfs_rpc_call_progver(call) ((call)->ru.RM_cmb.cb_vers) -#define nfs_rpc_call_progproc(call) ((call)->ru.RM_cmb.cb_proc) -#define nfs_rpc_opaque_auth_flavour(oa) ((oa)->oa_flavor) -#define nfs_rpc_opaque_auth_len(oa) ((oa)->oa_length) - -#define nfs_rpc_call_cred_flavour(call) (nfs_rpc_opaque_auth_flavour ((&(call)->ru.RM_cmb.cb_cred))) -#define nfs_rpc_call_cred_len(call) (nfs_rpc_opaque_auth_len ((&(call)->ru.RM_cmb.cb_cred))) - - -#define nfs_rpc_call_verf_flavour(call) (nfs_rpc_opaque_auth_flavour ((&(call)->ru.RM_cmb.cb_verf))) -#define nfs_rpc_call_verf_len(call) (nfs_rpc_opaque_auth_len ((&(call)->ru.RM_cmb.cb_verf))) - -extern int -nfs_xdr_bytes_round_up (struct iovec *vec, size_t bufsize); - -extern ssize_t -nfs_xdr_length_round_up (size_t len, size_t bufsize); - -void -nfs_xdr_vector_round_up (struct iovec *vec, int vcount, uint32_t count); -#endif diff --git a/xlators/nfs/server/src/Makefile.am b/xlators/nfs/server/src/Makefile.am index f8968916c39..8fd28638506 100644 --- a/xlators/nfs/server/src/Makefile.am +++ b/xlators/nfs/server/src/Makefile.am @@ -1,13 +1,17 @@ xlator_LTLIBRARIES = server.la xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/nfs -nfsrpclibdir = $(top_srcdir)/xlators/nfs/lib/src +nfsrpclibdir = $(top_srcdir)/rpc/rpc-lib/src server_la_LDFLAGS = -module -avoidversion -server_la_SOURCES = nfs.c nfs-common.c nfs-fops.c nfs-inodes.c nfs-generics.c mount3.c nfs3-fh.c nfs3.c nfs3-helpers.c $(nfsrpclibdir)/auth-null.c $(nfsrpclibdir)/auth-unix.c $(nfsrpclibdir)/msg-nfs3.c $(nfsrpclibdir)/rpc-socket.c $(nfsrpclibdir)/rpcsvc-auth.c $(nfsrpclibdir)/rpcsvc.c $(nfsrpclibdir)/xdr-nfs3.c $(nfsrpclibdir)/xdr-rpc.c +server_la_SOURCES = nfs.c nfs-common.c nfs-fops.c nfs-inodes.c nfs-generics.c mount3.c nfs3-fh.c nfs3.c nfs3-helpers.c server_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la -noinst_HEADERS = nfs.h nfs-common.h nfs-fops.h nfs-inodes.h nfs-generics.h mount3.h nfs3-fh.h nfs3.h nfs3-helpers.h nfs-mem-types.h $(nfsrpclibdir)/xdr-rpc.h $(nfsrpclibdir)/msg-nfs3.h $(nfsrpclibdir)/xdr-common.h $(nfsrpclibdir)/xdr-nfs3.h $(nfsrpclibdir)/rpc-socket.h $(nfsrpclibdir)/rpcsvc.h +noinst_HEADERS = nfs.h nfs-common.h nfs-fops.h nfs-inodes.h nfs-generics.h mount3.h nfs3-fh.h nfs3.h nfs3-helpers.h nfs-mem-types.h + AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\ + -DLIBDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/auth\" \ -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)\ - -I$(nfsrpclibdir) -L$(xlatordir)/ -I$(CONTRIBDIR)/rbtree + -I$(nfsrpclibdir) -L$(xlatordir)/ -I$(CONTRIBDIR)/rbtree\ + -I$(top_srcdir)/rpc/xdr/src/ \ + -I$(top_srcdir)/contrib/md5/ CLEANFILES = diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c index 643c5ebfaf5..5b765271996 100644 --- a/xlators/nfs/server/src/mount3.c +++ b/xlators/nfs/server/src/mount3.c @@ -56,11 +56,12 @@ mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc) struct iobuf *iob = NULL; struct mount3_state *ms = NULL; int ret = -1; + struct iobref *iobref = NULL; if (!req) return -1; - ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req); + ms = (struct mount3_state *)rpcsvc_request_program_private (req); if (!ms) { gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found"); goto ret; @@ -81,9 +82,18 @@ mnt3svc_submit_reply (rpcsvc_request_t *req, void *arg, mnt3_serializer sfunc) */ outmsg.iov_len = sfunc (outmsg, arg); + iobref = iobref_new (); + if (iobref == NULL) { + gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get iobref"); + goto ret; + } + + iobref_add (iobref, iob); + /* Then, submit the message for transmission. */ - ret = nfs_rpcsvc_submit_message (req, outmsg, iob); + ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref); iobuf_unref (iob); + iobref_unref (iobref); if (ret == -1) { gf_log (GF_MNT, GF_LOG_ERROR, "Reply submission failed"); goto ret; @@ -195,7 +205,7 @@ mnt3svc_update_mountlist (struct mount3_state *ms, rpcsvc_request_t *req, /* Must get the IP or hostname of the client so we * can map it into the mount entry. */ - ret = nfs_rpcsvc_conn_peername (req->conn, me->hostname, MNTPATHLEN); + ret = rpcsvc_transport_peername (req->trans, me->hostname, MNTPATHLEN); if (ret == -1) goto free_err; @@ -260,7 +270,7 @@ mnt3svc_lookup_mount_cbk (call_frame_t *frame, void *cookie, return -1; mntxl = (xlator_t *)cookie; - ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req); + ms = (struct mount3_state *)rpcsvc_request_program_private (req); if (!ms) { gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found"); op_ret = -1; @@ -287,9 +297,9 @@ xmit_res: gf_log (GF_MNT, GF_LOG_DEBUG, "MNT reply: fh %s, status: %d", fhstr, status); if (op_ret == 0) { - svc = nfs_rpcsvc_request_service (req); - autharrlen = nfs_rpcsvc_auth_array (svc, mntxl->name, autharr, - 10); + svc = rpcsvc_request_service (req); + autharrlen = rpcsvc_auth_array (svc, mntxl->name, autharr, + 10); } res = mnt3svc_set_mountres3 (status, &fh, autharr, autharrlen); @@ -502,7 +512,8 @@ __mnt3_resolve_export_subdir_comp (mnt3_resolve_t *mres) &mres->resolveloc, NFS_RESOLVE_CREATE); if ((ret < 0) && (ret != -2)) { gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve and create " - "inode: parent gfid %s, entry %s", uuid_utoa (mres->resolveloc.inode->gfid), nextcomp); + "inode: parent gfid %s, entry %s", + uuid_utoa (mres->resolveloc.inode->gfid), nextcomp); ret = -EFAULT; goto err; } @@ -558,9 +569,9 @@ err: if (op_ret == -1) { gf_log (GF_MNT, GF_LOG_DEBUG, "Mount reply status: %d", mntstat); - svc = nfs_rpcsvc_request_service (mres->req); - autharrlen = nfs_rpcsvc_auth_array (svc, mntxl->name, autharr, - 10); + svc = rpcsvc_request_service (mres->req); + autharrlen = rpcsvc_auth_array (svc, mntxl->name, autharr, + 10); res = mnt3svc_set_mountres3 (mntstat, &fh, autharr, autharrlen); mnt3svc_submit_reply (mres->req, (void *)&res, @@ -735,22 +746,23 @@ int mnt3_check_client_net (struct mount3_state *ms, rpcsvc_request_t *req, xlator_t *targetxl) { + rpcsvc_t *svc = NULL; int ret = -1; if ((!ms) || (!req) || (!targetxl)) return -1; - svc = nfs_rpcsvc_request_service (req); - ret = nfs_rpcsvc_conn_peer_check (svc->options, targetxl->name, - nfs_rpcsvc_request_conn (req)); + svc = rpcsvc_request_service (req); + ret = rpcsvc_transport_peer_check (svc->options, targetxl->name, + rpcsvc_request_transport (req)); if (ret == RPCSVC_AUTH_REJECT) { gf_log (GF_MNT, GF_LOG_TRACE, "Peer not allowed"); goto err; } - ret = nfs_rpcsvc_conn_privport_check (svc, targetxl->name, - nfs_rpcsvc_request_conn (req)); + ret = rpcsvc_transport_privport_check (svc, targetxl->name, + rpcsvc_request_transport (req)); if (ret == RPCSVC_AUTH_REJECT) { gf_log (GF_MNT, GF_LOG_TRACE, "Unprivileged port not allowed"); goto err; @@ -806,10 +818,10 @@ mnt3_find_export (rpcsvc_request_t *req, char *path, struct mnt3_export **e) if ((!req) || (!path) || (!e)) return -1; - ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req); + ms = (struct mount3_state *) rpcsvc_request_program_private (req); if (!ms) { gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); goto err; } @@ -854,17 +866,17 @@ mnt3svc_mnt (rpcsvc_request_t *req) pvec.iov_base = path; pvec.iov_len = MNTPATHLEN; - ret = xdr_to_mountpath (pvec, req->msg); + ret = xdr_to_mountpath (pvec, req->msg[0]); if (ret == -1) { gf_log (GF_MNT, GF_LOG_ERROR, "Failed to decode args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } - ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req); + ms = (struct mount3_state *)rpcsvc_request_program_private (req); if (!ms) { gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = -1; goto rpcerr; } @@ -921,8 +933,7 @@ mnt3svc_null (rpcsvc_request_t *req) gf_log (GF_MNT, GF_LOG_ERROR, "Got NULL request!"); return 0; } - - nfs_rpcsvc_submit_generic (req, dummyvec, NULL); + rpcsvc_submit_generic (req, &dummyvec, 1, NULL, 0, NULL); return 0; } @@ -1028,9 +1039,9 @@ mnt3svc_dump (rpcsvc_request_t *req) if (!req) return -1; - ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req); + ms = (struct mount3_state *)rpcsvc_request_program_private (req); if (!ms) { - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); goto rpcerr; } @@ -1040,7 +1051,7 @@ mnt3svc_dump (rpcsvc_request_t *req) if (!mlist) { if (ret != 0) { - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = -1; goto rpcerr; } else { @@ -1141,22 +1152,22 @@ mnt3svc_umnt (rpcsvc_request_t *req) /* Remove the mount point from the exports list. */ pvec.iov_base = dirpath; pvec.iov_len = MNTPATHLEN; - ret = xdr_to_mountpath (pvec, req->msg);; + ret = xdr_to_mountpath (pvec, req->msg[0]); if (ret == -1) { gf_log (GF_MNT, GF_LOG_ERROR, "Failed decode args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } - ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req); + ms = (struct mount3_state *)rpcsvc_request_program_private (req); if (!ms) { gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = -1; goto rpcerr; } - ret = nfs_rpcsvc_conn_peername (req->conn, hostname, MNTPATHLEN); + ret = rpcsvc_transport_peername (req->trans, hostname, MNTPATHLEN); if (ret != 0) { gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get remote name: %s", gai_strerror (ret)); @@ -1173,13 +1184,13 @@ mnt3svc_umnt (rpcsvc_request_t *req) try_umount_with_addr: if (ret != 0) - ret = nfs_rpcsvc_conn_peeraddr (req->conn, hostname, MNTPATHLEN, - NULL, 0); + ret = rpcsvc_transport_peeraddr (req->trans, hostname, + MNTPATHLEN, NULL, 0); if (ret != 0) { gf_log (GF_MNT, GF_LOG_ERROR, "Failed to get remote addr: %s", gai_strerror (ret)); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); goto rpcerr; } @@ -1247,10 +1258,10 @@ mnt3svc_umntall (rpcsvc_request_t *req) if (!req) return ret; - ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req); + ms = (struct mount3_state *)rpcsvc_request_program_private (req); if (!ms) { gf_log (GF_MNT, GF_LOG_ERROR, "Mount state not present"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); goto rpcerr; } @@ -1306,8 +1317,8 @@ mnt3_xlchildren_to_exports (rpcsvc_t *svc, struct mount3_state *ms) strcpy (elist->ex_dir, ent->expname); - addrstr = nfs_rpcsvc_volume_allowed (svc->options, - ent->vol->name); + addrstr = rpcsvc_volume_allowed (svc->options, + ent->vol->name); if (addrstr) addrstr = gf_strdup (addrstr); else @@ -1354,15 +1365,15 @@ mnt3svc_export (rpcsvc_request_t *req) if (!req) return -1; - ms = (struct mount3_state *)nfs_rpcsvc_request_program_private (req); + ms = (struct mount3_state *)rpcsvc_request_program_private (req); if (!ms) { gf_log (GF_MNT, GF_LOG_ERROR, "mount state not found"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); goto err; } /* Using the children translator names, build the export list */ - elist = mnt3_xlchildren_to_exports (nfs_rpcsvc_request_service (req), + elist = mnt3_xlchildren_to_exports (rpcsvc_request_service (req), ms); /* Do not return error when exports list is empty. An exports list can * be empty when no subvolumes have come up. No point returning error @@ -1754,10 +1765,9 @@ rpcsvc_program_t mnt3prog = { .prognum = MOUNT_PROGRAM, .progver = MOUNT_V3, .progport = GF_MOUNTV3_PORT, - .progaddrfamily = AF_INET, - .proghost = NULL, .actors = mnt3svc_actors, .numactors = MOUNT3_PROC_COUNT, + .min_auth = AUTH_NULL, }; @@ -1766,6 +1776,9 @@ mnt3svc_init (xlator_t *nfsx) { struct mount3_state *mstate = NULL; struct nfs_state *nfs = NULL; + dict_t *options = NULL; + char *portstr = NULL; + int ret = -1; if (!nfsx || !nfsx->private) return NULL; @@ -1780,6 +1793,22 @@ mnt3svc_init (xlator_t *nfsx) } mnt3prog.private = mstate; + options = dict_new (); + + ret = gf_asprintf (&portstr, "%d", GF_MOUNTV3_PORT); + if (ret == -1) + goto err; + + ret = dict_set_dynstr (options, "transport.socket.listen-port", portstr); + if (ret == -1) + goto err; + ret = dict_set_str (options, "transport-type", "socket"); + rpcsvc_create_listeners (nfs->rpcsvc, options, nfsx->name); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "Unable to create listeners"); + dict_unref (options); + goto err; + } return &mnt3prog; err: @@ -1801,10 +1830,9 @@ rpcsvc_program_t mnt1prog = { .prognum = MOUNT_PROGRAM, .progver = MOUNT_V1, .progport = GF_MOUNTV1_PORT, - .progaddrfamily = AF_INET, - .proghost = NULL, .actors = mnt1svc_actors, .numactors = MOUNT1_PROC_COUNT, + .min_auth = AUTH_NULL, }; @@ -1813,6 +1841,9 @@ mnt1svc_init (xlator_t *nfsx) { struct mount3_state *mstate = NULL; struct nfs_state *nfs = NULL; + dict_t *options = NULL; + char *portstr = NULL; + int ret = -1; if (!nfsx || !nfsx->private) return NULL; @@ -1828,6 +1859,23 @@ mnt1svc_init (xlator_t *nfsx) mnt1prog.private = mstate; + options = dict_new (); + + ret = gf_asprintf (&portstr, "%d", GF_MOUNTV1_PORT); + if (ret == -1) + goto err; + + ret = dict_set_dynstr (options, "transport.socket.listen-port", portstr); + if (ret == -1) + goto err; + ret = dict_set_str (options, "transport-type", "socket"); + rpcsvc_create_listeners (nfs->rpcsvc, options, nfsx->name); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "Unable to create listeners"); + dict_unref (options); + goto err; + } + return &mnt1prog; err: return NULL; diff --git a/xlators/nfs/server/src/nfs-fops.c b/xlators/nfs/server/src/nfs-fops.c index 7150cc46887..b4cbc18756d 100644 --- a/xlators/nfs/server/src/nfs-fops.c +++ b/xlators/nfs/server/src/nfs-fops.c @@ -1235,20 +1235,20 @@ nfs_fop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int nfs_fop_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, - struct iobuf *srciob, struct iovec *vector, int32_t count, + struct iobref *srciobref, struct iovec *vector, int32_t count, off_t offset, fop_writev_cbk_t cbk, void *local) { call_frame_t *frame = NULL; int ret = -EFAULT; struct nfs_fop_local *nfl = NULL; - if ((!nfsx) || (!xl) || (!fd) || (!vector) || (!nfu) || (!srciob)) + if ((!nfsx) || (!xl) || (!fd) || (!vector) || (!nfu) || (!srciobref)) return ret; nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err); nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err); nfs_fop_save_root_fd_ino (nfl, fd); - +/* nfl->iobref = iobref_new (); if (!nfl->iobref) { gf_log (GF_NFS, GF_LOG_ERROR, "iobref creation failed"); @@ -1257,8 +1257,9 @@ nfs_fop_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, } iobref_add (nfl->iobref, srciob); +*/ STACK_WIND_COOKIE (frame, nfs_fop_writev_cbk, xl, xl,xl->fops->writev - , fd, vector, count, offset, nfl->iobref); + , fd, vector, count, offset, srciobref); ret = 0; err: if (ret < 0) { diff --git a/xlators/nfs/server/src/nfs-fops.h b/xlators/nfs/server/src/nfs-fops.h index 4d09e3e242e..a220baa4670 100644 --- a/xlators/nfs/server/src/nfs-fops.h +++ b/xlators/nfs/server/src/nfs-fops.h @@ -180,7 +180,7 @@ nfs_fop_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, extern int nfs_fop_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, - struct iobuf *srciob, struct iovec *vector, int32_t count, + struct iobref *srciobref, struct iovec *vector, int32_t count, off_t offset, fop_writev_cbk_t cbk, void *local); extern int diff --git a/xlators/nfs/server/src/nfs-generics.c b/xlators/nfs/server/src/nfs-generics.c index 010fb17564c..5bc09b7d418 100644 --- a/xlators/nfs/server/src/nfs-generics.c +++ b/xlators/nfs/server/src/nfs-generics.c @@ -170,11 +170,11 @@ nfs_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, int nfs_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, - struct iobuf *srciob, struct iovec *vector, int32_t count, + struct iobref *srciobref, struct iovec *vector, int32_t count, off_t offset, fop_writev_cbk_t cbk, void *local) { - return nfs_fop_write (nfsx, xl, nfu, fd, srciob, vector, count, offset, - cbk, local); + return nfs_fop_write (nfsx, xl, nfu, fd, srciobref, vector, count, + offset, cbk, local); } diff --git a/xlators/nfs/server/src/nfs-generics.h b/xlators/nfs/server/src/nfs-generics.h index fa907b7c555..66156a3b81d 100644 --- a/xlators/nfs/server/src/nfs-generics.h +++ b/xlators/nfs/server/src/nfs-generics.h @@ -92,7 +92,7 @@ nfs_fsync (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, extern int nfs_write (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, fd_t *fd, - struct iobuf *srciob, struct iovec *vector, int32_t count, + struct iobref *srciobref, struct iovec *vector, int32_t count, off_t offset, fop_writev_cbk_t cbk, void *local); extern int diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c index b4568f519cf..7bf5383292b 100644 --- a/xlators/nfs/server/src/nfs.c +++ b/xlators/nfs/server/src/nfs.c @@ -82,8 +82,8 @@ nfs_deinit_versions (struct list_head *versions, xlator_t *this) version->deinit (this); */ if (version->program) - nfs_rpcsvc_program_unregister (nfs->rpcsvc, - *(version->program)); + rpcsvc_program_unregister (nfs->rpcsvc, + (version->program)); list_del (&version->list); GF_FREE (version); @@ -92,7 +92,6 @@ nfs_deinit_versions (struct list_head *versions, xlator_t *this) return 0; } - int nfs_init_versions (struct nfs_state *nfs, xlator_t *this) { @@ -118,17 +117,24 @@ nfs_init_versions (struct nfs_state *nfs, xlator_t *this) ret = -1; goto err; } - prog->actorxl = this; +// prog->actorxl = this; version->program = prog; if (nfs->override_portnum) prog->progport = nfs->override_portnum; gf_log (GF_NFS, GF_LOG_DEBUG, "Starting program: %s", prog->progname); - ret = nfs_rpcsvc_program_register (nfs->rpcsvc, *prog); + + ret = rpcsvc_program_register (nfs->rpcsvc, prog); if (ret == -1) { gf_log (GF_NFS, GF_LOG_ERROR, "Program init failed"); goto err; } + if (rpcsvc_register_portmap_enabled(nfs->rpcsvc)) { + ret = rpcsvc_program_register_portmap (prog, + prog->progport); + if (ret == -1) + goto err; + } } ret = 0; @@ -367,7 +373,7 @@ nfs_init_subvolumes (struct nfs_state *nfs, xlator_list_t *cl) } LOCK_INIT (&nfs->svinitlock); - nfs->initedxl = GF_CALLOC (svcount, sizeof (xlator_t *), + nfs->initedxl = GF_CALLOC (svcount, sizeof (xlator_t *), gf_nfs_mt_xlator_t ); if (!nfs->initedxl) { gf_log (GF_NFS, GF_LOG_ERROR, "Failed to allocated inited xls"); @@ -440,9 +446,9 @@ nfs_request_user_init (nfs_user_t *nfu, rpcsvc_request_t *req) if ((!req) || (!nfu)) return; - gidarr = nfs_rpcsvc_auth_unix_auxgids (req, &gids); - nfs_user_create (nfu, nfs_rpcsvc_request_uid (req), - nfs_rpcsvc_request_gid (req), gidarr, gids); + gidarr = rpcsvc_auth_unix_auxgids (req, &gids); + nfs_user_create (nfu, rpcsvc_request_uid (req), + rpcsvc_request_gid (req), gidarr, gids); return; } @@ -456,7 +462,7 @@ mem_acct_init (xlator_t *this) return ret; ret = xlator_mem_acct_init (this, gf_nfs_mt_end + 1); - + if (ret != 0) { gf_log(this->name, GF_LOG_ERROR, "Memory accounting init" "failed"); @@ -493,7 +499,7 @@ nfs_init_state (xlator_t *this) /* RPC service needs to be started before NFS versions can be * inited. */ - nfs->rpcsvc = nfs_rpcsvc_init (this->ctx, this->options); + nfs->rpcsvc = rpcsvc_init (this->ctx, this->options); if (!nfs->rpcsvc) { gf_log (GF_NFS, GF_LOG_ERROR, "RPC service init failed"); goto free_nfs; @@ -565,7 +571,7 @@ nfs_init_state (xlator_t *this) nfs->enable_ino32 = 1; } - nfs->override_portnum = 0; + nfs->override_portnum = GF_NFS3_PORT; if (dict_get (this->options, "nfs.port")) { ret = dict_get_str (this->options, "nfs.port", &optstr); @@ -582,6 +588,27 @@ nfs_init_state (xlator_t *this) } } + if (dict_get(this->options, "transport.socket.listen-port") == NULL) { + ret = gf_asprintf (&optstr, "%d", nfs->override_portnum); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "failed mem-allocation"); + goto free_foppool; + } + ret = dict_set_dynstr (this->options, + "transport.socket.listen-port", optstr); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_dynstr error"); + goto free_foppool; + } + } + + if (dict_get(this->options, "transport-type") == NULL) { + ret = dict_set_str (this->options, "transport-type", "socket"); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "dict_set_str error"); + goto free_foppool; + } + } this->private = (void *)nfs; INIT_LIST_HEAD (&nfs->versions); @@ -857,6 +884,15 @@ struct volume_options options[] = { "However, can be disabled if needed. Enabled by" "default." }, + { .key = {"rpc-auth.auth-unix.*.allow"}, + .type = GF_OPTION_TYPE_STR, + .description = "Disable or enable the AUTH_UNIX authentication type " + "for a particular exported volume over-riding defaults" + " and general setting for AUTH_UNIX scheme. Must " + "always be enabled for better interoperability." + "However, can be disabled if needed. Enabled by" + "default." + }, { .key = {"rpc-auth.auth-null.*"}, .type = GF_OPTION_TYPE_BOOL, .description = "Disable or enable the AUTH_NULL authentication type " diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c index 0b39e3d162e..9f0939d9c2d 100644 --- a/xlators/nfs/server/src/nfs3-helpers.c +++ b/xlators/nfs/server/src/nfs3-helpers.c @@ -1710,7 +1710,8 @@ nfs3_dir_open_and_resume (nfs3_call_state_t *cs, nfs3_resume_fn_t resume) gf_log (GF_NFS3, GF_LOG_TRACE, "Opening: %s", cs->resolvedloc.path); fd = fd_lookup (cs->resolvedloc.inode, 0); if (fd) { - gf_log (GF_NFS3, GF_LOG_TRACE, "fd found in state: ref: %d", fd->refcount); + gf_log (GF_NFS3, GF_LOG_TRACE, "fd found in state: ref: %d", + fd->refcount); cs->fd = fd; /* Gets unrefd when the call state is wiped. */ cs->resolve_ret = 0; nfs3_call_resume (cs); @@ -1955,7 +1956,7 @@ nfs3_file_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, fd->refcount); } - nfs3 = nfs_rpcsvc_request_program_private (cs->req); + nfs3 = rpcsvc_request_program_private (cs->req); /* Call states are flushed even when the opening of the file failed. * This allows returning an error for each one of the file io requests * that are currently queued waiting for the open to succeed. diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index 70ce23a3990..a162c498300 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -38,7 +38,8 @@ #include "nfs3-helpers.h" #include "nfs-mem-types.h" #include "nfs.h" - +#include "xdr-rpc.h" +#include "xdr-generic.h" #include <sys/socket.h> #include <sys/uio.h> @@ -58,7 +59,7 @@ #define nfs3_validate_nfs3_state(request, state, status, label, retval) \ do { \ - state = nfs_rpcsvc_request_program_private (request); \ + state = rpcsvc_request_program_private (request); \ if (!nfs3) { \ gf_log (GF_NFS3, GF_LOG_ERROR, "NFSv3 state " \ "missing from RPC request"); \ @@ -224,7 +225,7 @@ out: } else { \ gf_log (GF_NFS3, GF_LOG_TRACE, "FH to Volume: %s"\ ,volume->name); \ - nfs_rpcsvc_request_set_private (req, volume); \ + rpcsvc_request_set_private (req, volume); \ } \ } while (0); \ @@ -425,6 +426,8 @@ nfs3_call_state_wipe (nfs3_call_state_t *cs) nfs_loc_wipe (&cs->resolvedloc); if (cs->iob) iobuf_unref (cs->iob); + if (cs->iobref) + iobref_unref (cs->iobref); memset (cs, 0, sizeof (*cs)); mem_put (nfs3->localpool, cs); /* Already refd by fd_lookup, so no need to ref again. */ @@ -452,7 +455,7 @@ nfs3_serialize_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc, struct iobuf *iob = NULL; ssize_t retlen = -1; - nfs3 = (struct nfs3_state *)nfs_rpcsvc_request_program_private (req); + nfs3 = (struct nfs3_state *)rpcsvc_request_program_private (req); if (!nfs3) { gf_log (GF_NFS3, GF_LOG_ERROR, "NFSv3 state not found in RPC" " request"); @@ -500,6 +503,7 @@ nfs3svc_submit_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc) struct iovec outmsg = {0, }; struct iobuf *iob = NULL; int ret = -1; + struct iobref *iobref = NULL; if (!req) return -1; @@ -510,14 +514,24 @@ nfs3svc_submit_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc) goto ret; } + iobref = iobref_new (); + if (!iobref) { + gf_log (GF_NFS3, GF_LOG_ERROR, "failed on iobref_new()"); + goto ret; + } + + iobref_add (iobref, iob); + /* Then, submit the message for transmission. */ - ret = nfs_rpcsvc_submit_message (req, outmsg, iob); + ret = rpcsvc_submit_message (req, &outmsg, 1, NULL, 0, iobref); /* Now that we've done our job of handing the message to the RPC layer * we can safely unref the iob in the hope that RPC layer must have * ref'ed the iob on receiving into the txlist. */ iobuf_unref (iob); + iobref_unref (iobref); + if (ret == -1) { gf_log (GF_NFS3, GF_LOG_ERROR, "Reply submission failed"); goto ret; @@ -532,11 +546,12 @@ ret: int nfs3svc_submit_vector_reply (rpcsvc_request_t *req, void *arg, nfs3_serializer sfunc, struct iovec *payload, - int vcount, struct iobref *piobref) + int vcount, struct iobref *iobref) { struct iovec outmsg = {0, }; struct iobuf *iob = NULL; int ret = -1; + int new_iobref = 0; if (!req) return -1; @@ -544,25 +559,40 @@ nfs3svc_submit_vector_reply (rpcsvc_request_t *req, void *arg, iob = nfs3_serialize_reply (req, arg, sfunc, &outmsg); if (!iob) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to serialize reply"); - goto err; + goto ret; + } + if (iobref == NULL) { + iobref = iobref_new (); + if (!iobref) { + gf_log (GF_NFS3, GF_LOG_ERROR, "failed on iobref_new"); + goto ret; + } + new_iobref = 1; } - ret = nfs_rpcsvc_request_attach_vector (req, outmsg, iob, NULL, 0); - iobuf_unref (iob); + iobref_add (iobref, iob); - if (piobref) - ret = nfs_rpcsvc_request_attach_vectors (req, payload, vcount, - piobref); + /* Then, submit the message for transmission. */ + ret = rpcsvc_submit_message (req, &outmsg, 1, payload, vcount, iobref); - if (ret == -1) - goto err; - ret = nfs_rpcsvc_submit_vectors (req); -err: + /* Now that we've done our job of handing the message to the RPC layer + * we can safely unref the iob in the hope that RPC layer must have + * ref'ed the iob on receiving into the txlist. + */ + iobuf_unref (iob); + if (new_iobref) + iobref_unref (iobref); + if (ret == -1) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Reply submission failed"); + goto ret; + } + + ret = 0; +ret: return ret; } - uint64_t nfs3_request_xlator_deviceid (rpcsvc_request_t *rq) { @@ -574,8 +604,8 @@ nfs3_request_xlator_deviceid (rpcsvc_request_t *rq) if (!rq) return 0; - xl = nfs_rpcsvc_request_private (rq); - nfs3 = nfs_rpcsvc_request_program_private (rq); + xl = rpcsvc_request_private (rq); + nfs3 = rpcsvc_request_program_private (rq); if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx))) devid = (uint64_t)nfs_xlator_to_xlid (nfs3->exportslist, xl); else { @@ -593,8 +623,7 @@ nfs3svc_null (rpcsvc_request_t *req) struct iovec dummyvec = {0, }; if (!req) return RPCSVC_ACTOR_ERROR; - - nfs_rpcsvc_submit_generic (req, dummyvec, NULL); + rpcsvc_submit_generic (req, &dummyvec, 1, NULL, 0, NULL); return RPCSVC_ACTOR_SUCCESS; } @@ -628,7 +657,7 @@ nfs3svc_getattr_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1) status = nfs3_errno_to_nfsstat3 (op_errno); - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "GETATTR", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "GETATTR", status, op_errno); nfs3_getattr_reply (cs->req, status, buf); @@ -650,7 +679,7 @@ nfs3svc_getattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1) status = nfs3_errno_to_nfsstat3 (op_errno); - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "GETATTR", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "GETATTR", status, op_errno); nfs3_getattr_reply (cs->req, status, buf); @@ -695,7 +724,7 @@ nfs3_getattr_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "GETATTR", stat, -ret); nfs3_getattr_reply (cs->req, stat, NULL); nfs3_call_state_wipe (cs); @@ -718,7 +747,7 @@ nfs3_getattr (rpcsvc_request_t *req, struct nfs3_fh *fh) if ((!req) || (!fh)) return -1; - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "GETATTR", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "GETATTR", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -731,7 +760,7 @@ nfs3_getattr (rpcsvc_request_t *req, struct nfs3_fh *fh) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "GETATTR", + nfs3_log_common_res (rpcsvc_request_xid (req), "GETATTR", stat, -ret); nfs3_getattr_reply (req, stat, NULL); ret = 0; @@ -753,16 +782,16 @@ nfs3svc_getattr (rpcsvc_request_t *req) return ret; nfs3_prep_getattr3args (&args, &fh); - if (xdr_to_getattr3args (req->msg, &args) <= 0) { + if (xdr_to_getattr3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_getattr (req, &fh); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "GETATTR procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -812,7 +841,7 @@ nfs3svc_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "SETATTR", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "SETATTR", stat, op_errno); nfs3_setattr_reply (cs->req, stat, prestat, postbuf); nfs3_call_state_wipe (cs); @@ -869,7 +898,7 @@ nfs3svc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "SETATTR", stat, op_errno); nfs3_setattr_reply (cs->req, stat, prebuf, postop); nfs3_call_state_wipe (cs); @@ -912,7 +941,7 @@ nfs3svc_setattr_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "SETATTR", stat, op_errno); nfs3_setattr_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -950,7 +979,7 @@ nfs3_setattr_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "SETATTR", stat, -ret); nfs3_setattr_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -975,7 +1004,7 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr, return -1; } - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "SETATTR", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "SETATTR", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -1006,7 +1035,7 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "SETATTR", + nfs3_log_common_res (rpcsvc_request_xid (req), "SETATTR", stat, -ret); nfs3_setattr_reply (req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -1032,16 +1061,16 @@ nfs3svc_setattr (rpcsvc_request_t *req) return ret; nfs3_prep_setattr3args (&args, &fh); - if (xdr_to_setattr3args (req->msg, &args) <= 0) { + if (xdr_to_setattr3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_setattr (req, &fh, &args.new_attributes, &args.guard); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "SETATTR procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -1114,7 +1143,8 @@ nfs3svc_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } nfs3_fh_build_child_fh (&cs->parent, buf, &newfh); - oldinode = inode_link (inode, cs->resolvedloc.parent, cs->resolvedloc.name, buf); + oldinode = inode_link (inode, cs->resolvedloc.parent, + cs->resolvedloc.name, buf); xmit_res: /* Only send fresh lookup if it was a revalidate that failed. */ if ((op_ret == -1) && (nfs3_is_revalidate_lookup (cs))) { @@ -1122,7 +1152,7 @@ xmit_res: goto out; } - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", status, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), "LOOKUP", status, op_errno, &newfh); nfs3_lookup_reply (cs->req, status, &newfh, buf, postparent); nfs3_call_state_wipe (cs); @@ -1172,7 +1202,7 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } xmit_res: - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", status, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), "LOOKUP", status, op_errno, &newfh); nfs3_lookup_reply (cs->req, status, &newfh, buf, postparent); nfs3_call_state_wipe (cs); @@ -1237,7 +1267,7 @@ errtostat: nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "LOOKUP", stat, -ret); nfs3_lookup_reply (cs->req, stat, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -1272,7 +1302,7 @@ nfs3_lookup_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "LOOKUP", stat, -ret); nfs3_lookup_reply (cs->req, stat, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -1296,7 +1326,7 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name) return -1; } - nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "LOOKUP", fh, + nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "LOOKUP", fh, name); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); if (nfs3_solaris_zerolen_fh (fh, fhlen)) @@ -1321,7 +1351,7 @@ nfs3_lookup (rpcsvc_request_t *req, struct nfs3_fh *fh, int fhlen, char *name) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "LOOKUP", + nfs3_log_common_res (rpcsvc_request_xid (req), "LOOKUP", stat, -ret); nfs3_lookup_reply (req, stat, NULL, NULL, NULL); @@ -1348,16 +1378,16 @@ nfs3svc_lookup (rpcsvc_request_t *req) return ret; nfs3_prep_lookup3args (&args, &fh, name); - if (xdr_to_lookup3args (req->msg, &args) <= 0) { + if (xdr_to_lookup3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_lookup (req, &fh, args.what.dir.data.data_len, name); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "LOOKUP procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -1392,7 +1422,7 @@ nfs3svc_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1) status = nfs3_errno_to_nfsstat3 (op_errno); - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "ACCESS", status, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "ACCESS", status, op_errno); nfs3_access_reply (cs->req, status, op_errno); nfs3_call_state_wipe (cs); @@ -1422,7 +1452,7 @@ nfs3_access_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "ACCESS", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "ACCESS", stat, -ret); nfs3_access_reply (cs->req, stat, 0); nfs3_call_state_wipe (cs); @@ -1445,7 +1475,7 @@ nfs3_access (rpcsvc_request_t *req, struct nfs3_fh *fh, uint32_t accbits) if ((!req) || (!fh)) return -1; - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "ACCESS", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "ACCESS", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -1459,7 +1489,7 @@ nfs3_access (rpcsvc_request_t *req, struct nfs3_fh *fh, uint32_t accbits) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "ACCESS", + nfs3_log_common_res (rpcsvc_request_xid (req), "ACCESS", stat, -ret); nfs3_access_reply (req, stat, 0); nfs3_call_state_wipe (cs); @@ -1481,16 +1511,16 @@ nfs3svc_access (rpcsvc_request_t *req) return ret; nfs3_prep_access3args (&args, &fh); - if (xdr_to_access3args (req->msg, &args) <= 0) { + if (xdr_to_access3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_access (req, &fh, args.access); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "ACCESS procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -1532,7 +1562,7 @@ nfs3svc_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: - nfs3_log_readlink_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno, + nfs3_log_readlink_res (rpcsvc_request_xid (cs->req), stat, op_errno, (char *)path); nfs3_readlink_reply (cs->req, stat, (char *)path, buf); nfs3_call_state_wipe (cs); @@ -1562,7 +1592,7 @@ nfs3_readlink_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READLINK", stat, -ret); nfs3_readlink_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -1586,7 +1616,7 @@ nfs3_readlink (rpcsvc_request_t *req, struct nfs3_fh *fh) return -1; } - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "READLINK", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "READLINK", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -1599,7 +1629,7 @@ nfs3_readlink (rpcsvc_request_t *req, struct nfs3_fh *fh) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "READLINK", + nfs3_log_common_res (rpcsvc_request_xid (req), "READLINK", stat, -ret); nfs3_readlink_reply (req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -1624,16 +1654,16 @@ nfs3svc_readlink (rpcsvc_request_t *req) return ret; nfs3_prep_readlink3args (&args, &fh); - if (xdr_to_readlink3args (req->msg, &args) <= 0) { + if (xdr_to_readlink3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_readlink (req, &fh); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "READLINK procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -1653,17 +1683,19 @@ nfs3_read_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count, deviceid = nfs3_request_xlator_deviceid (req); nfs3_fill_read3res (&res, stat, count, poststat, is_eof, deviceid); if (stat == NFS3_OK) { - nfs_xdr_vector_round_up (vec, vcount, count); + xdr_vector_round_up (vec, vcount, count); /* iob can be zero if the file size was zero. If so, op_ret * would be 0 and count = 0. */ + if (count != 0) { nfs3svc_submit_vector_reply (req, (void *)&res, (nfs3_serializer) xdr_serialize_read3res_nocopy, vec, vcount, iobref); } else - nfs3svc_submit_reply (req, (void *)&res, + + nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer) xdr_serialize_read3res_nocopy); } else @@ -1695,7 +1727,7 @@ nfs3svc_read_cbk (call_frame_t *frame, void *cookie, xlator_t *this, is_eof = 1; err: - nfs3_log_read_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno, + nfs3_log_read_res (rpcsvc_request_xid (cs->req), stat, op_errno, op_ret, is_eof, vector, count); nfs3_read_reply (cs->req, stat, op_ret, vector, count, iobref, stbuf, is_eof); @@ -1725,7 +1757,7 @@ nfs3_read_fd_resume (void *carg) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "READ", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READ", stat, -ret); nfs3_read_reply (cs->req, stat, 0, NULL, 0, NULL, NULL, 0); nfs3_call_state_wipe (cs); @@ -1753,7 +1785,7 @@ nfs3_read_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "READ", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READ", stat, -ret); nfs3_read_reply (cs->req, stat, 0, NULL,0, NULL, NULL, 0); nfs3_call_state_wipe (cs); @@ -1777,7 +1809,7 @@ nfs3_read (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, return -1; } - nfs3_log_rw_call (nfs_rpcsvc_request_xid (req), "READ", fh, offset, + nfs3_log_rw_call (rpcsvc_request_xid (req), "READ", fh, offset, count, -1); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -1793,7 +1825,7 @@ nfs3_read (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "READ", stat, + nfs3_log_common_res (rpcsvc_request_xid (req), "READ", stat, -ret); nfs3_read_reply (req, stat, 0, NULL,0, NULL, NULL, 0); nfs3_call_state_wipe (cs); @@ -1815,16 +1847,16 @@ nfs3svc_read (rpcsvc_request_t *req) return ret; nfs3_prep_read3args (&args, &fh); - if (xdr_to_read3args (req->msg, &args) <= 0) { + if (xdr_to_read3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_read (req, &fh, args.offset, args.count); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "READ procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -1860,14 +1892,14 @@ nfs3svc_write_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, nfs3_call_state_t *cs = NULL; cs = frame->local; - nfs3 = nfs_rpcsvc_request_program_private (cs->req); + nfs3 = rpcsvc_request_program_private (cs->req); if (op_ret == -1) stat = nfs3_errno_to_nfsstat3 (op_errno); else stat = NFS3_OK; - nfs3_log_write_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno, + nfs3_log_write_res (rpcsvc_request_xid (cs->req), stat, op_errno, cs->maxcount, cs->writetype, nfs3->serverstart); nfs3_write_reply (cs->req, stat, cs->maxcount, cs->writetype, nfs3->serverstart, &cs->stbuf, postbuf); @@ -1957,7 +1989,7 @@ nfs3svc_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int sync_trusted = 0; cs = frame->local; - nfs3 = nfs_rpcsvc_request_program_private (cs->req); + nfs3 = rpcsvc_request_program_private (cs->req); if (op_ret == -1) { stat = nfs3_errno_to_nfsstat3 (op_errno); goto err; @@ -1987,7 +2019,7 @@ nfs3svc_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this, err: if (ret < 0) { - nfs3_log_write_res (nfs_rpcsvc_request_xid (cs->req), stat, + nfs3_log_write_res (rpcsvc_request_xid (cs->req), stat, op_errno, cs->maxcount, cs->writetype, nfs3->serverstart); nfs3_write_reply (cs->req, stat, cs->maxcount, @@ -2022,8 +2054,9 @@ __nfs3_write_resume (nfs3_call_state_t *cs) * opaque data buffers to multiples of 4 bytes. */ cs->datavec.iov_len = cs->datacount; - ret = nfs_write (cs->nfsx, cs->vol, &nfu, cs->fd, cs->iob, &cs->datavec, - 1, cs->dataoffset, nfs3svc_write_cbk, cs); + ret = nfs_write (cs->nfsx, cs->vol, &nfu, cs->fd, cs->iobref, + &cs->datavec, 1, cs->dataoffset, nfs3svc_write_cbk, + cs); return ret; } @@ -2047,7 +2080,7 @@ nfs3_write_resume (void *carg) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "WRITE", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "WRITE", stat, -ret); nfs3_write_reply (cs->req, stat, 0, cs->writetype, 0, NULL, NULL); @@ -2074,7 +2107,7 @@ nfs3_write_open_resume (void *carg) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "WRITE", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "WRITE", stat, -ret); nfs3_write_reply (cs->req, stat, 0, cs->writetype, 0, NULL, NULL); @@ -2088,7 +2121,7 @@ nfs3err: int nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, count3 count, stable_how stable, struct iovec payload, - struct iobuf *iob) + struct iobref *iobref) { xlator_t *vol = NULL; nfsstat3 stat = NFS3ERR_SERVERFAULT; @@ -2101,7 +2134,7 @@ nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, return -1; } - nfs3_log_rw_call (nfs_rpcsvc_request_xid (req), "WRITE", fh, offset, + nfs3_log_rw_call (rpcsvc_request_xid (req), "WRITE", fh, offset, count, stable); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -2112,7 +2145,7 @@ nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, cs->datacount = count; cs->dataoffset = offset; cs->writetype = stable; - cs->iob = iob; + cs->iobref = iobref; cs->datavec = payload; @@ -2122,7 +2155,7 @@ nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "WRITE", + nfs3_log_common_res (rpcsvc_request_xid (req), "WRITE", stat, -ret); nfs3_write_reply (req, stat, 0, stable, 0, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2140,99 +2173,46 @@ out: int -nfs3svc_write_vecsizer (rpcsvc_request_t *req, ssize_t *readsize, int *newbuf) +nfs3svc_write_vecsizer (int state, ssize_t *readsize, char *addr) { - ssize_t ret = RPCSVC_ACTOR_ERROR; - int state = 0; + int ret = 0; uint32_t fhlen = 0; uint32_t fhlen_n = 0; - write3args *args = NULL; - if (!req) - return ret; - - state = (long)nfs_rpcsvc_request_private (req); - *newbuf = 0; if (state == 0) { - nfs_rpcsvc_request_set_private (req, NFS3_VECWRITE_READFHLEN); + ret = NFS3_VECWRITE_READFHLEN; *readsize = 4; - ret = 0; } else if (state == NFS3_VECWRITE_READFHLEN) { - fhlen_n = *(uint32_t *)req->msg.iov_base; + fhlen_n = *(uint32_t *)(addr - 4); fhlen = ntohl (fhlen_n); - *readsize = nfs_xdr_length_round_up (fhlen, NFS3_FHSIZE); - nfs_rpcsvc_request_set_private (req, NFS3_VECWRITE_READFH); - ret = 0; + *readsize = xdr_length_round_up (fhlen, NFS3_FHSIZE); + ret = NFS3_VECWRITE_READFH; } else if (state == NFS3_VECWRITE_READFH) { *readsize = NFS3_WRITE_POSTFH_SIZE; - nfs_rpcsvc_request_set_private (req, NFS3_VECWRITE_READREST); - ret = 0; + ret = NFS3_VECWRITE_READREST; } else if (state == NFS3_VECWRITE_READREST) { - args = GF_CALLOC (1, sizeof (*args), gf_nfs_mt_write3args); - if (!args) - goto rpcerr; - - if (xdr_to_write3args_nocopy (req->msg, args, NULL) <= 0) { - gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); - goto rpcerr; - } - nfs_rpcsvc_request_set_private (req, args); - ret = nfs_xdr_length_round_up (args->data.data_len, 1048576); - *readsize = ret; - *newbuf = 1; ret = 0; - } - -rpcerr: - return ret; -} - - -int -nfs3svc_write_vec (rpcsvc_request_t *req, struct iobuf *iob) -{ - write3args *args = NULL; - int ret = RPCSVC_ACTOR_ERROR; - struct iovec payload = {0, }; - struct nfs3_fh fh = {{0}, }; - - if ((!req) || (!iob)) - return ret; - - args = nfs_rpcsvc_request_private (req); - iobuf_to_iovec (iob, &payload); - iobuf_ref (iob); - memcpy (&fh, args->file.data.data_val, args->file.data.data_len); - ret = nfs3_write (req, &fh, args->offset, args->count, args->stable, - payload,iob); - xdr_free_write3args_nocopy (args); - GF_FREE (args); - if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { - gf_log (GF_NFS3, GF_LOG_ERROR, "WRITE procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); - ret = RPCSVC_ACTOR_ERROR; - } + *readsize = 0; + } else + gf_log ("nfs", GF_LOG_ERROR, "state wrong"); return ret; } - int nfs3svc_write (rpcsvc_request_t *req) { struct nfs3_fh fh = {{0}, }; write3args args; int ret = RPCSVC_ACTOR_ERROR; - struct iovec payload = {0, }; if (!req) return ret; nfs3_prep_write3args (&args, &fh); - if (xdr_to_write3args_nocopy (req->msg, &args, &payload) <= 0) { + if (xdr_to_write3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } @@ -2241,12 +2221,12 @@ nfs3svc_write (rpcsvc_request_t *req) * ourselves because the RPC call handler who called us will unref its * own ref of the record's iobuf when it is done handling the request. */ - nfs_rpcsvc_request_record_ref (req); + ret = nfs3_write (req, &fh, args.offset, args.count, args.stable, - payload, nfs_rpcsvc_request_record_iob (req)); + req->msg[1], rpcsvc_request_iobref_ref (req)); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "WRITE procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -2254,6 +2234,12 @@ rpcerr: return ret; } +int +nfs3svc_write_vec (rpcsvc_request_t *req, struct iovec *payload, + int payload_count, struct iobref *iobref) +{ + return nfs3svc_write (req); +} int nfs3_create_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh, @@ -2288,7 +2274,7 @@ nfs3svc_create_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "CREATE", stat, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), "CREATE", stat, op_errno, &cs->fh); nfs3_create_reply (cs->req, stat, &cs->fh, postop, &cs->preparent, &cs->postparent); @@ -2334,7 +2320,7 @@ nfs3svc_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, nfs3err: if (ret < 0) { - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "CREATE", + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), "CREATE", stat, op_errno, &cs->fh); nfs3_create_reply (cs->req, stat, &cs->fh, buf, preparent, postparent); @@ -2396,20 +2382,23 @@ nfs3svc_create_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if ((cs->stbuf.ia_mtime == buf->ia_mtime) && (cs->stbuf.ia_atime == buf->ia_atime)) { - gf_log (GF_NFS3, GF_LOG_DEBUG, "Create req retransmitted verf %x %x", + gf_log (GF_NFS3, GF_LOG_DEBUG, + "Create req retransmitted verf %x %x", cs->stbuf.ia_mtime, cs->stbuf.ia_atime); stat = NFS3_OK; nfs3_fh_build_child_fh (&cs->parent, buf, &cs->fh); } else { - gf_log (GF_NFS3, GF_LOG_DEBUG, "File already exist new_verf %x %x" - "old_verf %x %x", cs->stbuf.ia_mtime, cs->stbuf.ia_atime, + gf_log (GF_NFS3, GF_LOG_DEBUG, + "File already exist new_verf %x %x" + "old_verf %x %x", cs->stbuf.ia_mtime, + cs->stbuf.ia_atime, buf->ia_mtime, buf->ia_atime); stat = NFS3ERR_EXIST; } nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "CREATE", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "CREATE", stat, op_errno); nfs3_create_reply (cs->req, stat, &cs->fh, buf, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2430,7 +2419,8 @@ nfs3_create_exclusive (nfs3_call_state_t *cs) /* Storing verifier as a mtime and atime attribute, to store it * in stable storage */ - memcpy (&cs->stbuf.ia_atime, &cs->cookieverf, sizeof (cs->stbuf.ia_atime)); + memcpy (&cs->stbuf.ia_atime, &cs->cookieverf, + sizeof (cs->stbuf.ia_atime)); memcpy (&cs->stbuf.ia_mtime, ((char *) &cs->cookieverf) + sizeof (cs->stbuf.ia_atime), sizeof (cs->stbuf.ia_mtime)); @@ -2454,7 +2444,8 @@ nfs3_create_exclusive (nfs3_call_state_t *cs) ret = nfs_create (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, O_RDWR, cs->mode, nfs3svc_create_cbk, cs); } else - ret = nfs_create (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, O_RDWR, + ret = nfs_create (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, + O_RDWR, NFS_DEFAULT_CREATE_MODE, nfs3svc_create_cbk, cs); @@ -2486,7 +2477,7 @@ nfs3_create_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "CREATE", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "CREATE", stat, -ret); nfs3_create_reply (cs->req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2508,7 +2499,7 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, if ((!req) || (!dirfh) || (!name) || (!sattr)) return -1; - nfs3_log_create_call (nfs_rpcsvc_request_xid (req), dirfh, name, mode); + nfs3_log_create_call (rpcsvc_request_xid (req), dirfh, name, mode); nfs3_validate_gluster_fh (dirfh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret); @@ -2521,8 +2512,9 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, /*In Exclusive create client is supposed to send cverf instead of * sattr*/ if (mode != EXCLUSIVE) - cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf, - &cs->mode); + cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, + &cs->stbuf, + &cs->mode); cs->createmode = mode; cs->parent = *dirfh; @@ -2532,7 +2524,7 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "CREATE", + nfs3_log_common_res (rpcsvc_request_xid (req), "CREATE", stat, -ret); nfs3_create_reply (req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2557,9 +2549,9 @@ nfs3svc_create (rpcsvc_request_t *req) return ret; nfs3_prep_create3args (&args, &dirfh, name); - if (xdr_to_create3args (req->msg, &args) <= 0) { + if (xdr_to_create3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } @@ -2567,7 +2559,8 @@ nfs3svc_create (rpcsvc_request_t *req) if (cval) cverf = *cval; else { - gf_log(GF_NFS3, GF_LOG_ERROR, "Error getting createverf3 from args"); + gf_log(GF_NFS3, GF_LOG_ERROR, + "Error getting createverf3 from args"); goto rpcerr; } @@ -2575,7 +2568,7 @@ nfs3svc_create (rpcsvc_request_t *req) &args.how.createhow3_u.obj_attributes, cverf); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "CREATE procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -2616,7 +2609,7 @@ nfs3svc_mkdir_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKDIR", stat, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), "MKDIR", stat, op_errno, &cs->fh); nfs3_mkdir_reply (cs->req, stat, &cs->fh, postop, &cs->preparent, &cs->postparent); @@ -2661,7 +2654,7 @@ nfs3svc_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, nfs3err: if (ret < 0) { - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKDIR", + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), "MKDIR", stat, op_errno, &cs->fh); nfs3_mkdir_reply (cs->req, stat, &cs->fh, buf, preparent, postparent); @@ -2700,7 +2693,7 @@ nfs3_mkdir_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "MKDIR", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "MKDIR", stat, -ret); nfs3_mkdir_reply (cs->req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2726,7 +2719,7 @@ nfs3_mkdir (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, return -1; } - nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "MKDIR", dirfh, + nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "MKDIR", dirfh, name); nfs3_validate_gluster_fh (dirfh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -2745,7 +2738,7 @@ nfs3_mkdir (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "MKDIR", + nfs3_log_common_res (rpcsvc_request_xid (req), "MKDIR", stat, -ret); nfs3_mkdir_reply (req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2767,16 +2760,16 @@ nfs3svc_mkdir (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_mkdir3args (&args, &dirfh, name); - if (xdr_to_mkdir3args (req->msg, &args) <= 0) { + if (xdr_to_mkdir3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_mkdir (req, &dirfh, name, &args.attributes); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "MKDIR procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -2822,7 +2815,7 @@ nfs3svc_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "SYMLINK", stat, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), "SYMLINK", stat, op_errno, &cs->fh); nfs3_symlink_reply (cs->req, stat, &cs->fh, buf, preparent, postparent); @@ -2852,7 +2845,7 @@ nfs3_symlink_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "SYMLINK", stat, -ret); nfs3_symlink_reply (cs->req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2877,7 +2870,7 @@ nfs3_symlink (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, return -1; } - nfs3_log_symlink_call (nfs_rpcsvc_request_xid (req), dirfh, name, + nfs3_log_symlink_call (rpcsvc_request_xid (req), dirfh, name, target); nfs3_validate_gluster_fh (dirfh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -2901,7 +2894,7 @@ nfs3_symlink (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "SYMLINK", + nfs3_log_common_res (rpcsvc_request_xid (req), "SYMLINK", stat, -ret); nfs3_symlink_reply (req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -2927,9 +2920,9 @@ nfs3svc_symlink (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_symlink3args (&args, &dirfh, name, target); - if (xdr_to_symlink3args (req->msg, &args) <= 0) { + if (xdr_to_symlink3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } @@ -2937,7 +2930,7 @@ nfs3svc_symlink (rpcsvc_request_t *req) &args.symlink.symlink_attributes); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "SYMLINK procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -2979,7 +2972,7 @@ nfs3svc_mknod_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKNOD", stat, + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), "MKNOD", stat, op_errno, &cs->fh); nfs3_mknod_reply (cs->req, stat, &cs->fh, postop, &cs->preparent, &cs->postparent); @@ -3024,7 +3017,7 @@ nfs3svc_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "MKNOD", + nfs3_log_newfh_res (rpcsvc_request_xid (cs->req), "MKNOD", stat, op_errno, &cs->fh); nfs3_mknod_reply (cs->req, stat, &cs->fh, buf, preparent, @@ -3123,7 +3116,7 @@ nfs3_mknod_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "MKNOD", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "MKNOD", stat, -ret); nfs3_mknod_reply (cs->req, stat, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3150,7 +3143,7 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name, return -1; } - nfs3_log_mknod_call (nfs_rpcsvc_request_xid (req), fh, name, + nfs3_log_mknod_call (rpcsvc_request_xid (req), fh, name, nodedata->type); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -3166,13 +3159,15 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name, case NF3BLK: cs->devnums = nodedata->mknoddata3_u.device.spec; sattr = &nodedata->mknoddata3_u.device.dev_attributes; - cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf, + cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, + &cs->stbuf, &cs->mode); break; case NF3SOCK: case NF3FIFO: sattr = &nodedata->mknoddata3_u.pipe_attributes; - cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf, + cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, + &cs->stbuf, &cs->mode); break; default: @@ -3187,7 +3182,7 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "MKNOD", + nfs3_log_common_res (rpcsvc_request_xid (req), "MKNOD", stat, -ret); nfs3_mknod_reply (req, stat, NULL, NULL, NULL, NULL); /* Ret must be 0 after this so that the caller does not @@ -3212,16 +3207,16 @@ nfs3svc_mknod (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_mknod3args (&args, &fh, name); - if (xdr_to_mknod3args (req->msg, &args) <= 0) { + if (xdr_to_mknod3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_mknod (req, &fh, name, &args.what); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "MKNOD procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -3265,14 +3260,14 @@ nfs3svc_remove_cbk (call_frame_t *frame, void *cookie, xlator_t *this, * finishes, the file is finally removed. */ openfd = fd_lookup (cs->resolvedloc.inode, 0); - nfs3 = nfs_rpcsvc_request_program_private (cs->req); + nfs3 = rpcsvc_request_program_private (cs->req); if (openfd) { fd_unref (openfd); nfs3_fdcache_remove (nfs3, openfd); } do_not_unref_cached_fd: - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "REMOVE", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "REMOVE", stat, op_errno); nfs3_remove_reply (cs->req, stat, preparent, postparent); nfs3_call_state_wipe (cs); @@ -3321,7 +3316,7 @@ nfs3_remove_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "REMOVE", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "REMOVE", stat, -ret); nfs3_remove_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3345,7 +3340,7 @@ nfs3_remove (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name) return -1; } - nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "REMOVE", fh, + nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "REMOVE", fh, name); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -3361,7 +3356,7 @@ nfs3_remove (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "REMOVE", + nfs3_log_common_res (rpcsvc_request_xid (req), "REMOVE", stat, -ret); nfs3_remove_reply (req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3386,16 +3381,16 @@ nfs3svc_remove (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_remove3args (&args, &fh, name); - if (xdr_to_remove3args (req->msg, &args) <= 0) { + if (xdr_to_remove3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_remove (req, &fh, name); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "REMOVE procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -3434,7 +3429,7 @@ nfs3svc_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; } - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RMDIR", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "RMDIR", stat, op_errno); nfs3_rmdir_reply (cs->req, stat, preparent, postparent); nfs3_call_state_wipe (cs); @@ -3463,7 +3458,7 @@ nfs3_rmdir_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RMDIR", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "RMDIR", stat, -ret); nfs3_rmdir_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3488,7 +3483,7 @@ nfs3_rmdir (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name) return -1; } - nfs3_log_fh_entry_call (nfs_rpcsvc_request_xid (req), "RMDIR", fh, + nfs3_log_fh_entry_call (rpcsvc_request_xid (req), "RMDIR", fh, name); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -3504,7 +3499,7 @@ nfs3_rmdir (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "RMDIR", + nfs3_log_common_res (rpcsvc_request_xid (req), "RMDIR", stat, -ret); nfs3_rmdir_reply (req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3529,16 +3524,16 @@ nfs3svc_rmdir (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_rmdir3args (&args, &fh, name); - if (xdr_to_rmdir3args (req->msg, &args) <= 0) { + if (xdr_to_rmdir3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_rmdir (req, &fh, name); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "RMDIR procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -3598,7 +3593,7 @@ nfs3svc_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } nfs3err: - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RENAME", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "RENAME", stat, -ret); nfs3_rename_reply (cs->req, stat, buf, preoldparent, postoldparent, prenewparent, postnewparent); @@ -3629,7 +3624,7 @@ nfs3_rename_resume_dst (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RENAME", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "RENAME", stat, -ret); nfs3_rename_reply (cs->req, stat, NULL, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3665,7 +3660,7 @@ nfs3_rename_resume_src (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "RENAME", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "RENAME", stat, -ret); nfs3_rename_reply (cs->req, stat, NULL, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3690,7 +3685,7 @@ nfs3_rename (rpcsvc_request_t *req, struct nfs3_fh *olddirfh, char *oldname, return -1; } - nfs3_log_rename_call (nfs_rpcsvc_request_xid (req), olddirfh, oldname, + nfs3_log_rename_call (rpcsvc_request_xid (req), olddirfh, oldname, newdirfh, newname); nfs3_validate_gluster_fh (olddirfh, stat, nfs3err); nfs3_validate_gluster_fh (newdirfh, stat, nfs3err); @@ -3720,7 +3715,7 @@ nfs3_rename (rpcsvc_request_t *req, struct nfs3_fh *olddirfh, char *oldname, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "RENAME", + nfs3_log_common_res (rpcsvc_request_xid (req), "RENAME", stat, -ret); nfs3_rename_reply (req, stat, NULL, NULL, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3747,16 +3742,16 @@ nfs3svc_rename (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_rename3args (&args, &olddirfh, oldname, &newdirfh, newname); - if (xdr_to_rename3args (req->msg, &args) <= 0) { + if (xdr_to_rename3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_rename (req, &olddirfh, oldname, &newdirfh, newname); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "RENAME procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -3796,7 +3791,7 @@ nfs3svc_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, else stat = NFS3_OK; - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LINK", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "LINK", stat, op_errno); nfs3_link_reply (cs->req, stat, buf, preparent, postparent); nfs3_call_state_wipe (cs); @@ -3827,7 +3822,7 @@ nfs3_link_resume_lnk (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LINK", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "LINK", stat, -ret); nfs3_link_reply (cs->req, stat, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3858,7 +3853,7 @@ nfs3_link_resume_tgt (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "LINK", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "LINK", stat, -ret); nfs3_link_reply (cs->req, stat, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3907,7 +3902,7 @@ nfs3_link (rpcsvc_request_t *req, struct nfs3_fh *targetfh, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "LINK", stat, + nfs3_log_common_res (rpcsvc_request_xid (req), "LINK", stat, -ret); nfs3_link_reply (req, stat, NULL, NULL, NULL); nfs3_call_state_wipe (cs); @@ -3932,16 +3927,16 @@ nfs3svc_link (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_link3args (&args, &targetfh, &dirfh, newpath); - if (xdr_to_link3args (req->msg, &args) <= 0) { + if (xdr_to_link3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_link (req, &targetfh, &dirfh, newpath); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "LINK procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4013,14 +4008,14 @@ nfs3svc_readdir_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; nfs3err: if (cs->maxcount == 0) { - nfs3_log_readdir_res (nfs_rpcsvc_request_xid (cs->req), stat, + nfs3_log_readdir_res (rpcsvc_request_xid (cs->req), stat, op_errno, (uintptr_t)cs->fd, cs->dircount, is_eof); nfs3_readdir_reply (cs->req, stat, &cs->parent, (uintptr_t)cs->fd, buf, &cs->entries, cs->dircount, is_eof); } else { - nfs3_log_readdirp_res (nfs_rpcsvc_request_xid (cs->req), stat, + nfs3_log_readdirp_res (rpcsvc_request_xid (cs->req), stat, op_errno, (uintptr_t)cs->fd, cs->dircount, cs->maxcount, is_eof); nfs3_readdirp_reply (cs->req, stat, &cs->parent, @@ -4069,11 +4064,11 @@ err: goto ret; if (cs->maxcount == 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READDIR", stat, op_errno); nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0); } else { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READDIRP", stat, op_errno); nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0, 0); @@ -4117,7 +4112,7 @@ nfs3_readdir_read_resume (void *carg) cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); - nfs3 = nfs_rpcsvc_request_program_private (cs->req); + nfs3 = rpcsvc_request_program_private (cs->req); ret = nfs3_verify_dircookie (nfs3, cs->fd, cs->cookie, cs->cookieverf, &stat); if (ret < 0) /* Stat already set by verifier function above. */ @@ -4129,12 +4124,12 @@ nfs3_readdir_read_resume (void *carg) nfs3err: if (ret < 0) { if (cs->maxcount == 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READDIR", stat, -ret); nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0); } else { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READDIRP", stat, -ret); nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0, 0); @@ -4165,12 +4160,12 @@ nfs3_readdir_open_resume (void *carg) nfs3err: if (ret < 0) { if (cs->maxcount == 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READDIR", stat, -ret); nfs3_readdir_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0); } else { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "READDIRP", stat, -ret); nfs3_readdirp_reply (cs->req, stat, NULL, 0, NULL, NULL, 0, 0, 0); @@ -4198,7 +4193,7 @@ nfs3_readdir (rpcsvc_request_t *req, struct nfs3_fh *fh, cookie3 cookie, return -1; } - nfs3_log_readdir_call (nfs_rpcsvc_request_xid (req), fh, dircount, + nfs3_log_readdir_call (rpcsvc_request_xid (req), fh, dircount, maxcount); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -4219,12 +4214,12 @@ nfs3_readdir (rpcsvc_request_t *req, struct nfs3_fh *fh, cookie3 cookie, nfs3err: if (ret < 0) { if (maxcount == 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), + nfs3_log_common_res (rpcsvc_request_xid (req), "READDIR", stat, -ret); nfs3_readdir_reply (req, stat, NULL, 0, NULL, NULL, 0, 0); } else { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), + nfs3_log_common_res (rpcsvc_request_xid (req), "READDIRP", stat, -ret); nfs3_readdirp_reply (req, stat, NULL, 0, NULL, NULL, 0, 0, 0); @@ -4252,9 +4247,9 @@ nfs3svc_readdir (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_readdir3args (&ra, &fh); - if (xdr_to_readdir3args (req->msg, &ra) <= 0) { + if (xdr_to_readdir3args (req->msg[0], &ra) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } @@ -4263,14 +4258,15 @@ nfs3svc_readdir (rpcsvc_request_t *req) if (cval) verf = *cval; else { - gf_log(GF_NFS3, GF_LOG_ERROR, "Error getting cookieverf from readdir args"); + gf_log(GF_NFS3, GF_LOG_ERROR, + "Error getting cookieverf from readdir args"); goto rpcerr; } ret = nfs3_readdir (req, &fh, ra.cookie, verf, ra.count, 0); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "READDIR procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4291,9 +4287,9 @@ nfs3svc_readdirp (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_readdirp3args (&ra, &fh); - if (xdr_to_readdirp3args (req->msg, &ra) <= 0) { + if (xdr_to_readdirp3args (req->msg[0], &ra) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } @@ -4302,7 +4298,8 @@ nfs3svc_readdirp (rpcsvc_request_t *req) if (cval) cverf = *cval; else { - gf_log (GF_NFS3, GF_LOG_ERROR, "Error getting cookieverf from readdirp args"); + gf_log (GF_NFS3, GF_LOG_ERROR, + "Error getting cookieverf from readdirp args"); goto rpcerr; } @@ -4310,7 +4307,7 @@ nfs3svc_readdirp (rpcsvc_request_t *req) ra.maxcount); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "READDIRP procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4347,7 +4344,7 @@ nfs3_fsstat_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, else stat = NFS3_OK; - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSTAT", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "FSTAT", stat, op_errno); nfs3_fsstat_reply (cs->req, stat, &cs->fsstat, buf); nfs3_call_state_wipe (cs); @@ -4383,7 +4380,7 @@ nfs3_fsstat_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSTAT", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "FSTAT", stat, -ret); nfs3_fsstat_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -4415,7 +4412,7 @@ nfs3_fsstat_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSTAT", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "FSTAT", stat, -ret); nfs3_fsstat_reply (cs->req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -4440,7 +4437,7 @@ nfs3_fsstat (rpcsvc_request_t *req, struct nfs3_fh *fh) return -1; } - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "FSSTAT", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "FSSTAT", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -4453,7 +4450,7 @@ nfs3_fsstat (rpcsvc_request_t *req, struct nfs3_fh *fh) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "FSTAT", + nfs3_log_common_res (rpcsvc_request_xid (req), "FSTAT", stat, -ret); nfs3_fsstat_reply (req, stat, NULL, NULL); nfs3_call_state_wipe (cs); @@ -4477,16 +4474,16 @@ nfs3svc_fsstat (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_fsstat3args (&args, &fh); - if (xdr_to_fsstat3args (req->msg, &args) <= 0) { + if (xdr_to_fsstat3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_fsstat (req, &fh); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "FSTAT procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4503,7 +4500,7 @@ nfs3_fsinfo_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *fsroot) uint64_t deviceid = 0; deviceid = nfs3_request_xlator_deviceid (req); - nfs3 = nfs_rpcsvc_request_program_private (req); + nfs3 = rpcsvc_request_program_private (req); nfs3_fill_fsinfo3res (nfs3, &res, status, fsroot, deviceid); nfs3svc_submit_reply (req, &res, @@ -4526,7 +4523,7 @@ nfs3svc_fsinfo_cbk (call_frame_t *frame, void *cookie, xlator_t *this, else status = NFS3_OK; - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSINFO", status, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "FSINFO", status, op_errno); nfs3_fsinfo_reply (cs->req, status, buf); @@ -4559,7 +4556,7 @@ nfs3_fsinfo_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "FSINFO", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "FSINFO", stat, -ret); nfs3_fsinfo_reply (cs->req, stat, NULL); nfs3_call_state_wipe (cs); @@ -4583,7 +4580,7 @@ nfs3_fsinfo (rpcsvc_request_t *req, struct nfs3_fh *fh) return -1; } - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "FSINFO", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "FSINFO", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -4596,7 +4593,7 @@ nfs3_fsinfo (rpcsvc_request_t *req, struct nfs3_fh *fh) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "FSINFO", + nfs3_log_common_res (rpcsvc_request_xid (req), "FSINFO", stat, -ret); nfs3_fsinfo_reply (req, stat, NULL); nfs3_call_state_wipe (cs); @@ -4618,16 +4615,16 @@ nfs3svc_fsinfo (rpcsvc_request_t *req) return ret; nfs3_prep_fsinfo3args (&args, &root); - if (xdr_to_fsinfo3args (req->msg, &args) <= 0) { + if (xdr_to_fsinfo3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding arguments"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_fsinfo (req, &root); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "FSINFO procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4669,7 +4666,7 @@ nfs3svc_pathconf_cbk (call_frame_t *frame, void *cookie, xlator_t *this, stat = NFS3_OK; } - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "PATHCONF", stat, + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "PATHCONF", stat, op_errno); nfs3_pathconf_reply (cs->req, stat, sbuf); nfs3_call_state_wipe (cs); @@ -4698,7 +4695,7 @@ nfs3_pathconf_resume (void *carg) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "PATHCONF", stat, -ret); nfs3_pathconf_reply (cs->req, stat, NULL); nfs3_call_state_wipe (cs); @@ -4721,7 +4718,7 @@ nfs3_pathconf (rpcsvc_request_t *req, struct nfs3_fh *fh) return -1; } - nfs3_log_common_call (nfs_rpcsvc_request_xid (req), "PATHCONF", fh); + nfs3_log_common_call (rpcsvc_request_xid (req), "PATHCONF", fh); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); @@ -4734,7 +4731,7 @@ nfs3_pathconf (rpcsvc_request_t *req, struct nfs3_fh *fh) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "PATHCONF", + nfs3_log_common_res (rpcsvc_request_xid (req), "PATHCONF", stat, -ret); nfs3_pathconf_reply (req, stat, NULL); nfs3_call_state_wipe (cs); @@ -4758,16 +4755,16 @@ nfs3svc_pathconf (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_pathconf3args (&args, &fh); - if (xdr_to_pathconf3args (req->msg, &args) <= 0) { + if (xdr_to_pathconf3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_pathconf (req, &fh); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "PATHCONF procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4806,8 +4803,8 @@ nfs3svc_commit_cbk (call_frame_t *frame, void *cookie, xlator_t *this, else stat = NFS3_OK; - nfs3 = nfs_rpcsvc_request_program_private (cs->req); - nfs3_log_commit_res (nfs_rpcsvc_request_xid (cs->req), stat, op_errno, + nfs3 = rpcsvc_request_program_private (cs->req); + nfs3_log_commit_res (rpcsvc_request_xid (cs->req), stat, op_errno, nfs3->serverstart); nfs3_commit_reply (cs->req, stat, nfs3->serverstart, prebuf, postbuf); nfs3_call_state_wipe (cs); @@ -4843,7 +4840,7 @@ nfs3_commit_resume (void *carg) nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "COMMIT", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "COMMIT", stat, -ret); nfs3_commit_reply (cs->req, stat, cs->nfs3state->serverstart, NULL, NULL); @@ -4873,7 +4870,7 @@ nfs3_commit_open_resume (void *carg) stat = nfs3_errno_to_nfsstat3 (-ret); nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (cs->req), "COMMIT", + nfs3_log_common_res (rpcsvc_request_xid (cs->req), "COMMIT", stat, -ret); nfs3_commit_reply (cs->req, stat, 0, NULL, NULL); nfs3_call_state_wipe (cs); @@ -4899,7 +4896,7 @@ nfs3_commit (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, return -1; } - nfs3_log_rw_call (nfs_rpcsvc_request_xid (req), "COMMIT", fh, offset, + nfs3_log_rw_call (rpcsvc_request_xid (req), "COMMIT", fh, offset, count, -1); nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); @@ -4917,7 +4914,7 @@ nfs3_commit (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, nfs3err: if (ret < 0) { - nfs3_log_common_res (nfs_rpcsvc_request_xid (req), "COMMIT", + nfs3_log_common_res (rpcsvc_request_xid (req), "COMMIT", stat, -ret); nfs3_commit_reply (req, stat, 0, NULL, NULL); nfs3_call_state_wipe (cs); @@ -4939,16 +4936,16 @@ nfs3svc_commit (rpcsvc_request_t *req) if (!req) return ret; nfs3_prep_commit3args (&args, &fh); - if (xdr_to_commit3args (req->msg, &args) <= 0) { + if (xdr_to_commit3args (req->msg[0], &args) <= 0) { gf_log (GF_NFS3, GF_LOG_ERROR, "Error decoding args"); - nfs_rpcsvc_request_seterr (req, GARBAGE_ARGS); + rpcsvc_request_seterr (req, GARBAGE_ARGS); goto rpcerr; } ret = nfs3_commit (req, &fh, args.offset, args.count); if ((ret < 0) && (ret != RPCSVC_ACTOR_IGNORE)) { gf_log (GF_NFS3, GF_LOG_ERROR, "COMMIT procedure failed"); - nfs_rpcsvc_request_seterr (req, SYSTEM_ERR); + rpcsvc_request_seterr (req, SYSTEM_ERR); ret = RPCSVC_ACTOR_ERROR; } @@ -4965,7 +4962,7 @@ rpcsvc_actor_t nfs3svc_actors[NFS3_PROC_COUNT] = { {"ACCESS", NFS3_ACCESS, nfs3svc_access, NULL, NULL}, {"READLINK", NFS3_READLINK, nfs3svc_readlink,NULL, NULL}, {"READ", NFS3_READ, nfs3svc_read, NULL, NULL}, - {"WRITE", NFS3_WRITE, nfs3svc_write, nfs3svc_write_vec, nfs3svc_write_vecsizer}, + {"WRITE", NFS3_WRITE, nfs3svc_write, nfs3svc_write_vec, nfs3svc_write_vecsizer}, {"CREATE", NFS3_CREATE, nfs3svc_create, NULL, NULL}, {"MKDIR", NFS3_MKDIR, nfs3svc_mkdir, NULL, NULL}, {"SYMLINK", NFS3_SYMLINK, nfs3svc_symlink,NULL, NULL}, @@ -4988,8 +4985,6 @@ rpcsvc_program_t nfs3prog = { .prognum = NFS_PROGRAM, .progver = NFS_V3, .progport = GF_NFS3_PORT, - .progaddrfamily = AF_INET, - .proghost = NULL, .actors = nfs3svc_actors, .numactors = NFS3_PROC_COUNT, @@ -5327,7 +5322,7 @@ nfs3_init_state (xlator_t *nfsx) struct nfs3_state *nfs3 = NULL; int ret = -1; unsigned int localpool = 0; - + struct nfs_state *nfs = NULL; if (!nfsx) return NULL; @@ -5339,6 +5334,7 @@ nfs3_init_state (xlator_t *nfsx) return NULL; } + nfs = nfsx->private; ret = nfs3_init_options (nfs3, nfsx); if (ret == -1) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init options"); @@ -5371,6 +5367,12 @@ nfs3_init_state (xlator_t *nfsx) LOCK_INIT (&nfs3->fdlrulock); nfs3->fdcount = 0; + rpcsvc_create_listeners (nfs->rpcsvc, nfsx->options, nfsx->name); + if (ret == -1) { + gf_log (GF_NFS, GF_LOG_ERROR, "Unable to create listeners"); + goto free_localpool; + } + ret = 0; free_localpool: diff --git a/xlators/nfs/server/src/nfs3.h b/xlators/nfs/server/src/nfs3.h index bf4371a8a45..ce671a9c85f 100644 --- a/xlators/nfs/server/src/nfs3.h +++ b/xlators/nfs/server/src/nfs3.h @@ -184,6 +184,7 @@ struct nfs3_local { count3 datacount; offset3 dataoffset; struct iobuf *iob; + struct iobref *iobref; createmode3 createmode; uint64_t cookieverf; int sattrguardcheck; @@ -206,7 +207,7 @@ struct nfs3_local { }; #define nfs3_is_revalidate_lookup(cst) ((cst)->lookuptype == GF_NFS3_REVALIDATE) -#define nfs3_lookup_op(cst) (nfs_rpcsvc_request_procnum(cst->req) == NFS3_LOOKUP) +#define nfs3_lookup_op(cst) (rpcsvc_request_procnum(cst->req) == NFS3_LOOKUP) typedef struct nfs3_local nfs3_call_state_t; /* Queue of ops waiting for open fop to return. */ diff --git a/xlators/protocol/server/src/server3_1-fops.c b/xlators/protocol/server/src/server3_1-fops.c index 22602d9d75e..4f44f3957dc 100644 --- a/xlators/protocol/server/src/server3_1-fops.c +++ b/xlators/protocol/server/src/server3_1-fops.c @@ -30,6 +30,7 @@ #include "compat-errno.h" #include "md5.h" +#include "xdr-nfs3.h" /* Callback function section */ @@ -3114,6 +3115,30 @@ server_writev_vec (rpcsvc_request_t *req, struct iovec *payload, return server_writev (req); } +#define SERVER3_1_VECWRITE_START 0 +#define SERVER3_1_VECWRITE_READINGHDR 1 + +int +server_writev_vecsizer (int state, ssize_t *readsize, char *addr) +{ + int nextstate = 0; + gfs3_write_req write_req = {{0,},}; + + switch (state) { + case SERVER3_1_VECWRITE_START: + *readsize = xdr_sizeof ((xdrproc_t) xdr_gfs3_write_req, &write_req); + nextstate = SERVER3_1_VECWRITE_READINGHDR; + break; + case SERVER3_1_VECWRITE_READINGHDR: + *readsize = 0; + nextstate = SERVER3_1_VECWRITE_START; + break; + default: + gf_log ("server3_1", GF_LOG_ERROR, "wrong state: %d", state); + } + return nextstate; +} + int server_release (rpcsvc_request_t *req) @@ -5154,7 +5179,7 @@ rpcsvc_actor_t glusterfs3_1_fop_actors[] = { [GFS3_OP_TRUNCATE] = { "TRUNCATE", GFS3_OP_TRUNCATE, server_truncate, NULL, NULL }, [GFS3_OP_OPEN] = { "OPEN", GFS3_OP_OPEN, server_open, NULL, NULL }, [GFS3_OP_READ] = { "READ", GFS3_OP_READ, server_readv, NULL, NULL }, - [GFS3_OP_WRITE] = { "WRITE", GFS3_OP_WRITE, server_writev, server_writev_vec, NULL }, + [GFS3_OP_WRITE] = { "WRITE", GFS3_OP_WRITE, server_writev, server_writev_vec, server_writev_vecsizer }, [GFS3_OP_STATFS] = { "STATFS", GFS3_OP_STATFS, server_statfs, NULL, NULL }, [GFS3_OP_FLUSH] = { "FLUSH", GFS3_OP_FLUSH, server_flush, NULL, NULL }, [GFS3_OP_FSYNC] = { "FSYNC", GFS3_OP_FSYNC, server_fsync, NULL, NULL }, |