Commit 7e55b59b authored by Kinglong Mee's avatar Kinglong Mee Committed by J. Bruce Fields

SUNRPC/NFSD: Support a new option for ignoring the result of svc_register

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: default avatarGareth Williams <gareth@garethwilliams.me.uk>
Reviewed-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarKinglong Mee <kinglongmee@gmail.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 8a891633
...@@ -1882,6 +1882,7 @@ struct svc_version nfsd_version4 = { ...@@ -1882,6 +1882,7 @@ struct svc_version nfsd_version4 = {
.vs_proc = nfsd_procedures4, .vs_proc = nfsd_procedures4,
.vs_dispatch = nfsd_dispatch, .vs_dispatch = nfsd_dispatch,
.vs_xdrsize = NFS4_SVC_XDRSIZE, .vs_xdrsize = NFS4_SVC_XDRSIZE,
.vs_rpcb_optnl = 1,
}; };
/* /*
......
...@@ -386,8 +386,10 @@ struct svc_version { ...@@ -386,8 +386,10 @@ struct svc_version {
struct svc_procedure * vs_proc; /* per-procedure info */ struct svc_procedure * vs_proc; /* per-procedure info */
u32 vs_xdrsize; /* xdrsize needed for this version */ 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. */ * 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). /* Override dispatch function (e.g. when caching replies).
* A return value of 0 means drop the request. * A return value of 0 means drop the request.
......
...@@ -916,9 +916,6 @@ static int __svc_register(struct net *net, const char *progname, ...@@ -916,9 +916,6 @@ static int __svc_register(struct net *net, const char *progname,
#endif #endif
} }
if (error < 0)
printk(KERN_WARNING "svc: failed to register %sv%u RPC "
"service (errno %d).\n", progname, version, -error);
return error; return error;
} }
...@@ -937,6 +934,7 @@ int svc_register(const struct svc_serv *serv, struct net *net, ...@@ -937,6 +934,7 @@ int svc_register(const struct svc_serv *serv, struct net *net,
const unsigned short port) const unsigned short port)
{ {
struct svc_program *progp; struct svc_program *progp;
struct svc_version *vers;
unsigned int i; unsigned int i;
int error = 0; int error = 0;
...@@ -946,7 +944,8 @@ int svc_register(const struct svc_serv *serv, struct net *net, ...@@ -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 (progp = serv->sv_program; progp; progp = progp->pg_next) {
for (i = 0; i < progp->pg_nvers; i++) { for (i = 0; i < progp->pg_nvers; i++) {
if (progp->pg_vers[i] == NULL) vers = progp->pg_vers[i];
if (vers == NULL)
continue; continue;
dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n", dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n",
...@@ -955,18 +954,28 @@ int svc_register(const struct svc_serv *serv, struct net *net, ...@@ -955,18 +954,28 @@ int svc_register(const struct svc_serv *serv, struct net *net,
proto == IPPROTO_UDP? "udp" : "tcp", proto == IPPROTO_UDP? "udp" : "tcp",
port, port,
family, family,
progp->pg_vers[i]->vs_hidden? vers->vs_hidden ?
" (but not telling portmap)" : ""); " (but not telling portmap)" : "");
if (progp->pg_vers[i]->vs_hidden) if (vers->vs_hidden)
continue; continue;
error = __svc_register(net, progp->pg_name, progp->pg_prog, error = __svc_register(net, progp->pg_name, progp->pg_prog,
i, family, proto, port); 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; break;
} }
} }
}
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment