diff options
author | Karen Rochford <Karen.Rochford@Sun.COM> | 2010-03-22 08:06:49 -0500 |
---|---|---|
committer | Karen Rochford <Karen.Rochford@Sun.COM> | 2010-03-22 08:06:49 -0500 |
commit | 60536ef9142d77aa1b72c9be89a1833c06e14629 (patch) | |
tree | 4ca5b5817456287d72348d0c9e28d0c7de30be84 | |
parent | b92a49ee0e4c83e644a2e7f8cd7753cd479a412a (diff) | |
download | illumos-gate-60536ef9142d77aa1b72c9be89a1833c06e14629.tar.gz |
6896473 Server rpcmod panic when client trying to mount rdma/krb5
-rw-r--r-- | usr/src/uts/common/rpc/sec_gss/svc_rpcsec_gss.c | 15 | ||||
-rw-r--r-- | usr/src/uts/common/rpc/svc.c | 16 | ||||
-rw-r--r-- | usr/src/uts/common/rpc/svc.h | 12 | ||||
-rw-r--r-- | usr/src/uts/common/rpc/svc_clts.c | 20 | ||||
-rw-r--r-- | usr/src/uts/common/rpc/svc_cots.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/rpc/svc_rdma.c | 57 |
6 files changed, 93 insertions, 32 deletions
diff --git a/usr/src/uts/common/rpc/sec_gss/svc_rpcsec_gss.c b/usr/src/uts/common/rpc/sec_gss/svc_rpcsec_gss.c index ffe4255580..3d47fab865 100644 --- a/usr/src/uts/common/rpc/sec_gss/svc_rpcsec_gss.c +++ b/usr/src/uts/common/rpc/sec_gss/svc_rpcsec_gss.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -970,20 +970,9 @@ rpcsec_gss_init( /* get a xprt clone for taskq thread, taskq func must free it */ arg->rq_xprt = svc_clone_init(); - svc_clone_link(rqst->rq_xprt->xp_master, arg->rq_xprt); + svc_clone_link(rqst->rq_xprt->xp_master, arg->rq_xprt, rqst->rq_xprt); arg->rq_xprt->xp_xid = rqst->rq_xprt->xp_xid; - /* UDP uses the incoming mblk for the response, so dup it. */ - /* Note this probably should be done by svc_clone_link(). */ - if (rqst->rq_xprt->xp_type == T_CLTS) { - struct udp_data *ud_src = - (struct udp_data *)rqst->rq_xprt->xp_p2buf; - struct udp_data *ud_dst = - (struct udp_data *)arg->rq_xprt->xp_p2buf; - if (ud_src->ud_resp) { - ud_dst->ud_resp = dupb(ud_src->ud_resp); - } - } /* set the appropriate wrap/unwrap routine for RPCSEC_GSS */ arg->rq_xprt->xp_auth.svc_ah_ops = svc_rpc_gss_ops; diff --git a/usr/src/uts/common/rpc/svc.c b/usr/src/uts/common/rpc/svc.c index 7c2f7f2f5e..a6bf8c76b2 100644 --- a/usr/src/uts/common/rpc/svc.c +++ b/usr/src/uts/common/rpc/svc.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1469,7 +1469,7 @@ svc_clone_free(SVCXPRT *clone_xprt) * - call a transport specific clone routine. */ void -svc_clone_link(SVCMASTERXPRT *xprt, SVCXPRT *clone_xprt) +svc_clone_link(SVCMASTERXPRT *xprt, SVCXPRT *clone_xprt, SVCXPRT *clone_xprt2) { cred_t *cred = clone_xprt->xp_cred; @@ -1496,14 +1496,8 @@ svc_clone_link(SVCMASTERXPRT *xprt, SVCXPRT *clone_xprt) /* Restore per-thread fields (xp_cred) */ clone_xprt->xp_cred = cred; - - /* - * NOTICE: There is no transport-type specific code now. - * If you want to add a transport-type specific cloning code - * add one more operation (e.g. xp_clone()) to svc_ops, - * implement it for each transport type, and call it here - * through an appropriate macro (e.g. SVC_CLONE()). - */ + if (clone_xprt2) + SVC_CLONE_XPRT(clone_xprt2, clone_xprt); } /* @@ -2192,7 +2186,7 @@ svc_run(SVCPOOL *pool) if (next != xprt) { if (xprt) svc_clone_unlink(clone_xprt); - svc_clone_link(next, clone_xprt); + svc_clone_link(next, clone_xprt, NULL); xprt = next; } diff --git a/usr/src/uts/common/rpc/svc.h b/usr/src/uts/common/rpc/svc.h index cd9149afd2..912d5b3961 100644 --- a/usr/src/uts/common/rpc/svc.h +++ b/usr/src/uts/common/rpc/svc.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ @@ -187,6 +187,8 @@ struct svc_ops { /* destroy a clone xprt */ void (*xp_start)(SVCMASTERXPRT *); /* `ready-to-receive' */ + void (*xp_clone_xprt)(SVCXPRT *, SVCXPRT *); + /* transport specific clone function */ }; #else /* _KERNEL */ /* @@ -510,6 +512,12 @@ struct __svcxprt { */ #ifdef _KERNEL + +#define SVC_CLONE_XPRT(src_xprt, dst_xprt) \ + if ((src_xprt)->xp_ops->xp_clone_xprt) \ + (*(src_xprt)->xp_ops->xp_clone_xprt) \ + (src_xprt, dst_xprt) + #define SVC_RECV(clone_xprt, mp, msg) \ (*(clone_xprt)->xp_ops->xp_recv)((clone_xprt), (mp), (msg)) @@ -1103,7 +1111,7 @@ extern int __svc_vc_dupdone(); */ extern SVCXPRT *svc_clone_init(void); extern void svc_clone_free(SVCXPRT *); -extern void svc_clone_link(SVCMASTERXPRT *, SVCXPRT *); +extern void svc_clone_link(SVCMASTERXPRT *, SVCXPRT *, SVCXPRT *); extern void svc_clone_unlink(SVCXPRT *); #endif /* _KERNEL */ diff --git a/usr/src/uts/common/rpc/svc_clts.c b/usr/src/uts/common/rpc/svc_clts.c index 56355eae8a..a738e63863 100644 --- a/usr/src/uts/common/rpc/svc_clts.c +++ b/usr/src/uts/common/rpc/svc_clts.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -79,6 +79,7 @@ static int32_t *svc_clts_kgetres(SVCXPRT *, int); static void svc_clts_kclone_destroy(SVCXPRT *); static void svc_clts_kfreeres(SVCXPRT *); static void svc_clts_kstart(SVCMASTERXPRT *); +static void svc_clts_kclone_xprt(SVCXPRT *, SVCXPRT *); /* * Server transport operations vector. @@ -94,7 +95,8 @@ struct svc_ops svc_clts_op = { svc_clts_kgetres, /* Get pointer to response buffer */ svc_clts_kfreeres, /* Destroy pre-serialized response header */ svc_clts_kclone_destroy, /* Destroy a clone xprt */ - svc_clts_kstart /* Tell `ready-to-receive' to rpcmod */ + svc_clts_kstart, /* Tell `ready-to-receive' to rpcmod */ + svc_clts_kclone_xprt /* transport specific clone xprt function */ }; /* @@ -230,6 +232,20 @@ svc_clts_kstart(SVCMASTERXPRT *xprt) { } +static void +svc_clts_kclone_xprt(SVCXPRT *src_xprt, SVCXPRT *dst_xprt) +{ + struct udp_data *ud_src = + (struct udp_data *)src_xprt->xp_p2buf; + struct udp_data *ud_dst = + (struct udp_data *)dst_xprt->xp_p2buf; + + if (ud_src->ud_resp) + ud_dst->ud_resp = dupb(ud_src->ud_resp); + +} + + /* * Receive rpc requests. * Pulls a request in off the socket, checks if the packet is intact, diff --git a/usr/src/uts/common/rpc/svc_cots.c b/usr/src/uts/common/rpc/svc_cots.c index c010f145a3..32ad943958 100644 --- a/usr/src/uts/common/rpc/svc_cots.c +++ b/usr/src/uts/common/rpc/svc_cots.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -99,7 +99,8 @@ struct svc_ops svc_cots_op = { svc_cots_kgetres, /* Get pointer to response buffer */ svc_cots_kfreeres, /* Destroy pre-serialized response header */ svc_cots_kclone_destroy, /* Destroy a clone xprt */ - svc_cots_kstart /* Tell `ready-to-receive' to rpcmod */ + svc_cots_kstart, /* Tell `ready-to-receive' to rpcmod */ + NULL /* Transport specific clone xprt */ }; /* diff --git a/usr/src/uts/common/rpc/svc_rdma.c b/usr/src/uts/common/rpc/svc_rdma.c index 18c32559c6..89770026e1 100644 --- a/usr/src/uts/common/rpc/svc_rdma.c +++ b/usr/src/uts/common/rpc/svc_rdma.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ @@ -90,12 +90,14 @@ struct rdma_data { * Plugin connection specific data stashed away in clone SVCXPRT */ struct clone_rdma_data { + bool_t cloned; /* xprt cloned for thread processing */ CONN *conn; /* RDMA connection */ rdma_buf_t rpcbuf; /* RPC req/resp buffer */ struct clist *cl_reply; /* reply chunk buffer info */ struct clist *cl_wlist; /* write list clist */ }; + #define MAXADDRLEN 128 /* max length for address mask */ /* @@ -115,6 +117,7 @@ static void svc_rdma_kfreeres(SVCXPRT *); static void svc_rdma_kclone_destroy(SVCXPRT *); static void svc_rdma_kstart(SVCMASTERXPRT *); void svc_rdma_kstop(SVCMASTERXPRT *); +static void svc_rdma_kclone_xprt(SVCXPRT *, SVCXPRT *); static int svc_process_long_reply(SVCXPRT *, xdrproc_t, caddr_t, struct rpc_msg *, bool_t, int *, @@ -141,7 +144,8 @@ struct svc_ops rdma_svc_ops = { svc_rdma_kgetres, /* Get pointer to response buffer */ svc_rdma_kfreeres, /* Destroy pre-serialized response header */ svc_rdma_kclone_destroy, /* Destroy a clone xprt */ - svc_rdma_kstart /* Tell `ready-to-receive' to rpcmod */ + svc_rdma_kstart, /* Tell `ready-to-receive' to rpcmod */ + svc_rdma_kclone_xprt /* Transport specific clone xprt */ }; /* @@ -384,8 +388,46 @@ svc_rdma_kstop(SVCMASTERXPRT *xprt) static void svc_rdma_kclone_destroy(SVCXPRT *clone_xprt) { + + struct clone_rdma_data *cdrp; + cdrp = (struct clone_rdma_data *)clone_xprt->xp_p2buf; + + /* + * Only free buffers and release connection when cloned is set. + */ + if (cdrp->cloned != TRUE) + return; + + rdma_buf_free(cdrp->conn, &cdrp->rpcbuf); + if (cdrp->cl_reply) { + clist_free(cdrp->cl_reply); + cdrp->cl_reply = NULL; + } + RDMA_REL_CONN(cdrp->conn); + + cdrp->cloned = 0; } +/* + * Clone the xprt specific information. It will be freed by + * SVC_CLONE_DESTROY. + */ +static void +svc_rdma_kclone_xprt(SVCXPRT *src_xprt, SVCXPRT *dst_xprt) +{ + struct clone_rdma_data *srcp2; + struct clone_rdma_data *dstp2; + + srcp2 = (struct clone_rdma_data *)src_xprt->xp_p2buf; + dstp2 = (struct clone_rdma_data *)dst_xprt->xp_p2buf; + + if (srcp2->conn != NULL) { + srcp2->cloned = TRUE; + *dstp2 = *srcp2; + } +} + + static bool_t svc_rdma_krecv(SVCXPRT *clone_xprt, mblk_t *mp, struct rpc_msg *msg) { @@ -1029,7 +1071,18 @@ svc_rdma_kfreeargs(SVCXPRT *clone_xprt, xdrproc_t xdr_args, struct clone_rdma_data *crdp; bool_t retval; + /* + * If the cloned bit is true, then this transport specific + * rmda data has been duplicated into another cloned xprt. Do + * not free, or release the connection, it is still in use. The + * buffers will be freed and the connection released later by + * SVC_CLONE_DESTROY(). + */ crdp = (struct clone_rdma_data *)clone_xprt->xp_p2buf; + if (crdp->cloned == TRUE) { + crdp->cloned = 0; + return (TRUE); + } /* * Free the args if needed then XDR_DESTROY |