]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: use autofs mount hint to ignore autofs mount entries
authorIan Kent <raven@themaw.net>
Thu, 24 Nov 2022 08:54:19 +0000 (16:54 +0800)
committerKarel Zak <kzak@redhat.com>
Tue, 29 Nov 2022 10:14:29 +0000 (11:14 +0100)
Historically autofs mounts were not included in mount table listings.
This is the case in other SysV autofs implementations and was also
the case with Linux autofs.

But now that /etc/mtab is a symlink to the proc filesystem mount
table the autofs mount entries appear in the mount table on Linux.

Prior to the symlinking of /etc/mtab mount table it was sufficient
to call mount(2) and simply not update /etc/mtab to exclude autofs
mounts from mount listings.

Also, with this symlinking of /etc/mtab we have seen a shift in usage
toward using the proc mount tables directly.

But the autofs mount entries need to be retained when coming from the
proc file system for applications that need them (such as systemd) so
filtering out these entries within the kernel itself can't be done,
it needs be done in user space.

There are three reasons to omit the autofs mount entries.

One is that certain types of auto-mounts have an autofs mount for every
entry in their autofs mount map (autofs direct mounts) and these maps
can be quite large. This leads to mount table listings containing a lot
of unnecessary entries.

Also, this difference in behaviour between autofs implementations can
cause problems for applications that need to use the mount table and
expect autofs entries aren't present.

Lastly, there's very little that user space can do with autofs mount
entries since this must be left to the autofs mount owner, typically
the automount daemon. And it can also lead to attempts to access
automount managed paths resulting in mounts being triggered when they
aren't needed or mounts staying mounted for much longer thay they
need to be.

So the Linux autofs file system has been modified to accept a pseudo
mount option of "ignore" (as is used in other OS implementations) so
that user space utilities can use this as a hint to skip these autofs
entries on reading the mount table.

The Linux autofs automount daemon used getmntent(3) itself and has been
modified to use the proc file system directly so that it isn't affected
by the presence of the "ignore" mount option.

The use of the "ignore" mount option is opt-in by autofs users and a
configuration option has been added which defaults to not use the option
so if there are applications that need these entries, other than autofs
itself, they can be retained. Also, since this filtering is based on an
added mount option earlier versions of Linux autofs and other autofs file
system users will not use the option and so won't be affected by the change.

Changes in v2:
- make naming consistent with util-linux conventions.
- make ignoring autofs mount entries the default since it will only
  have an effect if it has been enabled in the autofs configuration.
- drop patch to set ingore autofs mounts for mount(8) since it's now
  default.

Signed-off-by: Ian Kent <raven@themaw.net>
libmount/src/context.c
libmount/src/libmount.h.in
libmount/src/libmount.sym
libmount/src/mountP.h
libmount/src/tab_parse.c

index d325ce4309fccd544e90b48d71c61cfe0081e42e..a6d78953cdbea266bb6dd9f15766166e806e7a7c 100644 (file)
@@ -77,6 +77,8 @@ struct libmnt_context *mnt_new_context(void)
        /* if we're really root and aren't running setuid */
        cxt->restricted = (uid_t) 0 == ruid && ruid == euid ? 0 : 1;
 
+       cxt->noautofs = 1;
+
        DBG(CXT, ul_debugobj(cxt, "----> allocate %s",
                                cxt->restricted ? "[RESTRICTED]" : ""));
 
@@ -171,6 +173,7 @@ int mnt_reset_context(struct libmnt_context *cxt)
        cxt->mountdata = NULL;
        cxt->subdir = NULL;
        cxt->flags = MNT_FL_DEFAULT;
