Skip to content

Commit

Permalink
SUNRPC/NFSD: Support a new option for ignoring the result of svc_regi…
Browse files Browse the repository at this point in the history
…ster

NFSv4 clients can contact port 2049 directly instead of needing the
portmapper.

Therefore a failure to register to the portmapper when starting an
NFSv4-only server isn't really a problem.

But Gareth Williams reports that an attempt to start an NFSv4-only
server without starting portmap fails:

  #rpc.nfsd -N 2 -N 3
  rpc.nfsd: writing fd to kernel failed: errno 111 (Connection refused)
  rpc.nfsd: unable to set any sockets for nfsd

Add a flag to svc_version to tell the rpc layer it can safely ignore an
rpcbind failure in the NFSv4-only case.

Reported-by: Gareth Williams <gareth@garethwilliams.me.uk>
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
  • Loading branch information
kinglongmee authored and J. Bruce Fields committed Jan 3, 2014
1 parent 8a89163 commit 7e55b59
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
1 change: 1 addition & 0 deletions fs/nfsd/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1882,6 +1882,7 @@ struct svc_version nfsd_version4 = {
.vs_proc = nfsd_procedures4,
.vs_dispatch = nfsd_dispatch,
.vs_xdrsize = NFS4_SVC_XDRSIZE,
.vs_rpcb_optnl = 1,
};

/*
Expand Down
4 changes: 3 additions & 1 deletion include/linux/sunrpc/svc.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,10 @@ struct svc_version {
struct svc_procedure * vs_proc; /* per-procedure info */
u32 vs_xdrsize; /* xdrsize needed for this version */

unsigned int vs_hidden : 1; /* Don't register with portmapper.
unsigned int vs_hidden : 1, /* Don't register with portmapper.
* Only used for nfsacl so far. */
vs_rpcb_optnl:1;/* Don't care the result of register.
* Only used for nfsv4. */

/* Override dispatch function (e.g. when caching replies).
* A return value of 0 means drop the request.
Expand Down
25 changes: 17 additions & 8 deletions net/sunrpc/svc.c
Original file line number Diff line number Diff line change
Expand Up @@ -916,9 +916,6 @@ static int __svc_register(struct net *net, const char *progname,
#endif
}

if (error < 0)
printk(KERN_WARNING "svc: failed to register %sv%u RPC "
"service (errno %d).\n", progname, version, -error);
return error;
}

Expand All @@ -937,6 +934,7 @@ int svc_register(const struct svc_serv *serv, struct net *net,
const unsigned short port)
{
struct svc_program *progp;
struct svc_version *vers;
unsigned int i;
int error = 0;

Expand All @@ -946,7 +944,8 @@ int svc_register(const struct svc_serv *serv, struct net *net,

for (progp = serv->sv_program; progp; progp = progp->pg_next) {
for (i = 0; i < progp->pg_nvers; i++) {
if (progp->pg_vers[i] == NULL)
vers = progp->pg_vers[i];
if (vers == NULL)
continue;

dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n",
Expand All @@ -955,16 +954,26 @@ int svc_register(const struct svc_serv *serv, struct net *net,
proto == IPPROTO_UDP? "udp" : "tcp",
port,
family,
progp->pg_vers[i]->vs_hidden?
" (but not telling portmap)" : "");
vers->vs_hidden ?
" (but not telling portmap)" : "");

if (progp->pg_vers[i]->vs_hidden)
if (vers->vs_hidden)
continue;

error = __svc_register(net, progp->pg_name, progp->pg_prog,
i, family, proto, port);
if (error < 0)

if (vers->vs_rpcb_optnl) {
error = 0;
continue;
}

if (error < 0) {
printk(KERN_WARNING "svc: failed to register "
"%sv%u RPC service (errno %d).\n",
progp->pg_name, i, -error);
break;
}
}
}

Expand Down

0 comments on commit 7e55b59

Please sign in to comment.