FreeBSD Bugzilla – Attachment 223883 Details for
Bug 254840
NFSv4.1/4.2 client does not do a BindConnectionToSession for new TCP connections
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
fix NFSv4.1/4.2 client to do a BindConnectionToSession to maintain the backchannel
clntbind.patch (text/plain), 9.79 KB, created by
Rick Macklem
on 2021-04-06 23:20:44 UTC
(
hide
)
Description:
fix NFSv4.1/4.2 client to do a BindConnectionToSession to maintain the backchannel
Filename:
MIME Type:
Creator:
Rick Macklem
Created:
2021-04-06 23:20:44 UTC
Size:
9.79 KB
patch
obsolete
>--- sys/fs/nfs/nfsport.h.bc 2021-04-06 00:52:37.070211000 -0700 >+++ sys/fs/nfs/nfsport.h 2021-03-23 16:22:37.000000000 -0700 >@@ -412,10 +412,13 @@ > #define NFSPROC_RMEXTATTR 63 > #define NFSPROC_LISTEXTATTR 64 > >+/* BindConnectionToSession, done by the krpc for a new connection. */ >+#define NFSPROC_BINDCONNTOSESS 65 >+ > /* > * Must be defined as one higher than the last NFSv4.2 Proc# above. > */ >-#define NFSV42_NPROCS 65 >+#define NFSV42_NPROCS 66 > > #endif /* NFS_V3NPROCS */ > >@@ -444,7 +447,7 @@ struct nfsstatsv1 { > uint64_t readlink_bios; > uint64_t biocache_readdirs; > uint64_t readdir_bios; >- uint64_t rpccnt[NFSV42_NPROCS + 15]; >+ uint64_t rpccnt[NFSV42_NPROCS + 14]; > uint64_t rpcretries; > uint64_t srvrpccnt[NFSV42_NOPS + NFSV4OP_FAKENOPS + 15]; > uint64_t reserved_0; >@@ -509,7 +512,7 @@ struct nfsstatsov1 { > uint64_t readlink_bios; > uint64_t biocache_readdirs; > uint64_t readdir_bios; >- uint64_t rpccnt[NFSV42_NPROCS + 4]; >+ uint64_t rpccnt[NFSV42_NPROCS + 3]; > uint64_t rpcretries; > uint64_t srvrpccnt[NFSV42_PURENOPS + NFSV4OP_FAKENOPS]; > uint64_t reserved_0; >@@ -1006,6 +1009,7 @@ bool ncl_pager_setsize(struct vnode *vp, u_quad_t *nsi > * "out by one" without disastrous consequences. > */ > #define NFSINCRGLOBAL(a) ((a)++) >+#define NFSDECRGLOBAL(a) ((a)--) > > /* > * Assorted funky stuff to make things work under Darwin8. >--- sys/fs/nfs/nfsproto.h.bc 2021-03-23 12:04:08.210255000 -0700 >+++ sys/fs/nfs/nfsproto.h 2021-03-23 16:23:09.000000000 -0700 >@@ -394,10 +394,13 @@ > #define NFSPROC_RMEXTATTR 63 > #define NFSPROC_LISTEXTATTR 64 > >+/* BindConnectionToSession, done by the krpc for a new connection. */ >+#define NFSPROC_BINDCONNTOSESS 65 >+ > /* > * Must be defined as one higher than the last NFSv4.2 Proc# above. > */ >-#define NFSV42_NPROCS 65 >+#define NFSV42_NPROCS 66 > > #endif /* NFS_V3NPROCS */ > >--- sys/fs/nfs/nfs_var.h.bc 2021-03-23 12:04:21.163112000 -0700 >+++ sys/fs/nfs/nfs_var.h 2021-04-03 10:54:08.575100000 -0700 >@@ -561,6 +561,7 @@ int nfsrpc_listextattr(vnode_t, uint64_t *, struct uio > struct nfsvattr *, int *, struct ucred *, NFSPROC_T *); > int nfsrpc_rmextattr(vnode_t, const char *, struct nfsvattr *, int *, > struct ucred *, NFSPROC_T *); >+void nfsrpc_bindconnsess(CLIENT *, void *, struct ucred *); > > /* nfs_clstate.c */ > int nfscl_open(vnode_t, u_int8_t *, int, u_int32_t, int, >--- sys/fs/nfs/nfs_commonsubs.c.bc 2021-03-23 12:04:41.516877000 -0700 >+++ sys/fs/nfs/nfs_commonsubs.c 2021-04-05 07:04:40.804714000 -0700 >@@ -218,7 +218,7 @@ static struct nfsrv_lughash *nfsgroupnamehash; > static int nfs_bigreply[NFSV42_NPROCS] = { 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, > 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, >- 1, 0, 0, 1 }; >+ 1, 0, 0, 1, 0 }; > > /* local functions */ > static int nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep); >@@ -301,6 +301,7 @@ static struct { > { NFSV4OP_SETXATTR, 2, "Setxattr", 8, }, > { NFSV4OP_REMOVEXATTR, 2, "Rmxattr", 7, }, > { NFSV4OP_LISTXATTRS, 2, "Listxattr", 9, }, >+ { NFSV4OP_BINDCONNTOSESS, 1, "BindConSess", 11, }, > }; > > /* >@@ -309,7 +310,7 @@ static struct { > static int nfs_bigrequest[NFSV42_NPROCS] = { > 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, > 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, >- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 >+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 > }; > > /* >--- sys/fs/nfs/nfscl.h.bc 2021-03-24 08:44:36.568914000 -0700 >+++ sys/fs/nfs/nfscl.h 2021-03-24 13:04:14.000000000 -0700 >@@ -81,4 +81,9 @@ struct nfsv4node { > printf(__VA_ARGS__); \ > } while (0) > >+struct nfscl_reconarg { >+ int minorvers; >+ uint8_t sessionid[NFSX_V4SESSIONID]; >+}; >+ > #endif /* _NFS_NFSCL_H */ >--- sys/fs/nfsclient/nfs_clrpcops.c.bc 2021-04-06 01:06:06.586782000 -0700 >+++ sys/fs/nfsclient/nfs_clrpcops.c 2021-03-28 07:21:33.759492000 -0700 >@@ -946,6 +946,8 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclcli > struct nfsclds *dsp, *odsp; > struct in6_addr a6; > struct nfsclsession *tsep; >+ struct rpc_reconupcall recon; >+ struct nfscl_reconarg *rcp; > > if (nfsboottime.tv_sec == 0) > NFSSETBOOTTIME(nfsboottime); >@@ -1019,6 +1021,23 @@ nfsrpc_setclient(struct nfsmount *nmp, struct nfsclcli > NFSCL_DEBUG(1, "aft createsess=%d\n", error); > } > if (error == 0) { >+ /* >+ * If the session supports a backchannel, set up >+ * the BindConnectionToSession call in the krpc >+ * so that it is done on a reconnection. >+ */ >+ if (nfscl_enablecallb != 0 && nfs_numnfscbd > 0) { >+ rcp = mem_alloc(sizeof(*rcp)); >+ rcp->minorvers = nmp->nm_minorvers; >+ memcpy(rcp->sessionid, >+ dsp->nfsclds_sess.nfsess_sessionid, >+ NFSX_V4SESSIONID); >+ recon.call = nfsrpc_bindconnsess; >+ recon.arg = rcp; >+ CLNT_CONTROL(nmp->nm_client, CLSET_RECONUPCALL, >+ &recon); >+ } >+ > NFSLOCKMNT(nmp); > /* > * The old sessions cannot be safely free'd >@@ -8709,3 +8728,75 @@ nfsm_split(struct mbuf *mp, uint64_t xfer) > m->m_next = NULL; > return (m2); > } >+ >+/* >+ * Do the NFSv4.1 Bind Connection to Session. >+ * Called from the reconnect layer of the krpc (sys/rpc/clnt_rc.c). >+ */ >+void >+nfsrpc_bindconnsess(CLIENT *cl, void *arg, struct ucred *cr) >+{ >+ struct nfscl_reconarg *rcp = (struct nfscl_reconarg *)arg; >+ uint32_t res, *tl; >+ struct nfsrv_descript nfsd; >+ struct nfsrv_descript *nd = &nfsd; >+ struct rpc_callextra ext; >+ struct timeval utimeout; >+ enum clnt_stat stat; >+ int error; >+ >+ nfscl_reqstart(nd, NFSPROC_BINDCONNTOSESS, NULL, NULL, 0, NULL, NULL, >+ NFS_VER4, rcp->minorvers); >+ NFSM_BUILD(tl, uint32_t *, NFSX_V4SESSIONID + 2 * NFSX_UNSIGNED); >+ memcpy(tl, rcp->sessionid, NFSX_V4SESSIONID); >+ tl += NFSX_V4SESSIONID / NFSX_UNSIGNED; >+ *tl++ = txdr_unsigned(NFSCDFC4_FORE_OR_BOTH); >+ *tl = newnfs_false; >+ >+ memset(&ext, 0, sizeof(ext)); >+ utimeout.tv_sec = 30; >+ utimeout.tv_usec = 0; >+ ext.rc_auth = authunix_create(cr); >+ nd->nd_mrep = NULL; >+ stat = CLNT_CALL_MBUF(cl, &ext, NFSV4PROC_COMPOUND, nd->nd_mreq, >+ &nd->nd_mrep, utimeout); >+ AUTH_DESTROY(ext.rc_auth); >+ if (stat != RPC_SUCCESS) { >+ printf("nfsrpc_bindconnsess: call failed stat=%d\n", stat); >+ return; >+ } >+ if (nd->nd_mrep == NULL) { >+ printf("nfsrpc_bindconnsess: no reply args\n"); >+ return; >+ } >+ error = 0; >+ newnfs_realign(&nd->nd_mrep, M_WAITOK); >+ nd->nd_md = nd->nd_mrep; >+ nd->nd_dpos = mtod(nd->nd_md, char *); >+ NFSM_DISSECT(tl, uint32_t *, 2 * NFSX_UNSIGNED); >+ nd->nd_repstat = fxdr_unsigned(uint32_t, *tl++); >+ if (nd->nd_repstat == NFSERR_OK) { >+ res = fxdr_unsigned(uint32_t, *tl); >+ if (res > 0 && (error = nfsm_advance(nd, NFSM_RNDUP(res), >+ -1)) != 0) >+ goto nfsmout; >+ NFSM_DISSECT(tl, uint32_t *, NFSX_V4SESSIONID + >+ 4 * NFSX_UNSIGNED); >+ tl += 3; >+ if (!NFSBCMP(tl, rcp->sessionid, NFSX_V4SESSIONID)) { >+ tl += NFSX_V4SESSIONID / NFSX_UNSIGNED; >+ res = fxdr_unsigned(uint32_t, *tl); >+ if (res != NFSCDFS4_BOTH) >+ printf("nfsrpc_bindconnsess: did not " >+ "return FS4_BOTH\n"); >+ } else >+ printf("nfsrpc_bindconnsess: not same " >+ "sessionid\n"); >+ } else >+ printf("nfsrpc_bindconnsess: returned %d\n", nd->nd_repstat); >+nfsmout: >+ if (error != 0) >+ printf("nfsrpc_bindconnsess: reply bad xdr\n"); >+ m_freem(nd->nd_mrep); >+} >+ >--- sys/rpc/krpc.h.bc 2021-03-23 12:02:30.993335000 -0700 >+++ sys/rpc/krpc.h 2021-03-24 14:17:05.000000000 -0700 >@@ -81,6 +81,9 @@ struct rc_data { > void *rc_backchannel; > bool rc_tls; /* Enable TLS on connection */ > char *rc_tlscertname; >+ void (*rc_reconcall)(CLIENT *, void *, >+ struct ucred *); /* reconection upcall */ >+ void *rc_reconarg; /* upcall arg */ > }; > > /* Bits for ct_rcvstate. */ >--- sys/rpc/clnt.h.bc 2021-03-23 12:02:43.013133000 -0700 >+++ sys/rpc/clnt.h 2021-03-25 05:42:01.000000000 -0700 >@@ -360,6 +360,12 @@ enum clnt_stat clnt_call_private(CLIENT *, struct rpc_ > #define CLSET_TLS 30 /* set TLS for socket */ > #define CLSET_BLOCKRCV 31 /* Temporarily block reception */ > #define CLSET_TLSCERTNAME 32 /* TLS certificate file name */ >+/* Structure used as the argument for CLSET_RECONUPCALL. */ >+struct rpc_reconupcall { >+ void (*call)(CLIENT *, void *, struct ucred *); >+ void *arg; >+}; >+#define CLSET_RECONUPCALL 33 /* Reconnect upcall */ > #endif > > >--- sys/rpc/clnt_rc.c.bc 2021-03-23 12:03:02.451346000 -0700 >+++ sys/rpc/clnt_rc.c 2021-03-25 00:00:16.684092000 -0700 >@@ -111,6 +111,8 @@ clnt_reconnect_create( > rc->rc_client = NULL; > rc->rc_tls = false; > rc->rc_tlscertname = NULL; >+ rc->rc_reconcall = NULL; >+ rc->rc_reconarg = NULL; > > cl->cl_refs = 1; > cl->cl_ops = &clnt_reconnect_ops; >@@ -213,6 +215,9 @@ clnt_reconnect_connect(CLIENT *cl) > goto out; > } > } >+ if (newclient != NULL && rc->rc_reconcall != NULL) >+ (*rc->rc_reconcall)(newclient, rc->rc_reconarg, >+ rc->rc_ucred); > } > td->td_ucred = oldcred; > >@@ -408,6 +413,7 @@ clnt_reconnect_control(CLIENT *cl, u_int request, void > struct rc_data *rc = (struct rc_data *)cl->cl_private; > SVCXPRT *xprt; > size_t slen; >+ struct rpc_reconupcall *upcp; > > if (info == NULL) { > return (FALSE); >@@ -513,6 +519,12 @@ clnt_reconnect_control(CLIENT *cl, u_int request, void > strlcpy(rc->rc_tlscertname, info, slen); > break; > >+ case CLSET_RECONUPCALL: >+ upcp = (struct rpc_reconupcall *)info; >+ rc->rc_reconcall = upcp->call; >+ rc->rc_reconarg = upcp->arg; >+ break; >+ > default: > return (FALSE); > } >@@ -555,12 +567,15 @@ clnt_reconnect_destroy(CLIENT *cl) > CLNT_DESTROY(rc->rc_client); > if (rc->rc_backchannel) { > xprt = (SVCXPRT *)rc->rc_backchannel; >+ KASSERT(xprt->xp_socket == NULL, >+ ("clnt_reconnect_destroy: xp_socket not NULL")); > xprt_unregister(xprt); > SVC_RELEASE(xprt); > } > crfree(rc->rc_ucred); > mtx_destroy(&rc->rc_lock); > mem_free(rc->rc_tlscertname, 0); /* 0 ok, since arg. ignored. */ >+ mem_free(rc->rc_reconarg, 0); > mem_free(rc, sizeof(*rc)); > mem_free(cl, sizeof (CLIENT)); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 254840
: 223883 |
224005