Hi,

we seem to have the same or a very similar problem here: mountd crashes
reproducibly after the second mount/umount request.

I have compiled mountd with debugging, and installed the debugging
version of libc.

on the NFS server:

    # COLUMNS=100 dpkg -l libc6 nfs-kernel-server libnss-ldap
    ii  libc6               2.3.2.ds1-22        GNU C Library: Shared libraries 
and Timezone data
    ii  nfs-kernel-server   1.0.6-3.1           Kernel NFS server support
    ii  libnss-ldap         238-1               NSS module for using LDAP as a 
naming service

    # grep netgroup /etc/nsswitch.conf
    netgroup:       ldap

on the NFS server, in nfs-utils-1.0.6/utils/mountd:

    # LD_LIBRARY_PATH=/usr/lib/debug gdb mountd
    ...
    (gdb) directory /people/mike/tmp/nfs/glibc-2.3.2.ds1/glibc-2.3.2/sunrpc
    Source directories searched: 
/people/mike/tmp/nfs/glibc-2.3.2.ds1/glibc-2.3.2/sunrpc:$cdir:$cwd
    (gdb) run -F
    Starting program: /people/mike/tmp/nfs/nfs-utils-1.0.6/utils/mountd/mountd 
-F

on the NFS client:

    # mount /archive

meanwhile on the NFS server: creates new thread

    [Thread debugging using libthread_db enabled]
    [New Thread 16384 (LWP 13211)]

on the NFS client, a second (u)mount request

    # umount /archive

on the NFS server: presto SEGV

    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 16384 (LWP 13211)]
    0x40139ff7 in svc_getreq_common (fd=7) at svc.c:415
    warning: Source file is more recent than executable.

    415       xprt = xports[fd];

Now, the problem seems to be as follows. The xports variable is
thread-safe:

    glibc-2.3.2/sunrpc/svc.c:47

        #define xports ((SVCXPRT **)RPC_THREAD_VARIABLE(svc_xports_s))

On program startup, xports was lazily initialized in
glibc-2.3.2/sunrpc/svc.c:82

        xports = (SVCXPRT **) malloc (_rpc_dtablesize () * sizeof (SVCXPRT      
   *));

But we are in a new thread (see above "[New Thread 16384 (LWP 13211)]")
that has empty thread-local rpc variables:

    glibc-2.3.2/include/rpc/rpc.h:50

        #define RPC_THREAD_VARIABLE(x) (__rpc_thread_variables()->x)

    (gdb) p *__rpc_thread_variables()
      $2 = {svc_fdset_s = {fds_bits = {0 <repeats 32 times>}}, rpc_createerr_s 
= {cf_stat = RPC_SUCCESS, cf_error = {
        re_status = RPC_SUCCESS, ru = {RE_errno = 0, RE_why = AUTH_OK, RE_vers 
= {low = 0, high = 0}, RE_lb = {
            s1 = 0, s2 = 0}}}}, svc_pollfd_s = 0x0, svc_max_pollfd_s = 0, 
clnt_perr_buf_s = 0x0,
      clntraw_private_s = 0x0, callrpc_private_s = 0x0, key_call_private_s = 
0x0, authdes_cache_s = 0x0,
      authdes_lru_s = 0x0, svc_xports_s = 0x0, svc_head_s = 0x0, 
svcraw_private_s = 0x0, svcsimple_proglst_s = 0x0,
      svcsimple_transp_s = 0x0}

Therefore, in this thread, the sunrpc facility is not initialized, and no
service handlers registered. Since xports is dereferenced unconditionally,
this leads to a SEGV.

In my opinion, the sunrpc facility in glibc is _too_ thread-safe, as the
registration of service handlers is not known across threads. mountd
itself is not to blame, as it does not knowingly open a new thread.

Please let me know if you have any ideas on how to debug this further.

Best wishes, Mike

PS: The following libraries are loaded, and I suspect one of them to open
    the new thread (as the sunrpc does not seem to create new threads
    itself):

    # cat /proc/13211/maps | awk '{ print $6}' | sort | uniq

    /lib/ld-2.3.2.so
    /lib/libcom_err.so.2.1
    /lib/libnss_ldap-2.3.2.so
    /lib/libwrap.so.0.7.6
    /people/mike/tmp/nfs/nfs-utils-1.0.6/utils/mountd/mountd
    /usr/lib/debug/libc-2.3.2.so
    /usr/lib/debug/libcrypt-2.3.2.so
    /usr/lib/debug/libdl-2.3.2.so
    /usr/lib/debug/libnsl-2.3.2.so
    /usr/lib/debug/libnss_dns-2.3.2.so
    /usr/lib/debug/libnss_files-2.3.2.so
    /usr/lib/debug/libpthread-0.10.so
    /usr/lib/debug/libresolv-2.3.2.so
    /usr/lib/libdb-4.2.so
    /usr/lib/libgcrypt.so.11.1.1
    /usr/lib/libgnutls.so.11.1.16
    /usr/lib/libgpg-error.so.0.1.3
    /usr/lib/libgssapi_krb5.so.2.2
    /usr/lib/libk5crypto.so.3.0
    /usr/lib/libkrb5.so.3.2
    /usr/lib/liblber.so.2.0.130
    /usr/lib/libldap_r.so.2.0.130
    /usr/lib/libsasl2.so.2.0.19
    /usr/lib/libtasn1.so.2.0.10
    /usr/lib/libz.so.1.2.1.1
    /usr/lib/sasl2/libsasldb.so.2.0.19

-- 
If you don't breathe, there is no air.          DI Michael Wildpaner
If you don't walk, there is no earth.                  Ph.D. Student
If you don't speak, there is no world.
    -- Navajo (Dineh) wisdom


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to