aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-05-15 14:28:54 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-05-16 09:15:41 -0400
commitabfdbd53a4e28844ad953b313f017f55edbb85b7 (patch)
treee75cce0ff477831f77a5cb4be6984a7a9248132b /net
parentd36ccb9cec22a09a12d9ef8234d634f840d7ae4b (diff)
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>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c13
-rw-r--r--net/sunrpc/netns.h2
-rw-r--r--net/sunrpc/rpc_pipe.c4
3 files changed, 18 insertions, 1 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index f17f3c581ff4..3aff72f78bf2 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -52,6 +52,8 @@
52#include <linux/sunrpc/gss_api.h> 52#include <linux/sunrpc/gss_api.h>
53#include <asm/uaccess.h> 53#include <asm/uaccess.h>
54 54
55#include "../netns.h"
56
55static const struct rpc_authops authgss_ops; 57static const struct rpc_authops authgss_ops;
56 58
57static const struct rpc_credops gss_credops; 59static const struct rpc_credops gss_credops;
@@ -559,9 +561,12 @@ out:
559static inline int 561static inline int
560gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) 562gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
561{ 563{
564 struct net *net = rpc_net_ns(gss_auth->client);
565 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
562 struct rpc_pipe *pipe; 566 struct rpc_pipe *pipe;
563 struct rpc_cred *cred = &gss_cred->gc_base; 567 struct rpc_cred *cred = &gss_cred->gc_base;
564 struct gss_upcall_msg *gss_msg; 568 struct gss_upcall_msg *gss_msg;
569 unsigned long timeout;
565 DEFINE_WAIT(wait); 570 DEFINE_WAIT(wait);
566 int err; 571 int err;
567 572
@@ -569,11 +574,17 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
569 __func__, from_kuid(&init_user_ns, cred->cr_uid)); 574 __func__, from_kuid(&init_user_ns, cred->cr_uid));
570retry: 575retry:
571 err = 0; 576 err = 0;
577 /* Default timeout is 15s unless we know that gssd is not running */
578 timeout = 15 * HZ;
579 if (!sn->gssd_running)
580 timeout = HZ >> 2;
572 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); 581 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
573 if (PTR_ERR(gss_msg) == -EAGAIN) { 582 if (PTR_ERR(gss_msg) == -EAGAIN) {
574 err = wait_event_interruptible_timeout(pipe_version_waitqueue, 583 err = wait_event_interruptible_timeout(pipe_version_waitqueue,
575 pipe_version >= 0, 15*HZ); 584 pipe_version >= 0, timeout);
576 if (pipe_version < 0) { 585 if (pipe_version < 0) {
586 if (err == 0)
587 sn->gssd_running = 0;
577 warn_gssd(); 588 warn_gssd();
578 err = -EACCES; 589 err = -EACCES;
579 } 590 }
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index 7111a4c9113b..0827f641e8d7 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -29,6 +29,8 @@ struct sunrpc_net {
29 struct rpc_clnt *gssp_clnt; 29 struct rpc_clnt *gssp_clnt;
30 int use_gss_proxy; 30 int use_gss_proxy;
31 struct proc_dir_entry *use_gssp_proc; 31 struct proc_dir_entry *use_gssp_proc;
32
33 unsigned int gssd_running;
32}; 34};
33 35
34extern int sunrpc_net_id; 36extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index a9129f8d7070..a370762e459d 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -216,11 +216,14 @@ rpc_destroy_inode(struct inode *inode)
216static int 216static int
217rpc_pipe_open(struct inode *inode, struct file *filp) 217rpc_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 struct rpc_pipe *pipe; 221 struct rpc_pipe *pipe;
220 int first_open; 222 int first_open;
221 int res = -ENXIO; 223 int res = -ENXIO;
222 224
223 mutex_lock(&inode->i_mutex); 225 mutex_lock(&inode->i_mutex);
226 sn->gssd_running = 1;
224 pipe = RPC_I(inode)->pipe; 227 pipe = RPC_I(inode)->pipe;
225 if (pipe == NULL) 228 if (pipe == NULL)
226 goto out; 229 goto out;
@@ -1069,6 +1072,7 @@ void rpc_pipefs_init_net(struct net *net)
1069 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 1072 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
1070 1073
1071 mutex_init(&sn->pipefs_sb_lock); 1074 mutex_init(&sn->pipefs_sb_lock);
1075 sn->gssd_running = 1;
1072} 1076}
1073 1077
1074/* 1078/*