+       cxt->noautofs = 1;
 
        /* free additional mounts list */
        while (!list_empty(&cxt->addmounts)) {
@@ -311,6 +314,8 @@ struct libmnt_context *mnt_copy_context(struct libmnt_context *o)
        n->table_fltrcb = o->table_fltrcb;
        n->table_fltrcb_data = o->table_fltrcb_data;
 
+       n->noautofs = o->noautofs;
+
        return n;
 failed:
        mnt_free_context(n);
@@ -1299,6 +1304,8 @@ int mnt_context_get_mountinfo(struct libmnt_context *cxt, struct libmnt_table **
                        goto end;
                }
 
+               mnt_table_enable_noautofs(cxt->mountinfo, cxt->noautofs);
+
                if (cxt->table_errcb)
                        mnt_table_set_parser_errcb(cxt->mountinfo, cxt->table_errcb);
                if (cxt->table_fltrcb)
@@ -2778,6 +2785,23 @@ int mnt_context_strerror(struct libmnt_context *cxt __attribute__((__unused__)),
        return 0;
 }
 
+/**
+ * mnt_context_enable_noautofs:
+ * @cxt: context
+ * @ignore: ignore or don't ignore
+ *
+ * Enable/disable ignore autofs mount table entries on reading the
+ * mount table. Only effective if the "ignore" mount option is being
+ * used for autofs mounts (such as if automount(8) has been configured
+ * to do so).
+ */
+int mnt_context_enable_noautofs(struct libmnt_context *cxt, int ignore)
+{
+       if (!cxt)
+               return -EINVAL;
+       cxt->noautofs = ignore ? 1 : 0;
+       return 0;
+}
 
 int mnt_context_get_generic_excode(int rc, char *buf, size_t bufsz, const char *fmt, ...)
 {
index 2fb641d03a4efb9db72ed216ea912fee81b00e60..8ca58a0b5f47f52b3a540c01b8b2eb32864fbf7a 100644 (file)
@@ -863,6 +863,8 @@ extern int mnt_context_strerror(struct libmnt_context *cxt, char *buf,
                                size_t bufsiz)
                                __ul_attribute__((deprecated));
 
+extern int mnt_context_enable_noautofs(struct libmnt_context *cxt, int ignore);
+
 extern int mnt_context_get_excode(struct libmnt_context *cxt,
                         int rc, char *buf, size_t bufsz);
 
index b99fc4cc29d218dc6aad636c943e351cb2249148..e0df6db3b2067a6a7f3b12b2d5bf666f90d0f83e 100644 (file)
@@ -371,4 +371,7 @@ MOUNT_2_39 {
        mnt_context_enable_onlyonce;
        mnt_context_is_lazy;
        mnt_context_get_mountinfo_userdata;
+       mnt_context_enable_noautofs;
+       mnt_table_enable_noautofs;
+       mnt_table_is_noautofs;
 } MOUNT_2_38;
index ffd9ba4fe3be2148f86aad3de8d24e0259318aa8..6f8f03a331eecee4a30af8a31079d44c5c19b4c0 100644 (file)
@@ -148,6 +148,9 @@ extern int __mnt_table_is_fs_mounted(       struct libmnt_table *tb,
                                        struct libmnt_fs *fstab_fs,
                                        const char *tgt_prefix);
 
+extern int mnt_table_enable_noautofs(struct libmnt_table *tb, int ignore);
+extern int mnt_table_is_noautofs(struct libmnt_table *tb);
+
 /*
  * Generic iterator
  */
@@ -251,6 +254,7 @@ struct libmnt_table {
        int             (*fltrcb)(struct libmnt_fs *fs, void *data);
        void            *fltrcb_data;
 
+       int             noautofs;       /* ignore autofs mounts */
 
        struct list_head        ents;   /* list of entries (libmnt_fs) */
        void            *userdata;
@@ -357,7 +361,8 @@ struct libmnt_context
        struct libmnt_ns        ns_tgt;         /* target namespace */
        struct libmnt_ns        *ns_cur;        /* pointer to current namespace */
 
-       unsigned int    enabled_textdomain : 1;         /* bindtextdomain() called */
+       unsigned int    enabled_textdomain : 1; /* bindtextdomain() called */
+       unsigned int    noautofs : 1;           /* ignore autofs mounts */
 };
 
 /* flags */
index 75f8e406bb42ad4e1d5724096fec344ed4620ffe..6e3d5ef9f731be012355ad0f045f869363fdbcac 100644 (file)
@@ -762,6 +762,14 @@ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filenam
                if (rc == 0 && tb->fltrcb && tb->fltrcb(fs, tb->fltrcb_data))
                        rc = 1; /* filtered out by callback... */
 
+               if (rc == 0 && mnt_table_is_noautofs(tb)) {
+                       const char *fstype = mnt_fs_get_fstype(fs);
+
+                       if (fstype && strcmp(fstype, "autofs") == 0 &&
+                           mnt_fs_get_option(fs, "ignore", NULL, NULL) == 0)
+                               rc = 1; /* Skip "ignore" autofs entry */
+               }
+
                /* add to the table */
                if (rc == 0) {
                        rc = mnt_table_add_fs(tb, fs);
@@ -1059,6 +1067,32 @@ int mnt_table_set_parser_fltrcb(struct libmnt_table *tb,
        return 0;
 }
 
+/*
+ * mnt_table_enable_noautofs:
+ * @tb: table
+ * @ignore: ignore or don't ignore
+ *
+ * Enable/disable ignore autofs mount table entries on reading.
+ */
+int mnt_table_enable_noautofs(struct libmnt_table *tb, int ignore)
+{
+       if (!tb)
+               return -EINVAL;
+       tb->noautofs = ignore ? 1 : 0;
+       return 0;
+}
+
+/*
+ * mnt_table_is_noautofs:
+ * @tb: table
+ *
+ * Return the the enabled status of ignore autofs mount table entries.
+ */
+int mnt_table_is_noautofs(struct libmnt_table *tb)
+{
+       return tb ? tb->noautofs : 0;
+}
+
 /**
  * mnt_table_parse_swaps:
  * @tb: table