Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -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,
};
};


/*
/*
+3 −1
Original line number Original line Diff line number Diff line
@@ -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. 
+17 −8
Original line number Original line Diff line number Diff line
@@ -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,
		 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,


	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,
					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;
}
}