Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 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>

authored by

Kinglong Mee and committed by
J. Bruce Fields
7e55b59b 8a891633

+21 -9
+1
fs/nfsd/nfs4proc.c
··· 1882 1882 .vs_proc = nfsd_procedures4, 1883 1883 .vs_dispatch = nfsd_dispatch, 1884 1884 .vs_xdrsize = NFS4_SVC_XDRSIZE, 1885 + .vs_rpcb_optnl = 1, 1885 1886 }; 1886 1887 1887 1888 /*
+3 -1
include/linux/sunrpc/svc.h
··· 386 386 struct svc_procedure * vs_proc; /* per-procedure info */ 387 387 u32 vs_xdrsize; /* xdrsize needed for this version */ 388 388 389 - unsigned int vs_hidden : 1; /* Don't register with portmapper. 389 + unsigned int vs_hidden : 1, /* Don't register with portmapper. 390 390 * Only used for nfsacl so far. */ 391 + vs_rpcb_optnl:1;/* Don't care the result of register. 392 + * Only used for nfsv4. */ 391 393 392 394 /* Override dispatch function (e.g. when caching replies). 393 395 * A return value of 0 means drop the request.
+17 -8
net/sunrpc/svc.c
··· 916 916 #endif 917 917 } 918 918 919 - if (error < 0) 920 - printk(KERN_WARNING "svc: failed to register %sv%u RPC " 921 - "service (errno %d).\n", progname, version, -error); 922 919 return error; 923 920 } 924 921 ··· 934 937 const unsigned short port) 935 938 { 936 939 struct svc_program *progp; 940 + struct svc_version *vers; 937 941 unsigned int i; 938 942 int error = 0; 939 943 ··· 944 946 945 947 for (progp = serv->sv_program; progp; progp = progp->pg_next) { 946 948 for (i = 0; i < progp->pg_nvers; i++) { 947 - if (progp->pg_vers[i] == NULL) 949 + vers = progp->pg_vers[i]; 950 + if (vers == NULL) 948 951 continue; 949 952 950 953 dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n", ··· 954 955 proto == IPPROTO_UDP? "udp" : "tcp", 955 956 port, 956 957 family, 957 - progp->pg_vers[i]->vs_hidden? 958 - " (but not telling portmap)" : ""); 958 + vers->vs_hidden ? 959 + " (but not telling portmap)" : ""); 959 960 960 - if (progp->pg_vers[i]->vs_hidden) 961 + if (vers->vs_hidden) 961 962 continue; 962 963 963 964 error = __svc_register(net, progp->pg_name, progp->pg_prog, 964 965 i, family, proto, port); 965 - if (error < 0) 966 + 967 + if (vers->vs_rpcb_optnl) { 968 + error = 0; 969 + continue; 970 + } 971 + 972 + if (error < 0) { 973 + printk(KERN_WARNING "svc: failed to register " 974 + "%sv%u RPC service (errno %d).\n", 975 + progp->pg_name, i, -error); 966 976 break; 977 + } 967 978 } 968 979 } 969 980