SUNRPC: Faster detection if gssd is actually running

Recent changes to the NFS security flavour negotiation mean that
we have a stronger dependency on rpc.gssd. If the latter is not
running, because the user failed to start it, then we time out
and mark the container as not having an instance. We then
use that information to time out faster the next time.

If, on the other hand, the rpc.gssd successfully binds to an rpc_pipe,
then we mark the container as having an rpc.gssd instance.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

+18 -1
+12 -1
net/sunrpc/auth_gss/auth_gss.c
··· 52 52 #include <linux/sunrpc/gss_api.h> 53 53 #include <asm/uaccess.h> 54 54 55 + #include "../netns.h" 56 + 55 57 static const struct rpc_authops authgss_ops; 56 58 57 59 static const struct rpc_credops gss_credops; ··· 561 559 static inline int 562 560 gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) 563 561 { 562 + struct net *net = rpc_net_ns(gss_auth->client); 563 + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 564 564 struct rpc_pipe *pipe; 565 565 struct rpc_cred *cred = &gss_cred->gc_base; 566 566 struct gss_upcall_msg *gss_msg; 567 + unsigned long timeout; 567 568 DEFINE_WAIT(wait); 568 569 int err; 569 570 ··· 574 569 __func__, from_kuid(&init_user_ns, cred->cr_uid)); 575 570 retry: 576 571 err = 0; 572 + /* Default timeout is 15s unless we know that gssd is not running */ 573 + timeout = 15 * HZ; 574 + if (!sn->gssd_running) 575 + timeout = HZ >> 2; 577 576 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); 578 577 if (PTR_ERR(gss_msg) == -EAGAIN) { 579 578 err = wait_event_interruptible_timeout(pipe_version_waitqueue, 580 - pipe_version >= 0, 15*HZ); 579 + pipe_version >= 0, timeout); 581 580 if (pipe_version < 0) { 581 + if (err == 0) 582 + sn->gssd_running = 0; 582 583 warn_gssd(); 583 584 err = -EACCES; 584 585 }
+2
net/sunrpc/netns.h
··· 29 29 struct rpc_clnt *gssp_clnt; 30 30 int use_gss_proxy; 31 31 struct proc_dir_entry *use_gssp_proc; 32 + 33 + unsigned int gssd_running; 32 34 }; 33 35 34 36 extern int sunrpc_net_id;
+4
net/sunrpc/rpc_pipe.c
··· 216 216 static int 217 217 rpc_pipe_open(struct inode *inode, struct file *filp) 218 218 { 219 + struct net *net = inode->i_sb->s_fs_info; 220 + struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 219 221 struct rpc_pipe *pipe; 220 222 int first_open; 221 223 int res = -ENXIO; 222 224 223 225 mutex_lock(&inode->i_mutex); 226 + sn->gssd_running = 1; 224 227 pipe = RPC_I(inode)->pipe; 225 228 if (pipe == NULL) 226 229 goto out; ··· 1072 1069 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1073 1070 1074 1071 mutex_init(&sn->pipefs_sb_lock); 1072 + sn->gssd_running = 1; 1075 1073 } 1076 1074 1077 1075 /*