[LTP] [RFC] rpcbind: detect support of remote calls

Steve Dickson steved@redhat.com
Wed Jun 4 22:05:46 CEST 2025



On 6/4/25 3:42 PM, Petr Vorel wrote:
> Hi Steve,
> 
>> Hey!
> 
>> On 6/2/25 9:37 AM, Petr Vorel wrote:
>>> Hi Steve,
> 
>>> Ricardo found that TI-RPC rpc_pmap_rmtcall [1] tirpc_rpcb_rmtcall [2] tests are
>>> failing when they use rpcbind *without* --enable-rmtcalls (the default since
>>> 2018, see 2e9c289 ("rpcbind: Disable remote calls by default") [3]).
> 
>>> TL;DR: Is there a way to detect missing support from rpcbind? Because we cannot
>>> blindly expect that timeout means disabled remote calls (it could be also
>>> caused by regression). Other option is just to disable these tests by default
>>> (detection is preferred).
>> No there is not a way, that I know of, to see if remote calls
>> are or are not enabled since it is a compile time flag.
> 
> How about rpcbind to print version via new -v or -V command line option.
> Then compiled options could be printed as part of the output.
That is not a bad idea... It could be a bit messy since they're
close to 20 different ifdefs...

> 
> Nobody needed to know rpcbind version, therefore I'm not sure if testing justify
> it, but that would be an easy way to provide the info.
No testing would be needed... as long as rpcbind does not
drop core with the -v option :-) also there would be a
manpage up date... but it would not be very invasive.

> 
>> I really don't know what to say... In Fedora we disabled rmtcalls
>> which broke NIS and in RHEL we left it enable which drives
>> SELinux (and a few customers) nuts.
> 
> Thanks for info, I fully understand the chosen solution.
I wish other people would!!! 8-)

steved.

