summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2010-11-10 07:56:45 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-11-10 20:07:33 -0800
commit7b8015edf8ac2fc33e486d2ef66b01c53c200d60 (patch)
treec54344344a3afd3a9c3bd0380aacbabb8f030822
parent681d7d3aa926e0959ad3f66e53282cb4e55d6202 (diff)
rpcsvc: Fix crash in program search after portmap registration failure
Failure to register with portmap was leaving the registered programs list in inconsistent state. This was causing a crash. portmap registration can fail if there is an NFS server already running. Signed-off-by: Shehjar Tikoo <shehjart@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 2072 (NFS server crash in __nfs_rpcsvc_program_actor) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2072
-rw-r--r--xlators/nfs/lib/src/rpcsvc.c39
-rw-r--r--xlators/nfs/lib/src/rpcsvc.h6
2 files changed, 29 insertions, 16 deletions
diff --git a/xlators/nfs/lib/src/rpcsvc.c b/xlators/nfs/lib/src/rpcsvc.c
index 081b4d6fe66..780c9aea474 100644
--- a/xlators/nfs/lib/src/rpcsvc.c
+++ b/xlators/nfs/lib/src/rpcsvc.c
@@ -1270,7 +1270,7 @@ __nfs_rpcsvc_program_actor (rpcsvc_request_t *req, rpcsvc_program_t **prg)
prglist = &((nfs_rpcsvc_request_service (req))->allprograms);
if (list_empty (prglist))
- return ret;
+ goto err;
list_for_each_entry (program, prglist, proglist) {
ret = PROG_UNAVAIL;
@@ -1329,6 +1329,10 @@ err:
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;
@@ -1549,14 +1553,21 @@ nfs_rpcsvc_fill_reply (rpcsvc_request_t *req, struct rpc_msg *reply)
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)
- nfs_rpc_fill_accepted_reply (reply, req->rpc_err,
- prog->proglowvers,
- prog->proghighvers,
- req->verf.flavour,
- req->verf.datalen,
- req->verf.authdata);
- else
+ 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;
@@ -1917,8 +1928,10 @@ nfs_rpcsvc_request_create (rpcsvc_conn_t *conn)
}
ret = __nfs_rpcsvc_program_actor (req, &program);
- if (ret != SUCCESS)
+ if (ret != SUCCESS) {
+ ret = -1;
goto err;
+ }
req->program = program;
ret = nfs_rpcsvc_authenticate (req);
@@ -1933,11 +1946,6 @@ nfs_rpcsvc_request_create (rpcsvc_conn_t *conn)
goto err;
}
-
- /* 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;
ret = 0;
err:
if (ret == -1) {
@@ -2804,6 +2812,7 @@ free_prog:
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);
}
diff --git a/xlators/nfs/lib/src/rpcsvc.h b/xlators/nfs/lib/src/rpcsvc.h
index 300111de5e0..6d4bcf89ed5 100644
--- a/xlators/nfs/lib/src/rpcsvc.h
+++ b/xlators/nfs/lib/src/rpcsvc.h
@@ -635,7 +635,11 @@ 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) (req)->auth_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);