Subject: mount option timeo - in deciseconds, or seconds?

Hi,

I've been trying to figure out why the nfs.man manpage states

.BI timeo= n
The time in deciseconds (tenths of a second) the NFS client waits for a
response before it retries an NFS request.

Can someone who actually understands NFS enlighten me?
Here's where I'm up to.

I looked in the upstream git.
The 'deciseconds' has been in there since the start of git history
(2007, commit id 16db99b56a532bf56fa27618a6ef30763cd9006f).
But is it (still) correct?

Unfortunately I can't see a direct use of the 'timeo' field
of the NFS data structure so the answer is not easily found.

In utils/mount/nfsmount.c mountnfs() we have

timeout = time(NULL) + 60 * retry;

This sets the upper bound for how long to wait for a mount to succeed.
The units are seconds, because retry is given in minutes.

Also we see

prevt = 0;
t = 30;
val = 1;

these are the control variables for the loop
The main check that prolongs the waiting time is

if (t - prevt < 30)
sleep(30);
....if not mounted yet...
prevt = t;

The decision to time out is made like this
t = time(NULL);
if (t >= timeout) {
rpc_mount_errors(*nfs_server.hostname, 0, bg);
goto fail;
}

so it seems clear that t should also have the units of seconds.
That also matches up with the declaration of t & timeout as time_t.

But I still don't see how data.timo gets used.
utils/mount/network.h defines this

static const struct timeval TIMEOUT = { 20, 0 };
and
#define MOUNT_TIMEOUT (30)

which would seem to be in units of seconds,
since eg. connect_to() uses seconds
which reaches it via the calling path:

1.
CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
{
...
*msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, MOUNT_TIMEOUT,
TRUE, FALSE);

2.
static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
unsigned int timeout, int resvp, int conn)
{
...
cc = connect_to(so, SAFE_SOCKADDR(saddr), namelen,
timeout);
3.
/*
* Attempt to connect a socket, but time out after "timeout" seconds.
*
* On error return, caller closes the socket.
*/
static int connect_to(int fd, struct sockaddr *addr,
socklen_t addrlen, int timeout)
{


Thanks
Vince


2018-12-17 15:11:45

by Chuck Lever III

[permalink] [raw]
Subject: Re: mount option timeo - in deciseconds, or seconds?

Hi Vincent-


> On Dec 14, 2018, at 9:50 PM, Vincent McIntyre <[email protected]> wrote:
>
> Hi,
>
> I've been trying to figure out why the nfs.man manpage states
>
> .BI timeo= n
> The time in deciseconds (tenths of a second) the NFS client waits for a
> response before it retries an NFS request.
>
> Can someone who actually understands NFS enlighten me?
> Here's where I'm up to.
>
> I looked in the upstream git.
> The 'deciseconds' has been in there since the start of git history
> (2007, commit id 16db99b56a532bf56fa27618a6ef30763cd9006f).
> But is it (still) correct?
>
> Unfortunately I can't see a direct use of the 'timeo' field
> of the NFS data structure so the answer is not easily found.

The "timeo" mount option is not used by the mount.nfs command.
It is passed to the kernel, which treats it just as the man
page says.

The code you excerpt below implements the "retry" mount option.

.BI retry= n
The number of minutes that the
.BR mount (8)
command retries an NFS mount operation
in the foreground or background before giving up.
If this option is not specified, the default value for foreground mounts
is 2 minutes, and the default value for background mounts is 10000 minutes
(80 minutes shy of one week).
If a value of zero is specified, the
.BR mount (8)
command exits immediately after the first failure.
.IP
Note that this only affects how many retries are made and doesn't
affect the delay caused by each retry. For UDP each retry takes the
time determined by the
.BR timeo
and
.BR retrans
options, which by default will be about 7 seconds. For TCP the
default is 3 minutes, but system TCP connection timeouts will
sometimes limit the timeout of each retransmission to around 2 minutes.


> In utils/mount/nfsmount.c mountnfs() we have
>
> timeout = time(NULL) + 60 * retry;
>
> This sets the upper bound for how long to wait for a mount to succeed.
> The units are seconds, because retry is given in minutes.
>
> Also we see
>
> prevt = 0;
> t = 30;
> val = 1;
>
> these are the control variables for the loop
> The main check that prolongs the waiting time is
>
> if (t - prevt < 30)
> sleep(30);
> ....if not mounted yet...
> prevt = t;
>
> The decision to time out is made like this
> t = time(NULL);
> if (t >= timeout) {
> rpc_mount_errors(*nfs_server.hostname, 0, bg);
> goto fail;
> }
>
> so it seems clear that t should also have the units of seconds.
> That also matches up with the declaration of t & timeout as time_t.
>
> But I still don't see how data.timo gets used.
> utils/mount/network.h defines this
>
> static const struct timeval TIMEOUT = { 20, 0 };
> and
> #define MOUNT_TIMEOUT (30)
>
> which would seem to be in units of seconds,
> since eg. connect_to() uses seconds
> which reaches it via the calling path:
>
> 1.
> CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
> {
> ...
> *msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, MOUNT_TIMEOUT,
> TRUE, FALSE);
>
> 2.
> static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
> unsigned int timeout, int resvp, int conn)
> {
> ...
> cc = connect_to(so, SAFE_SOCKADDR(saddr), namelen,
> timeout);
> 3.
> /*
> * Attempt to connect a socket, but time out after "timeout" seconds.
> *
> * On error return, caller closes the socket.
> */
> static int connect_to(int fd, struct sockaddr *addr,
> socklen_t addrlen, int timeout)
> {
>
>
> Thanks
> Vince

--
Chuck Lever




Subject: Re: mount option timeo - in deciseconds, or seconds?

On Mon, Dec 17, 2018 at 10:11:34AM -0500, Chuck Lever wrote:
> Hi Vincent-
>
>
> > On Dec 14, 2018, at 9:50 PM, Vincent McIntyre <[email protected]> wrote:
> >
> > Hi,
> >
> > I've been trying to figure out why the nfs.man manpage states
> >
> > .BI timeo= n
> > The time in deciseconds (tenths of a second) the NFS client waits for a
> > response before it retries an NFS request.
> >
> > Can someone who actually understands NFS enlighten me?
> > Here's where I'm up to.
> >
> > I looked in the upstream git.
> > The 'deciseconds' has been in there since the start of git history
> > (2007, commit id 16db99b56a532bf56fa27618a6ef30763cd9006f).
> > But is it (still) correct?
> >
> > Unfortunately I can't see a direct use of the 'timeo' field
> > of the NFS data structure so the answer is not easily found.
>
> The "timeo" mount option is not used by the mount.nfs command.
> It is passed to the kernel, which treats it just as the man
> page says.

Thanks Chuck.
I did eventually figure this out but forgot to follow up here.

> The code you excerpt below implements the "retry" mount option.
>

doh. Thanks for pointing that out.

Kind regards
Vince