Discussion:
RequiresMountsFor and the noauto option.
(too old to reply)
NeilBrown
2017-01-23 00:13:52 UTC
Permalink
Raw Message
hi,
according to "man systemd.unit" :

RequiresMountsFor=
Takes a space-separated list of absolute paths.
Automatically adds dependencies of type Requires= and
After= for all mount units required to access the
specified path.

Mount points marked with noauto are not mounted
automatically and will be ignored for the purposes of
this option. If such a mount should be a requirement for
this unit, direct dependencies on the mount units may be
added (Requires= and After= or some other combination).


I understand this to mean that if a mount point has the "noauto" option in
/etc/fstab, and if a systemd service has RequiresMountsFor the path to
that mount point, then the service will *not* require the mount point,
and it will start even if that mountpoint cannot be mounted.

I recently made a change to nfs-utils to make use of this
functionality. A generator creates RequiresMountsFor dependences for
nfs-server so that it won't start until all exported filesystems
(listed in /etc/exports) are mounted. I assumed this would not trigger
the mounting of filesystems marked as "noauto". I really want After
functionality, but not Requires.

However, this is not how it works.

The "noauto" option stops a "Requires" dependency being created for
local-fs.target, but does not stop a "Requires" dependency being
created for a service which "RequiresMountsFor". There is no checking
for "noauto" in unit_add_mount_dependencies().

If this a bug in the documentation, or a bug in the code? I'm hoping
the later, otherwise I'll need to find a different solution for
nfs-utils, and that will probably require having my generator read
/etc/fstab and duplicate the work of fstab-generator.c

If the documentation is wrong, and the code is correct, would it be
possible to get "AfterMountsFor=" as that is the functionality that I
really want.

Thanks,
NeilBrown
Andrei Borzenkov
2017-01-23 04:10:06 UTC
Permalink
Raw Message
This was discussed just recently as regression in Leap 42.2 on opensuse
mailing list ...
Post by NeilBrown
hi,
RequiresMountsFor=
Takes a space-separated list of absolute paths.
Automatically adds dependencies of type Requires= and
After= for all mount units required to access the
specified path.
Mount points marked with noauto are not mounted
automatically and will be ignored for the purposes of
this option. If such a mount should be a requirement for
this unit, direct dependencies on the mount units may be
added (Requires= and After= or some other combination).
I understand this to mean that if a mount point has the "noauto" option in
/etc/fstab, and if a systemd service has RequiresMountsFor the path to
that mount point, then the service will *not* require the mount point,
and it will start even if that mountpoint cannot be mounted.
I recently made a change to nfs-utils to make use of this
functionality. A generator creates RequiresMountsFor dependences for
nfs-server so that it won't start until all exported filesystems
(listed in /etc/exports) are mounted. I assumed this would not trigger
the mounting of filesystems marked as "noauto". I really want After
functionality, but not Requires.
However, this is not how it works.
The "noauto" option stops a "Requires" dependency being created for
local-fs.target, but does not stop a "Requires" dependency being
created for a service which "RequiresMountsFor". There is no checking
for "noauto" in unit_add_mount_dependencies().
If this a bug in the documentation, or a bug in the code? I'm hoping
Well ... I do not see any special handling for noauto in original commit
that added this option (7c8fa05c4d5d01748ff2a04edb882afb3119b7d7). Nor
do I see even theoretical possibility to handle it, because "noauto"
just means "mount unit is not dependency of local-fs.target".

What I suspect happened was

- original patch depends on mount unit being present in systemd cache
- due to aggressive garbage collection mount units without "auto" were
displaced from cache early. So those units were not visible at the time
dependency was checked
- later c7c89abb9edf9320246482bf4a8e0656199281ae made systemd to always
(try to) load all possible mount units for prefix

Long story short - this is documentation bug (added
5d2abc04fc95f5c5f6d0eaf2f9b06c70d504019f by mistake). This option always
was designed to *Require* other mount unit.
Post by NeilBrown
the later, otherwise I'll need to find a different solution for
nfs-utils, and that will probably require having my generator read
/etc/fstab and duplicate the work of fstab-generator.c
If the documentation is wrong, and the code is correct, would it be
possible to get "AfterMountsFor=" as that is the functionality that I
really want.
That's rather interesting question. As discussed in the thread I
mentioned, user has /foo/bar in /etc/exports. So the question now is -
what is semantic if /foo/bar is not mounted? nfsd server starts and
export /foo/bar *mount point*, right? But that feels just as wrong, does
not it?

