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));
 }

Reply via email to