• NeilBrown's avatar
    sunrpc/cache: handle missing listeners better. · 9d69338c
    NeilBrown authored
    If no handler (such as rpc.mountd) has opened
    a cache 'channel', the sunrpc cache responds to
    all lookup requests with -ENOENT.  This is particularly
    important for the auth.unix.gid cache which is
    optional.
    
    If the channel was open briefly and an upcall was written to it,
    this upcall remains pending even when the handler closes the
    channel.  When an upcall is pending, the code currently
    doesn't check if there are still listeners, it only performs
    that check before sending an upcall.
    
    As the cache treads a recently closes channel (closed less than
    30 seconds ago) as "potentially still open", there is a
    reasonable sized window when a request can become pending
    in a closed channel, and thereby block lookups indefinitely.
    
    This can easily be demonstrated by running
      cat /proc/net/rpc/auth.unix.gid/channel
    
    and then trying to mount an NFS filesystem from this host.  It
    will block indefinitely (unless mountd is run with --manage-gids,
    or krb5 is used).
    
    When cache_check() finds that an upcall is pending, it should
    perform the "cache_listeners_exist()" exist test.  If no
    listeners do exist, the request should be negated.
    
    With this change in place, there can still be a 30second wait on
    mount, until the cache gives up waiting for a handler to come
    back, but this is much better than an indefinite wait.
    Signed-off-by: default avatarNeilBrown <neilb@suse.com>
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    9d69338c
cache.c 45.5 KB