I.e. if some unit refers to path /foo/bar and we *know* that /foo/bar is
on filesystem /foo - should we skip mounting filesystem? Then we risk
unit misbehavior, because it will miss some data in /foo/bar, right?
NeilBrown
2017-01-23 05:18:09 UTC
Permalink
Raw Message
Post by Andrei Borzenkov
This was discussed just recently as regression in Leap 42.2 on opensuse
mailing list ...
Post by NeilBrown
hi,
RequiresMountsFor=
Takes a space-separated list of absolute paths.
Automatically adds dependencies of type Requires= and
After= for all mount units required to access the
specified path.
Mount points marked with noauto are not mounted
automatically and will be ignored for the purposes of
this option. If such a mount should be a requirement for
this unit, direct dependencies on the mount units may be
added (Requires= and After= or some other combination).
I understand this to mean that if a mount point has the "noauto" option in
/etc/fstab, and if a systemd service has RequiresMountsFor the path to
that mount point, then the service will *not* require the mount point,
and it will start even if that mountpoint cannot be mounted.
I recently made a change to nfs-utils to make use of this
functionality. A generator creates RequiresMountsFor dependences for
nfs-server so that it won't start until all exported filesystems
(listed in /etc/exports) are mounted. I assumed this would not trigger
the mounting of filesystems marked as "noauto". I really want After
functionality, but not Requires.
However, this is not how it works.
The "noauto" option stops a "Requires" dependency being created for
local-fs.target, but does not stop a "Requires" dependency being
created for a service which "RequiresMountsFor". There is no checking
for "noauto" in unit_add_mount_dependencies().
If this a bug in the documentation, or a bug in the code? I'm hoping
Well ... I do not see any special handling for noauto in original commit
that added this option (7c8fa05c4d5d01748ff2a04edb882afb3119b7d7). Nor
do I see even theoretical possibility to handle it, because "noauto"
just means "mount unit is not dependency of local-fs.target".
I could Theoretically be handled by having any unit with declares
"RequiresMountsFor" getting either "Requires local-fs.target" or
"Requires remote-fs.target" instead of the current "Requires foo.mount",
depending on whether the "foo.mount" is a 'net'
filesystem.... presumably that can be measured.
The "After foo.mount" dependency would remain.

Maybe a bit clumsy, but I think it could "theoretically" be made to work"
Post by Andrei Borzenkov
What I suspect happened was
- original patch depends on mount unit being present in systemd cache
- due to aggressive garbage collection mount units without "auto" were
displaced from cache early. So those units were not visible at the time
dependency was checked
- later c7c89abb9edf9320246482bf4a8e0656199281ae made systemd to always
(try to) load all possible mount units for prefix
Long story short - this is documentation bug (added
5d2abc04fc95f5c5f6d0eaf2f9b06c70d504019f by mistake). This option always
was designed to *Require* other mount unit.
I agree that the name "Requires" seemed to be inconsistent with the
behaviour described, but it seems more strange that the behaviour with
respect to "noauto" would be explicity described if it was not
intentional.

.... ah-ha. The documentation was change by commit
Commit: 5d2abc04fc95 ("man: document relationship between RequiresMountsFor and noauto")

in response to https://bugzilla.redhat.com/show_bug.cgi?id=1088057

So it was really documenting behaviour, not intention. ????
I should systemd promised some sort of stable API thing.....
Post by Andrei Borzenkov
Post by NeilBrown
the later, otherwise I'll need to find a different solution for
nfs-utils, and that will probably require having my generator read
/etc/fstab and duplicate the work of fstab-generator.c
If the documentation is wrong, and the code is correct, would it be
possible to get "AfterMountsFor=" as that is the functionality that I
really want.
That's rather interesting question. As discussed in the thread I
mentioned, user has /foo/bar in /etc/exports. So the question now is -
what is semantic if /foo/bar is not mounted? nfsd server starts and
export /foo/bar *mount point*, right? But that feels just as wrong, does
not it?
It depends.
If the directory being exported is a subdirectory of the mountpoint,
then there will be no directory to export and the client will see ESTALE
or ENOENT (depending on exact sequence of events). This is correct.

/etc/exports has a 'mountpoint' option which causes an entry to be
ignored if it is not, in fact, a mountpoint. This works well for NFSv3
but is a bit awkward for NFSv4 (I don't recall exactly why).
Setting "mountpoint" on exports of filesystems which are "noauto" will
avoid most of the strange behaviour that you fear.

I could change the nfs-server generator to only RequiresMountsFor export
points that do not have the "mountpoint" option. I considered that at
the time, but didn't because the systemd documentation told me I didn't
need to. :-(

Back to the drawing-board I guess .... but I'd really like to see the
documentation for systemd.unit reverted before I commit a change to
nfs-utils.

Thanks,
NeilBrown
Post by Andrei Borzenkov
I.e. if some unit refers to path /foo/bar and we *know* that /foo/bar is
on filesystem /foo - should we skip mounting filesystem? Then we risk
unit misbehavior, because it will miss some data in /foo/bar, right?
Lennart Poettering
2017-02-06 20:38:13 UTC
Permalink
Raw Message
Post by NeilBrown
hi,
RequiresMountsFor=
Takes a space-separated list of absolute paths.
Automatically adds dependencies of type Requires= and
After= for all mount units required to access the
specified path.
Mount points marked with noauto are not mounted
automatically and will be ignored for the purposes of
this option. If such a mount should be a requirement for
this unit, direct dependencies on the mount units may be
added (Requires= and After= or some other combination).
Hmm, this is weird. This is actually not what happens. The
documentaiton is simply not correct here. That's a bug we need to
fix. I filed a bug about this now:

https://github.com/systemd/systemd/issues/5249

What actually happens is that RMF= adds After= for all prefix mount
units, but Requires= only to those which have a fragment file
(i.e. are explicitly configured). The "noauto" flag is not checked.

Sorry for the confusion.
Post by NeilBrown
If the documentation is wrong, and the code is correct, would it be
possible to get "AfterMountsFor=" as that is the functionality that I
really want.
I figure we could add that. Please file an RFE on github.

Lennart
--
Lennart Poettering, Red Hat
Loading...