> 
> Kind regards,
> Petr
> 
>> There is no clear answer... IMHO.
> 
>> steved.
> 
> 
> 
>>> # export PATH="/opt/ltp/testcases/bin:$PATH"
>>> # rpc_test.sh -s tirpc_svc_4 -c tirpc_rpcb_rmtcall
>>> ...
>>> tirpc_rpcb_rmtcall 10.0.0.2 536875000
>>> rpc_test 1 TFAIL: tirpc_rpcb_rmtcall 10.0.0.2 536875000 failed unexpectedly
> 
>>> As the name of the test suggests they are using pmap_rmtcall() and rpcb_rmtcall().
>>> A bit debug info.
> 
>>> Modified rpc_test.sh to use strace:
> 
>>> +++ b/testcases/network/rpc/rpc-tirpc/rpc_test.sh
>>> @@ -87,6 +87,8 @@ do_test()
>>>    		done
>>>    	fi
>>> +	echo "$CLIENT $(tst_ipaddr) $PROGNUMNOSVC $CLIENT_EXTRA_OPTS" # FIXME: debug
>>> +	EXPECT_RHOST_PASS strace -o /tmp/a $CLIENT $(tst_ipaddr) $PROGNUMNOSVC $CLIENT_EXTRA_OPTS
>>>    	EXPECT_RHOST_PASS $CLIENT $(tst_ipaddr) $PROGNUMNOSVC $CLIENT_EXTRA_OPTS
>>>    }
> 
>>> I see the test timeouts (full strace output below):
> 
>>> # rpc_test.sh -s tirpc_svc_4 -c tirpc_rpcb_rmtcall
>>> ...
>>> sendto(5, "h=\r}\0\0\0\0\0\0\0\2\0\1\206\240\0\0\0\4\0\0\0\5\0\0\0\0\0\0\0\0"..., 60, 0, {sa_family=AF_INET, sin_port=htons(111), sin_addr=inet_addr("10.0.0.2")}, 16) = 60
>>> poll([{fd=5, events=POLLIN}], 1, 1000)  = 0 (Timeout)
> 
>>> Using rpcbind 1.2.7-1.2 (from Tumbleweed), output when run with debug mode:
> 
>>> # /usr/sbin/rpcbind -w -f -d
>>> rpcbind: PMAPPROC_DUMP
> 
>>> rpcbind: RPCB_UNSET request for (536875000, 1, ) :
>>> rpcbind: RPCB_UNSET: succeeded
>>> rpcbind: RPCB_SET request for (536875000, 1, udp, 0.0.0.0.223.168) :
>>> rpcbind: RPCB_SET: succeeded
>>> rpcbind: RPCB_GETADDR req for (100000, 2, tcp) from 127.0.0.1.3.98:
>>> mergeaddr: contact uaddr = 127.0.0.1.0.111
>>> addrmerge(caller, 0.0.0.0.0.111, 127.0.0.1.0.111, tcp
>>> addrmerge: hint 127.0.0.1.0.111
>>> addrmerge: returning 127.0.0.1.0.111
>>> mergeaddr: uaddr = 0.0.0.0.0.111, merged uaddr = 127.0.0.1.0.111
>>> rpcbind: getaddr: 127.0.0.1.0.111
>>> rpcbind: PMAPPROC_DUMP
> 
>>> rpcbind: RPCB_GETADDR req for (536875000, 1, udp) from 10.0.0.1.3.105:
>>> mergeaddr: contact uaddr = 10.0.0.2.0.111
>>> addrmerge(caller, 0.0.0.0.223.168, 10.0.0.2.0.111, udp
>>> addrmerge: hint 10.0.0.2.0.111
>>> addrmerge: returning 10.0.0.2.223.168
>>> mergeaddr: uaddr = 0.0.0.0.223.168, merged uaddr = 10.0.0.2.223.168
>>> rpcbind: getaddr: 10.0.0.2.223.168
>>> rpcbind: RPCBPROC_BCAST
> 
>>> rpcbind: rpcb_indirect callit req for (536875000, 1, 1, udp) from 10.0.0.1.3.105 :
>>> rpcbind: found at uaddr 0.0.0.0.223.168
> 
>>> addrmerge(caller, 0.0.0.0.223.168, NULL, udp
>>> addrmerge: hint 127.0.0.1.0.111
>>> addrmerge: returning 127.0.0.1.223.168
>>> addrmerge(caller, 0.0.0.0.223.168, NULL, udp
>>> addrmerge: hint 10.0.0.1.3.105
>>> addrmerge: returning 192.168.122.43.223.168
>>> rpcbind: merged uaddr 192.168.122.43.223.168
> 
>>> rpcbind: RPCB_UNSET request for (536875000, 1, ) :
>>> rpcbind: Suppression RPC_UNSET(map_unset)
>>> rpcbind: rbl->rpcb_map.r_owner=superuser
>>> rpcbind: owner=superuser
>>> rpcbind: RPCB_UNSET: succeeded
> 
>>> Obviously, if I compile rpcbind with --enable-rmtcalls and run it, both tests work:
> 
>>> $ ./autogen.sh && ./configure --enable-debug --enable-warmstarts --enable-rmtcalls --with-rpcuser=rpc --with-nss-modules="files usrfiles"
>>> $ make -j`nproc`
>>> # ./rpcbind -w -d -f
> 
>>> # rpc_test.sh -s tirpc_svc_4 -c tirpc_rpcb_rmtcall
>>> ...
>>> rpc_test 1 TINFO: using libtirpc: yes
>>> tirpc_rpcb_rmtcall 10.0.0.2 536875000
>>> rpc_test 1 TPASS: tirpc_rpcb_rmtcall 10.0.0.2 536875000 passed as expected
> 
>>> # rpc_test.sh -s rpc_svc_1 -c rpc_pmap_rmtcall
>>> ...
>>> rpc_pmap_rmtcall 10.0.0.2 536875000
>>> rpc_test 1 TPASS: rpc_pmap_rmtcall 10.0.0.2 536875000 passed as expected
> 
> 
>>> And the rpcbind outpt contains also:
> 
>>> rpcbind: rpcbproc_callit_com:  original XID 683f1705, new XID f68e200
>>> rpcbind: my_svc_run:  polled on forwarding fd 7, netid udp - calling handle_reply
> 
>>> Also, wouldn't it be worth mention --enable-rmtcalls in functions' man pages?
>>> (Or have I overlooked that in man?)
> 
>>> Thanks for any hint.
> 
>>> Kind regards,
>>> Petr
> 
>>> [1] https://github.com/linux-test-project/ltp/tree/master/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/rpc/rpc_addrmanagmt_pmap_rmtcall/rpc_pmap_rmtcall.c
>>> [2] https://github.com/linux-test-project/ltp/tree/master/testcases/network/rpc/rpc-tirpc/tests_pack/rpc_suite/tirpc/tirpc_expertlevel_rpcb_rmtcall/tirpc_rpcb_rmtcall.c
>>> [3] https://git.linux-nfs.org/?p=steved/rpcbind.git;a=commitdiff;h=2e9c289246c647e25649914bdb0d9400c66f486e
> 
>>> Full strace on rpcbind compiled without --enable-rmtcalls (the default, thus
>>> how it's shipped to the new distros):
> 
>>> # rpc_test.sh -s tirpc_svc_4 -c tirpc_rpcb_rmtcall
> 
>>> execve("/opt/ltp/testcases/bin/tirpc_rpcb_rmtcall", ["tirpc_rpcb_rmtcall", "10.0.0.2", "536875000"], 0x7ffee8701b10 /* 228 vars */) = 0
>>> ...
>>> openat(AT_FDCWD, "/etc/services", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
>>> openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 5
>>> ...
>>> openat(AT_FDCWD, "/usr/etc/services", O_RDONLY|O_CLOEXEC) = 5
>>> fstat(5, {st_mode=S_IFREG|0644, st_size=868338, ...}) = 0
>>> read(5, "#\n# Network services, Internet s"..., 4096) = 4096
>>> read(5, "[Jon_Postel]\ndaytime            "..., 4096) = 4096
>>> read(5, "gs          44/udp       # MPM F"..., 4096) = 4096
>>> read(5, "emote Job Service \nnetrjs-2     "..., 4096) = 4096
>>> read(5, "Jon_Postel]\nhostname           1"..., 4096) = 4096
>>> close(5)                                = 0
>>> socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) = 5
>>> getsockname(5, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
>>> getsockopt(5, SOL_SOCKET, SO_TYPE, [2], [4]) = 0
>>> openat(AT_FDCWD, "/etc/bindresvport.blacklist", O_RDONLY) = 6
>>> fstat(6, {st_mode=S_IFREG|0644, st_size=415, ...}) = 0
>>> read(6, "#\n# This file contains a list of"..., 4096) = 415
>>> read(6, "", 4096)                       = 0
>>> close(6)                                = 0
>>> getsockname(5, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
>>> getpid()                                = 28530
>>> bind(5, {sa_family=AF_INET, sin_port=htons(722), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
>>> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
>>> rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
>>> getsockname(5, {sa_family=AF_INET, sin_port=htons(722), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
>>> getsockopt(5, SOL_SOCKET, SO_TYPE, [2], [4]) = 0
>>> gettimeofday({tv_sec=1748867467, tv_usec=890549}, NULL) = 0
>>> getpid()                                = 28530
>>> setsockopt(5, SOL_IP, IP_RECVERR, [1], 4) = 0
>>> ioctl(5, FIONBIO, [1])                  = 0
>>> ...
>>> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
>>> sendto(5, "h0`M\0\0\0\0\0\0\0\2\0\1\206\240\0\0\0\4\0\0\0\3\0\0\0\0\0\0\0\0"..., 88, 0, {sa_family=AF_INET, sin_port=htons(111), sin_addr=inet_addr("10.0.0.2")}, 16) = 88
>>> poll([{fd=5, events=POLLIN}], 1, 15000) = 1 ([{fd=5, revents=POLLIN}])
>>> recvfrom(5, "h0`M\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\02010.0"..., 8800, 0, NULL, NULL) = 44
>>> rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
>>> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
>>> rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
>>> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
>>> close(5)                                = 0
>>> rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
>>> socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) = 5
>>> getsockname(5, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
>>> getsockopt(5, SOL_SOCKET, SO_TYPE, [2], [4]) = 0
>>> getsockname(5, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
>>> getpid()                                = 28530
>>> bind(5, {sa_family=AF_INET, sin_port=htons(722), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
>>> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
>>> rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
>>> getsockname(5, {sa_family=AF_INET, sin_port=htons(722), sin_addr=inet_addr("0.0.0.0")}, [128 => 16]) = 0
>>> getsockopt(5, SOL_SOCKET, SO_TYPE, [2], [4]) = 0
>>> gettimeofday({tv_sec=1748867467, tv_usec=892984}, NULL) = 0
>>> getpid()                                = 28530
>>> setsockopt(5, SOL_IP, IP_RECVERR, [1], 4) = 0
>>> ioctl(5, FIONBIO, [1])                  = 0
>>> ...
>>> sendto(5, "h0V\302\0\0\0\0\0\0\0\2\0\1\206\240\0\0\0\4\0\0\0\5\0\0\0\0\0\0\0\0"..., 60, 0, {sa_family=AF_INET, sin_port=htons(111), sin_addr=inet_addr("10.0.0.2")}, 16) = 60
>>> poll([{fd=5, events=POLLIN}], 1, 1000)  = 0 (Timeout)
>>> rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
>>> rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
>>> close(5)                                = 0
>>> rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
>>> fstat(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
>>> write(1, "1\n", 2)                      = 2
>>> exit_group(1)                           = ?
>>> +++ exited with 1 +++
> 
> 



More information about the ltp mailing list