[CRIU] [PATCH v6 04/13] autofs: parse fsinfo stage introduced

Stanislav Kinsburskiy skinsbursky at virtuozzo.com
Wed Jan 27 09:57:11 PST 2016


Autofs uses packetized pipe (with O_DIRECT), migration of which is not
supported.
Luckely, because we support only empty autofs pipes, they can be collected
into some list and then explicitly treated as normal pipes on dump.

Note: packetized mode is set by kernel inself on mount operation. So, we don't
need to carry the flag at all.

Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
---
 Makefile.crtools |    1 +
 autofs.c         |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/autofs.h |    5 +++++
 mount.c          |    7 ++++++
 pipes.c          |    5 +++--
 5 files changed, 76 insertions(+), 2 deletions(-)
 create mode 100644 autofs.c

diff --git a/Makefile.crtools b/Makefile.crtools
index 5788ef0..8a38fd1 100644
--- a/Makefile.crtools
+++ b/Makefile.crtools
@@ -78,6 +78,7 @@ obj-y	+= fault-injection.o
 obj-y	+= pie/util-fd.o
 obj-y	+= pie/util.o
 obj-y	+= seccomp.o
+obj-y	+= autofs.o
 
 ifneq ($(MAKECMDGOALS),clean)
 incdeps := y
diff --git a/autofs.c b/autofs.c
new file mode 100644
index 0000000..e402072
--- /dev/null
+++ b/autofs.c
@@ -0,0 +1,60 @@
+#include "proc_parse.h"
+#include "autofs.h"
+#include "util.h"
+
+#define AUTOFS_OPT_UNKNOWN	INT_MIN
+
+struct autofs_pipe_s {
+	struct list_head list;
+	unsigned long inode;
+};
+
+struct list_head autofs_pipes = LIST_HEAD_INIT(autofs_pipes);
+
+bool is_autofs_pipe(unsigned long inode)
+{
+	struct autofs_pipe_s *p;
+
+	list_for_each_entry(p, &autofs_pipes, list) {
+		if (p->inode == inode)
+			return true;
+	}
+	return false;
+}
+
+static int autofs_gather_pipe(unsigned long inode)
+{
+	struct autofs_pipe_s *pipe;
+
+	pipe = xmalloc(sizeof(*pipe));
+	if (!pipe)
+		return -1;
+	pipe->inode = inode;
+	list_add_tail(&pipe->list, &autofs_pipes);
+	return 0;
+}
+
+int autofs_parse(struct mount_info *pm)
+{
+	long pipe_ino = AUTOFS_OPT_UNKNOWN;
+	char **opts;
+	int nr_opts, i;
+
+	split(pm->options, ',', &opts, &nr_opts);
+	if (!opts)
+		return -1;
+	for (i = 0; i < nr_opts; i++) {
+		if (!strncmp(opts[i], "pipe_ino=", strlen("pipe_ino=")))
+			pipe_ino = atoi(opts[i] + strlen("pipe_ino="));
+	}
+	for (i = 0; i < nr_opts; i++)
+		xfree(opts[i]);
+	free(opts);
+
+	if (pipe_ino == AUTOFS_OPT_UNKNOWN) {
+		pr_err("Failed to find pipe_ino option (old kernel?)\n");
+		return -1;
+	}
+
+	return autofs_gather_pipe(pipe_ino);
+}
diff --git a/include/autofs.h b/include/autofs.h
index b30d915..c0dbe8d 100644
--- a/include/autofs.h
+++ b/include/autofs.h
@@ -5,4 +5,9 @@
 #define AUTOFS_MINOR	235
 #endif
 
+bool is_autofs_pipe(unsigned long inode);
+
+struct mount_info;
+int autofs_parse(struct mount_info *pm);
+
 #endif
diff --git a/mount.c b/mount.c
index 7cdcc53..722a2de 100644
--- a/mount.c
+++ b/mount.c
@@ -27,6 +27,7 @@
 #include "kerndat.h"
 #include "fs-magic.h"
 #include "sysfs_parse.h"
+#include "autofs.h"
 
 #include "protobuf/mnt.pb-c.h"
 #include "protobuf/binfmt-misc.pb-c.h"
@@ -1693,6 +1694,12 @@ static struct fstype fstypes[32] = {
 		.name = "overlay",
 		.code = FSTYPE__OVERLAYFS,
 		.parse = overlayfs_parse,
+	}, {
+		.name = "autofs",
+		.code = FSTYPE__AUTOFS,
+		.parse = autofs_parse,
+		.dump = always_fail,
+		.restore = always_fail,
 	},
 };
 
diff --git a/pipes.c b/pipes.c
index a155212..1f4cc1a 100644
--- a/pipes.c
+++ b/pipes.c
@@ -10,6 +10,7 @@
 #include "files.h"
 #include "pipes.h"
 #include "util-pie.h"
+#include "autofs.h"
 
 #include "protobuf.h"
 #include "protobuf/pipe.pb-c.h"
@@ -499,14 +500,14 @@ static int dump_one_pipe(int lfd, u32 id, const struct fd_parms *p)
 	pr_info("Dumping pipe %d with id %#x pipe_id %#x\n",
 			lfd, id, pipe_id(p));
 
-	if (p->flags & O_DIRECT) {
+	if ((p->flags & O_DIRECT) && !is_autofs_pipe(pipe_id(p))) {
 		pr_err("The packetized mode for pipes is not supported yet\n");
 		return -1;
 	}
 
 	pe.id		= id;
 	pe.pipe_id	= pipe_id(p);
-	pe.flags	= p->flags;
+	pe.flags	= p->flags & ~O_DIRECT;
 	pe.fown		= (FownEntry *)&p->fown;
 
 	if (pb_write_one(img_from_set(glob_imgset, CR_FD_PIPES), &pe, PB_PIPE))



More information about the CRIU mailing list