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