From b8f2fce2a20944cd8b1a7e91dfa04f9725ec3eb8 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Thu, 18 Nov 2021 11:47:08 +0100
Subject: [PATCH] libmount: (--all) continue although /proc is not mounted

Now 'mount --all' ends with error if /proc is not mounted and there is
some other entry before /proc in fstab. This commit improves this
situation and ignores all mount table related errors if the table is
empty.

This is important for situation when there is for example "/" as the
first line in fstab.

Addresses: https://github.com/util-linux/util-linux/issues/1492
Signed-off-by: Karel Zak <kzak@redhat.com>
---
 libmount/src/context.c       | 25 +++++++++++++++++--------
 libmount/src/context_mount.c |  9 ++++++++-
 sys-utils/mount.8.adoc       |  2 ++
 3 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/libmount/src/context.c b/libmount/src/context.c
index 3b32224..bd215c0 100644
--- a/libmount/src/context.c
+++ b/libmount/src/context.c
@@ -1298,6 +1298,16 @@ int mnt_context_get_mtab(struct libmnt_context *cxt, struct libmnt_table **tb)
 					cxt->table_fltrcb_data);
 
 		mnt_table_set_cache(cxt->mtab, mnt_context_get_cache(cxt));
+	}
+
+	/* Read the table; it's empty, because this first mnt_context_get_mtab()
+	 * call, or because /proc was not accessible in previous calls */
+	if (mnt_table_is_empty(cxt->mtab)) {
+		if (!ns_old) {
+			ns_old = mnt_context_switch_target_ns(cxt);
+			if (!ns_old)
+				return -MNT_ERR_NAMESPACE;
+		}
 
 		/*
 		 * Note that mtab_path is NULL if mtab is useless or unsupported
@@ -2874,7 +2884,7 @@ int mnt_context_is_fs_mounted(struct libmnt_context *cxt,
 			      struct libmnt_fs *fs, int *mounted)
 {
 	struct libmnt_table *mtab, *orig;
-	int rc;
+	int rc = 0;
 	struct libmnt_ns *ns_old;
 
 	if (!cxt || !fs || !mounted)
@@ -2893,18 +2903,17 @@ int mnt_context_is_fs_mounted(struct libmnt_context *cxt,
 			cxt->mtab = NULL;
 		}
 		*mounted = 0;
-		return 0;	/* /proc not mounted */
-	}
+		rc = 0;			/* /proc not mounted */
 
-	if (rc)
-		return rc;
-
-	*mounted = __mnt_table_is_fs_mounted(mtab, fs,
+	} else if (rc == 0) {
+		*mounted = __mnt_table_is_fs_mounted(mtab, fs,
 				mnt_context_get_target_prefix(cxt));
 
+	}
+
 	if (!mnt_context_switch_ns(cxt, ns_old))
 		return -MNT_ERR_NAMESPACE;
-	return 0;
+	return rc;
 }
 
 static int mnt_context_add_child(struct libmnt_context *cxt, pid_t pid)
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
index 55ebf79..f9bedd2 100644
--- a/libmount/src/context_mount.c
+++ b/libmount/src/context_mount.c
@@ -1397,8 +1397,15 @@ int mnt_context_next_mount(struct libmnt_context *cxt,
 
 	/* ignore already mounted filesystems */
 	rc = mnt_context_is_fs_mounted(cxt, *fs, &mounted);
-	if (rc)
+	if (rc) {
+		if (mnt_table_is_empty(cxt->mtab)) {
+			DBG(CXT, ul_debugobj(cxt, "next-mount: no mount table [rc=%d], ignore", rc));
+			rc = 0;
+			if (ignored)
+				*ignored = 1;
+		}
 		return rc;
+	}
 	if (mounted) {
 		if (ignored)
 			*ignored = 2;
diff --git a/sys-utils/mount.8.adoc b/sys-utils/mount.8.adoc
index 6e72d48..e8f0c36 100644
--- a/sys-utils/mount.8.adoc
+++ b/sys-utils/mount.8.adoc
@@ -301,6 +301,8 @@ Command-line options available for the *mount* command are:
 *-a*, *--all*::
 Mount all filesystems (of the given types) mentioned in _fstab_ (except for those whose line contains the *noauto* keyword). The filesystems are mounted following their order in _fstab_. The *mount* command compares filesystem source, target (and fs root for bind mount or btrfs) to detect already mounted filesystems. The kernel table with already mounted filesystems is cached during *mount --all*. This means that all duplicated _fstab_ entries will be mounted.
 +
+The correct functionality depends on /proc (to detect already mounted filesystems) and on /sys (to evaluate filesystem tags like UUID= or LABEL=). It's strongly recommended to mount /proc and /sys filesystems before *mount -a* is executed, or keep /proc and /sys at the beginning of fstab.
++
 The option *--all* is possible to use for remount operation too. In this case all filters (*-t* and *-O*) are applied to the table of already mounted filesystems.
 +
 Since version 2.35 is possible to use the command line option *-o* to alter mount options from _fstab_ (see also *--options-mode*).
-- 
2.27.0

