You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
4.9 KiB
148 lines
4.9 KiB
4 years ago
|
commit 08b7e9988272113ca5640cf5e115ea51449fb392
|
||
|
Author: Ian Kent <ikent@redhat.com>
|
||
|
Date: Mon Sep 2 13:26:14 2019 +0200
|
||
|
|
||
|
Use autofs "ignore" mount hint in getmntent_r/getmntent
|
||
|
|
||
|
Historically autofs mounts were not included in mount table
|
||
|
listings. This is the case in other SysV autofs implementations
|
||
|
and was also the case with Linux autofs.
|
||
|
|
||
|
But now that /etc/mtab is a symlink to the proc filesystem
|
||
|
mount table the autofs mount entries appear in the mount table
|
||
|
on Linux.
|
||
|
|
||
|
Prior to the symlinking of /etc/mtab mount table it was
|
||
|
sufficient to call mount(2) and simply not update /etc/mtab
|
||
|
to exclude autofs mounts from mount listings.
|
||
|
|
||
|
Also, with the symlinking of /etc/mtab we have seen a shift in
|
||
|
usage toward using the proc mount tables directly.
|
||
|
|
||
|
But the autofs mount entries need to be retained when coming
|
||
|
from the proc file system for applications that need them
|
||
|
(largely autofs file system users themselves) so filtering out
|
||
|
these entries within the kernel itself can't be done. So it
|
||
|
needs be done in user space.
|
||
|
|
||
|
There are three reasons to omit the autofs mount entries.
|
||
|
|
||
|
One is that certain types of auto-mounts have an autofs mount
|
||
|
for every entry in their autofs mount map and these maps can
|
||
|
be quite large. This leads to mount table listings containing
|
||
|
a lot of unnecessary entries.
|
||
|
|
||
|
Also, this change in behaviour between autofs implementations
|
||
|
can cause problems for applications that use getmntent(3) in
|
||
|
other OS implementations as well as Linux.
|
||
|
|
||
|
Lastly, there's very little that user space can do with autofs
|
||
|
mount entries since this must be left to the autofs mount owner,
|
||
|
typically the automount daemon. But it can also lead to attempts
|
||
|
to access automount managed paths resulting mounts being triggered
|
||
|
when they aren't needed or mounts staying mounted for much longer
|
||
|
thay they need be. While the point of this change ins't to help
|
||
|
with these problems (and it can be quite a problem) it may be
|
||
|
a welcome side effect.
|
||
|
|
||
|
So the Linux autofs file system has been modified to accept a
|
||
|
pseudo mount option of "ignore" (as is used in other OS
|
||
|
implementations) so that user space can use this as a hint to
|
||
|
skip autofs entries on reading the mount table.
|
||
|
|
||
|
The Linux autofs automount daemon used getmntent(3) itself and
|
||
|
has been modified to use the proc file system directly so that
|
||
|
it can "ignore" mount option.
|
||
|
|
||
|
The use of this mount option is opt-in and a configuration
|
||
|
option has been added which defaults to not use this option
|
||
|
so if there are applications that need these entries, other
|
||
|
than autofs itself, they can be retained. Also, since this
|
||
|
filtering is based on an added mount option earlier versions
|
||
|
of Linux autofs iand other autofs file system users will not
|
||
|
use the option and so won't be affected by the change.
|
||
|
|
||
|
diff -rup a/misc/mntent_r.c b/misc/mntent_r.c
|
||
|
--- a/misc/mntent_r.c 2012-12-24 22:02:13.000000000 -0500
|
||
|
+++ b/misc/mntent_r.c 2020-01-20 15:55:23.417838854 -0500
|
||
|
@@ -18,6 +18,7 @@
|
||
|
|
||
|
#include <alloca.h>
|
||
|
#include <mntent.h>
|
||
|
+#include <stdbool.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdio_ext.h>
|
||
|
#include <string.h>
|
||
|
@@ -112,26 +113,18 @@ decode_name (char *buf)
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
-
|
||
|
-/* Read one mount table entry from STREAM. Returns a pointer to storage
|
||
|
- reused on the next call, or null for EOF or error (use feof/ferror to
|
||
|
- check). */
|
||
|
-struct mntent *
|
||
|
-__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
|
||
|
+static bool
|
||
|
+get_mnt_entry (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
|
||
|
{
|
||
|
char *cp;
|
||
|
char *head;
|
||
|
|
||
|
- flockfile (stream);
|
||
|
do
|
||
|
{
|
||
|
char *end_ptr;
|
||
|
|
||
|
if (fgets_unlocked (buffer, bufsiz, stream) == NULL)
|
||
|
- {
|
||
|
- funlockfile (stream);
|
||
|
- return NULL;
|
||
|
- }
|
||
|
+ return false;
|
||
|
|
||
|
end_ptr = strchr (buffer, '\n');
|
||
|
if (end_ptr != NULL) /* chop newline */
|
||
|
@@ -173,9 +166,40 @@ __getmntent_r (FILE *stream, struct mnte
|
||
|
case 2:
|
||
|
break;
|
||
|
}
|
||
|
+
|
||
|
+ return true;
|
||
|
+}
|
||
|
+
|
||
|
+/* Read one mount table entry from STREAM. Returns a pointer to storage
|
||
|
+ reused on the next call, or null for EOF or error (use feof/ferror to
|
||
|
+ check). */
|
||
|
+struct mntent *
|
||
|
+__getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
|
||
|
+{
|
||
|
+ struct mntent *result;
|
||
|
+
|
||
|
+ flockfile (stream);
|
||
|
+ while (true)
|
||
|
+ if (get_mnt_entry (stream, mp, buffer, bufsiz))
|
||
|
+ {
|
||
|
+ /* If the file system is autofs look for a mount option hint
|
||
|
+ ("ignore") to skip the entry. */
|
||
|
+ if (strcmp (mp->mnt_type, "autofs") == 0 && __hasmntopt (mp, "ignore"))
|
||
|
+ memset (mp, 0, sizeof (*mp));
|
||
|
+ else
|
||
|
+ {
|
||
|
+ result = mp;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ result = NULL;
|
||
|
+ break;
|
||
|
+ }
|
||
|
funlockfile (stream);
|
||
|
|
||
|
- return mp;
|
||
|
+ return result;
|
||
|
}
|
||
|
libc_hidden_def (__getmntent_r)
|
||
|
weak_alias (__getmntent_r, getmntent_r)
|