Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Jul 2017 22:19:52 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        John Baldwin <jhb@freebsd.org>
Cc:        Ian Lepore <ian@freebsd.org>, Edward Tomasz Napierala <trasz@freebsd.org>,  rgrimes@freebsd.org, src-committers@freebsd.org, svn-src-all@freebsd.org,  svn-src-head@freebsd.org
Subject:   Re: svn commit: r320803 - head/sbin/mount
Message-ID:  <20170712200850.T1271@besplex.bde.org>
In-Reply-To: <5242112.0aHCQARnit@ralph.baldwin.cx>
References:  <20170708171641.GA1129@brick> <20170711201230.GB1725@brick> <1499805315.45330.14.camel@freebsd.org> <5242112.0aHCQARnit@ralph.baldwin.cx>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 11 Jul 2017, John Baldwin wrote:

> On Tuesday, July 11, 2017 02:35:15 PM Ian Lepore wrote:
>> I think the docs on this are pretty clear... under -u it says:
>>
>>     The set of options is determined by applying the options specified
>>     in the argument to -o and finally applying the -r or -w option.
>>
>> To me, that says that nothing in /etc/fstab is germane to mount -u
>> unless one of the other args to mount -u is -o fstab.
>>
>> This change (r320803) seems like an acceptable workaround, but I think
>> the correct long term fix would be to not even open /etc/fstab on mount
>> -u without -o fstab.  But that may be harder to do than to say; I still
>> haven't actually looked at the code involved.

I thought that it did do that (not look in fstab, except possibly for
pathnames).

> I concur with this.  I've always viewed '-u' as meaning "apply a delta
> to the current configuration", not "add this delta to the fstab options
> and then apply that entire set of options".   In practice, it seems that
> it doesn't do either of those, but instead it seems to treats the options
> passed to -o as the entire list of options.  This is perhaps a bit
> surprising.

I thought that everyone knew that the behaviour is to blow away the current
options, since this is surprisingly bad.  My fingers know this, and exploit
it to reduce typing for mounting the root file system rw:
- "rw" is not an option, but is the absense of the "ro" option, so to change
   the root file system from read-only to read-write, my fingers type
   "mount /" -- this blows away "ro"
- however, all my fs's are mounted with noatime and I don't want to blow this
   away unintentionally.  My fingers know this, so they actually type
   "mount -o noatime" for the previous operation.

This is part of a large suite of design and implementation bugs.  dwmalone@
added [-u -o] "fstab" and "current" options to give more control and save
typing, but these weren't complete and they rotted with the larger design
and implementation bug nmount(2).  "current" only gives the current
settings that are in the mount flags returned by statfs(2), and "fstab"
doesn't blow away the current settings that aren't in the mount flags.
nmount(2) increased the problem by making it too easy to add unstructured
options that are not in the mount flags and moving parsing of options to
the kernel.

mount(8) with no args only displays the options in the mount flags.


> For example, suppose you had this:
>
> /etc/fstab:
>
> /dev/md0        /bar            ufs     ro,noauto,noexec        0       0
>
> # mount /bar
> # mount | grep bar
ooooooop
> /dev/md0 on /bar (ufs, local, noexec, read-only)
> # mount -u -o rw /bar
> /dev/md0 on /bar (ufs, local)
>
> (We just lost "noexec" from fstab by upgrading to read-write)

Expect to lose that are in the mount flags like this.

But unstructured options tend to be sticky due to undocumented
implementation details.  This causes my most problems with nfs tcp/udp
flags and nfs read/write sizes.  Even when these were parsed in
nfs_mount(8), IIRC the absence of an option in the command line was
passed to the kernel as nothing and interpreted by the kernel as
a null change.  With nmount(2), userland does almost no option
processing so more clearly passes absent options as nothing so the
result is whatever undocumented interpretation the kernel prefers.
For read/write sizes, nfs also "fixes" wrong sizes by adjusting to
limits.  There is API for determining what sizes its ends up with,
so the only way to know what sizes you are setting is to always
set sizes that won't be adjusted and remember what these are in
userland.

> # mount -u -o nosuid /bar
> # mount | grep bar
> /dev/md0 on /bar (ufs, local, nosuid)
>
> (Did not lose "read-write" somehow, RO vs RW must be magically sticky?)

RW is just the default.  It is not a flag, but the absense of the "ro"
flag.

nmount(2) still handles negative options worse than mount(8) using much
much larger code, but after many years of fixes it handles this "rw"
negative option well enough.  Most generic flags have 3 variants like
"ro", "noro" and "nonoro", and "ro" also has variants "" "rw".
Non-generic flags (implemented in individual file systems) tend to
have less orthogonality.  Sometimes if the basic flag is "nofoo", there
is no flag "foo".  Sometimes there is a flag "nonofoo" to negate "foo".

> # mount -u -o fstab,nosuid /bar
> # mount |grep bar
> /dev/md0 on /bar (ufs, local, noexec, nosuid)
>
> (Did not honor "ro" from fstab!  Left mount RW)

Correction: after many years of fixes, nmount(2) still doesn't understand
the "ro" flag.  This example works correctly with old mount utilities
using mount(2).  This is with the same current kernel -- mount(8) from
FreeBSD-~5.2 parses the options correctly and then uses mount(2), while
mount(8) from FreeBSD-10 uses nmount(2).  Even nmount(2) can handle this,
so the bug must be in parsing or concatenating fstab options.  "fstab"
seems to work correctly with newer mount(8) for options in fstab except
"ro".

> It would seem that there is no actual rhyme or reason to how mount -u works,
> and certainly Edward's change doesn't make it worse.  I would like to have
> some kind of mode where you can toggle one or more options without disturbing
> others.  Maybe if we had a new "special" option called "current" or some such
> that is like "fstab" but instead represents the options currently in force,
> then you could do true delta operations via 'mount -o current,rw -u /foo'.
> As it is, there doesn't currently seem to a reliable way to achieve that
> functionality.

-u -o current was implemented in 1999, but never really worked.  To
summarize, -u tends to preserve the current settings for everything
except the mount flags that you can actually see, and should change
all of those flags to 0.  So -u -o -current tends to preserve everything.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20170712200850.T1271>