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