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