[CRIU] [PATCH v2 2/2] introduce --skip-mnt cli option

Oleg Nesterov oleg at redhat.com
Thu Apr 2 12:00:45 PDT 2015


Which obviously can be used to "ignore" the mounts we do not want or
need to dump. The user should know what he does.

Note: this patch changes parse_mountinfo() to check should_skip_mount().
This is because imo we want to filter out the unwanted mounts asap, af
if they do not exist. This increases the chances the dumping will fail
if something else depends on this mount. Say, another mountpoint or an
opened file.

Perhaps it makes sense to teach should_skip_mount() to use fnmatch()
and/or look at the optional "(fs|mnt)=" prefix to skip by fsname too.

Signed-off-by: Oleg Nesterov <oleg at redhat.com>
---
 crtools.c            |    6 ++++++
 include/proc_parse.h |    1 +
 proc_parse.c         |   43 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/crtools.c b/crtools.c
index 5eae49f..dd7aaf8 100644
--- a/crtools.c
+++ b/crtools.c
@@ -204,6 +204,7 @@ int main(int argc, char *argv[], char *envp[])
 		{ "cgroup-root", required_argument, 0, 1061},
 		{ "inherit-fd", required_argument, 0, 1062},
 		{ "feature", required_argument, 0, 1063},
+		{ "skip-mnt", required_argument, 0, 1064},
 		{ },
 	};
 
@@ -421,6 +422,10 @@ int main(int argc, char *argv[], char *envp[])
 			if (check_add_feature(optarg) < 0)
 				return 1;
 			break;
+		case 1064:
+			if (!add_skip_mount(optarg))
+				return 1;
+			break;
 		case 'M':
 			{
 				char *aux;
@@ -647,6 +652,7 @@ usage:
 "                        change the root cgroup the controller will be\n"
 "                        installed into. No controller means that root is the\n"
 "                        default for all controllers not specified.\n"
+"  --skip-mnt PATH       ignore this mountpoint when dumping the mount namespace.\n"
 "\n"
 "* Logging:\n"
 "  -o|--log-file FILE    log file name\n"
diff --git a/include/proc_parse.h b/include/proc_parse.h
index 4c9ec4e..a0fee1f 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -153,6 +153,7 @@ extern void mnt_entry_free(struct mount_info *mi);
 
 struct vm_area_list;
 
+extern bool add_skip_mount(const char *mountpoint);
 extern struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid, bool for_dump);
 extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
 extern int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list);
diff --git a/proc_parse.c b/proc_parse.c
index d361fff..31ec5fc 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -975,6 +975,37 @@ err:
 	goto ret;
 }
 
+static LIST_HEAD(skip_mount_list);
+
+struct str_node {
+	struct list_head node;
+	char string[];
+};
+
+bool add_skip_mount(const char *mountpoint)
+{
+	struct str_node *skip = xmalloc(sizeof(struct str_node) +
+					strlen(mountpoint) + 1);
+	if (!skip)
+		return false;
+
+	strcpy(skip->string, mountpoint);
+	list_add(&skip->node, &skip_mount_list);
+	return true;
+}
+
+static bool should_skip_mount(const char *mountpoint)
+{
+	struct str_node *pos;
+
+	list_for_each_entry(pos, &skip_mount_list, node) {
+		if (strcmp(mountpoint, pos->string) == 0)
+			return true;
+	}
+
+	return false;
+}
+
 struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid, bool for_dump)
 {
 	struct mount_info *list = NULL;
@@ -1004,6 +1035,18 @@ struct mount_info *parse_mountinfo(pid_t pid, struct ns_id *nsid, bool for_dump)
 			goto end;
 		}
 
+		/*
+		 * Drop this mountpoint early, so that lookup_mnt_id/etc will
+		 * fail loudly at "dump" stage if an opened file or another mnt
+		 * depends on this one.
+		 */
+		if (for_dump && should_skip_mount(new->mountpoint + 1)) {
+			pr_info("\tskip %s @ %s\n", fsname,  new->mountpoint);
+			mnt_entry_free(new);
+			new = NULL;
+			goto end;
+		}
+
 		pr_info("\ttype %s source %s mnt_id %d s_dev %#x %s @ %s flags %#x options %s\n",
 				fsname, new->source,
 				new->mnt_id, new->s_dev, new->root, new->mountpoint,
-- 
1.5.5.1




More information about the CRIU mailing list