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