[3/5] mount: Move binfmt_misc-mounting code to separate function

Submitted by Kirill Tkhai on July 15, 2017, 3:25 p.m.

Details

Message ID 150013232164.12956.15053354524318939700.stgit@localhost.localdomain
State New
Series "binfmt_misc: Switch to dumpee user_ns before mount"
Headers show

Commit Message

Kirill Tkhai July 15, 2017, 3:25 p.m.
Introduce new helper mount_and_collect_binfmt_misc(),
and do all the work there.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/mount.c |   61 ++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 36 insertions(+), 25 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/mount.c b/criu/mount.c
index 0eaa9c67f..176cc436c 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -1291,7 +1291,40 @@  static __maybe_unused int mount_cr_time_mount(struct ns_id *ns, unsigned int *s_
 	return ret < 0 ? 0 : exit_code;
 }
 
+static __maybe_unused int mount_and_collect_binfmt_misc(void)
+{
+	unsigned int s_dev = 0;
+	struct ns_id *ns;
+	int ret;
 
+	for (ns = ns_ids; ns != NULL; ns = ns->next) {
+		if (ns->type == NS_ROOT && ns->nd == &mnt_ns_desc)
+			break;
+	}
+	BUG_ON(!ns);
+
+	ret = mount_cr_time_mount(ns, &s_dev, "binfmt_misc", "/" BINFMT_MISC_HOME,
+				  "binfmt_misc");
+	if (ret == -EPERM || ret == -ENODEV || ret == -ENOENT) {
+		/*
+		 * EPERM is returned when we're in !init_user_ns, ENODEV and ENOENT
+		 * when no binfmt_misc module is loaded.
+		 */
+		pr_info("Can't mount binfmt_misc: %d %s\n", ret, strerror(-ret));
+		ret = 0;
+	} else if (ret < 0) {
+		errno = -ret;
+		pr_perror("Can't mount binfmt_misc");
+	} else if (ret == 0) {
+		/* Error not connected with mount */
+		ret = -1;
+	} else if (ret > 0) {
+		ret = add_cr_time_mount(ns->mnt.mntinfo_tree, "binfmt_misc",
+					BINFMT_MISC_HOME, s_dev);
+	}
+
+	return ret;
+}
 
 static int dump_one_fs(struct mount_info *mi)
 {
@@ -3253,31 +3286,9 @@  int collect_mnt_namespaces(bool for_dump)
 
 #ifdef CONFIG_BINFMT_MISC_VIRTUALIZED
 	if (for_dump && !opts.has_binfmt_misc) {
-		unsigned int s_dev = 0;
-		struct ns_id *ns;
-
-		for (ns = ns_ids; ns != NULL; ns = ns->next) {
-			if (ns->type == NS_ROOT && ns->nd == &mnt_ns_desc)
-				break;
-		}
-
-		if (ns) {
-			ret = mount_cr_time_mount(ns, &s_dev, "binfmt_misc", "/" BINFMT_MISC_HOME,
-						  "binfmt_misc");
-			if (ret == -EPERM)
-				pr_info("Can't mount binfmt_misc: EPERM. Running in user_ns?\n");
-			else if (ret < 0 && ret != -ENODEV && ret != -ENOENT) {
-				pr_err("Can't mount binfmt_misc: %d %s\n", ret, strerror(-ret));
-				goto err;
-			} else if (ret == 0) {
-				ret = -1;
-				goto err;
-			} else if (ret > 0 && add_cr_time_mount(ns->mnt.mntinfo_tree, "binfmt_misc",
-								BINFMT_MISC_HOME, s_dev) < 0) {
-				ret = -1;
-				goto err;
-			}
-		}
+		ret = mount_and_collect_binfmt_misc();
+		if (ret)
+			goto err;
 	}
 #endif