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