Skip to content

Commit

Permalink
SUNRPC: Faster detection if gssd is actually running
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed May 16, 2013
1 parent d36ccb9 commit abfdbd5
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
13 changes: 12 additions & 1 deletion net/sunrpc/auth_gss/auth_gss.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
#include <linux/sunrpc/gss_api.h>
#include <asm/uaccess.h>

#include "../netns.h"

static const struct rpc_authops authgss_ops;

static const struct rpc_credops gss_credops;
Expand Down Expand Up @@ -559,21 +561,30 @@ gss_refresh_upcall(struct rpc_task *task)
static inline int
gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
{
struct net *net = rpc_net_ns(gss_auth->client);
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
struct rpc_pipe *pipe;
struct rpc_cred *cred = &gss_cred->gc_base;
struct gss_upcall_msg *gss_msg;
unsigned long timeout;
DEFINE_WAIT(wait);
int err;

dprintk("RPC: %s for uid %u\n",
__func__, from_kuid(&init_user_ns, cred->cr_uid));
retry:
err = 0;
/* Default timeout is 15s unless we know that gssd is not running */
timeout = 15 * HZ;
if (!sn->gssd_running)
timeout = HZ >> 2;
gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
if (PTR_ERR(gss_msg) == -EAGAIN) {
err = wait_event_interruptible_timeout(pipe_version_waitqueue,
pipe_version >= 0, 15*HZ);
pipe_version >= 0, timeout);
if (pipe_version < 0) {
if (err == 0)
sn->gssd_running = 0;
warn_gssd();
err = -EACCES;
}
Expand Down
2 changes: 2 additions & 0 deletions net/sunrpc/netns.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ struct sunrpc_net {
struct rpc_clnt *gssp_clnt;
int use_gss_proxy;
struct proc_dir_entry *use_gssp_proc;

unsigned int gssd_running;
};

extern int sunrpc_net_id;
Expand Down
4 changes: 4 additions & 0 deletions net/sunrpc/rpc_pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,14 @@ rpc_destroy_inode(struct inode *inode)
static int
rpc_pipe_open(struct inode *inode, struct file *filp)
{
struct net *net = inode->i_sb->s_fs_info;
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
struct rpc_pipe *pipe;
int first_open;
int res = -ENXIO;

mutex_lock(&inode->i_mutex);
sn->gssd_running = 1;
pipe = RPC_I(inode)->pipe;
if (pipe == NULL)
goto out;
Expand Down Expand Up @@ -1069,6 +1072,7 @@ void rpc_pipefs_init_net(struct net *net)
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);

mutex_init(&sn->pipefs_sb_lock);
sn->gssd_running = 1;
}

/*
Expand Down

0 comments on commit abfdbd5

Please sign in to comment.