Package: nfs-ganesha
Version: 6.5-5
Severity: important
Tags: patch upstream
X-Debbugs-Cc: [email protected]
NFS-Ganesha suddenly starts to consume CPU time, and repeats this log message
in a loop:
`rpc :TIRPC :EVENT :svc_dg_rendezvous: Bad message sa_family is 0xffff`
This continues until the NFS-Ganesha service is restarted.
There's an upstream report that this behaviour is triggered by receiving a NULL
RPC over UDP. A patch has been merged into newer NFS-Ganesha versions, but not
yet backported into Debian:
- https://github.com/nfs-ganesha/ntirpc/issues/326
- https://github.com/nfs-ganesha/ntirpc/pull/318
-- System Information:
Debian Release: 13.3
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 6.12.57+deb13-cloud-amd64 (SMP w/12 CPU threads; PREEMPT)
diff --git a/ntirpc/rpc/svc.h b/ntirpc/rpc/svc.h
index e53d5d695..748660828 100644
--- a/ntirpc/rpc/svc.h
+++ b/ntirpc/rpc/svc.h
@@ -562,9 +562,12 @@ static inline void svc_destroy_it(SVCXPRT *xprt,
(*(xprt)->xp_ops->xp_unref_user_data)(xprt);
}
- /* Let's shutdown the sockets so that FIN-ACK could be sent to the
- * client immediately. */
- if (xprt->xp_fd != RPC_ANYFD) {
+ /* Check if the connection was already set as dead or closed,
+ * If set, let's cleanup and close the FDs, so that FIN-ACK
+ * could be sent to the client immediately.
+ * Also for UDP xprt, this is never set, needn't enter here */
+ if ((atomic_fetch_uint16_t(&xprt->xp_flags) & SVC_XPRT_FLAG_CLOSE)
+ && xprt->xp_fd != RPC_ANYFD) {
(void)shutdown(xprt->xp_fd, SHUT_RDWR);
if (xprt->xp_fd_send != RPC_ANYFD)
(void)shutdown(xprt->xp_fd_send, SHUT_RDWR);
diff --git a/src/svc_dg.c b/src/svc_dg.c
index d3c7e8c00..59c614bb9 100644
--- a/src/svc_dg.c
+++ b/src/svc_dg.c
@@ -255,7 +255,7 @@ svc_dg_rendezvous(SVCXPRT *xprt)
su->su_dr.maxrec = req_su->su_dr.maxrec;
svc_dg_override_ops(newxprt, xprt);
- again:
+again:
iov.iov_base = &su[1];
iov.iov_len = su->su_dr.maxrec;
mesgp = &su->su_msghdr;
@@ -281,21 +281,21 @@ svc_dg_rendezvous(SVCXPRT *xprt)
return (XPRT_DIED);
}
- if (sp->sa_family == (sa_family_t) 0xffff) {
- __warnx(TIRPC_DEBUG_FLAG_ERROR,
- "%s: Bad message sa_family is 0xffff",
- __func__);
+ if (sp->sa_family == (sa_family_t) 0xffff) {
+ __warnx(TIRPC_DEBUG_FLAG_ERROR,
+ "%s: xprt(%p) newxprt(%p) fd %d Bad message sa_family
is 0xffff",
+ __func__, xprt, newxprt, newxprt->xp_fd);
svc_dg_xprt_free(su);
- return SVC_STAT(xprt);
- }
+ return SVC_STAT(xprt);
+ }
- if (rlen == -1 || (rlen < (ssize_t) (4 * sizeof(u_int32_t)))) {
- __warnx(TIRPC_DEBUG_FLAG_ERROR,
- "%s: Bad message rlen: %d",
- __func__, rlen);
+ if (rlen == -1 || (rlen < (ssize_t) (4 * sizeof(u_int32_t)))) {
+ __warnx(TIRPC_DEBUG_FLAG_ERROR,
+ "%s: xprt(%p) newxprt(%p) fd %d Bad message
rlen: %d",
+ __func__, xprt, newxprt, newxprt->xp_fd, rlen);
svc_dg_xprt_free(su);
- return SVC_STAT(xprt);
- }
+ return SVC_STAT(xprt);
+ }
__rpc_address_setup(&newxprt->xp_local);
__rpc_address_setup(&newxprt->xp_remote);
@@ -315,13 +315,13 @@ svc_dg_rendezvous(SVCXPRT *xprt)
#endif
xdrmem_create(su->su_dr.ioq.xdrs, iov.iov_base, iov.iov_len,
- XDR_DECODE);
+ XDR_DECODE);
SVC_REF(xprt, SVC_REF_FLAG_NONE);
newxprt->xp_parent = xprt;
atomic_set_uint16_t_bits(&newxprt->xp_flags,
- SVC_XPRT_FLAG_READY);
+ SVC_XPRT_FLAG_READY);
return (xprt->xp_dispatch.rendezvous_cb(newxprt));
}