[CRIU] [PATCH v8 04/15] autofs: parse fsinfo stage introduced

Stanislav Kinsburskiy skinsbursky at virtuozzo.com
Wed Mar 16 06:17:14 PDT 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>
---
 criu/Makefile.crtools |    1 +
 criu/autofs.c         |   61 +++++++++++++++++++++++++++++++++++++++++++++++++
 criu/include/autofs.h |    5 ++++
 criu/mount.c          |    7 ++++++
 criu/pipes.c          |    5 ++--
 5 files changed, 77 insertions(+), 2 deletions(-)
 create mode 100644 criu/autofs.c

diff --git a/criu/Makefile.crtools b/criu/Makefile.crtools
index 4448047..b53612c 100644
--- a/criu/Makefile.crtools
+++ b/criu/Makefile.crtools
@@ -75,6 +75,7 @@ obj-y			+= tty.o
 obj-y			+= tun.o
 obj-y			+= util.o
 obj-y			+= uts_ns.o
+obj-y			+= autofs.o
 
 ifeq ($(VDSO),y)
 obj-y			+= pie-util-vdso.o
diff --git a/criu/autofs.c b/criu/autofs.c
new file mode 100644
index 0000000..ca7c21b
--- /dev/null
+++ b/criu/autofs.c
@@ -0,0 +1,61 @@
+#include "proc_parse.h"
+#include "autofs.h"
+#include "util.h"
+#include "mount.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/criu/include/autofs.h b/criu/include/autofs.h
index b30d915..c0dbe8d 100644
--- a/criu/include/autofs.h
+++ b/criu/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/criu/mount.c b/criu/mount.c
index 23581d4..2958365 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -28,6 +28,7 @@
 #include "kerndat.h"
 #include "fs-magic.h"
 #include "sysfs_parse.h"
+#include "autofs.h"
 
 #include "images/mnt.pb-c.h"
 #include "images/binfmt-misc.pb-c.h"
@@ -1694,6 +1695,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/criu/pipes.c b/criu/pipes.c
index 876eb93..e11e53c 100644
--- a/criu/pipes.c
+++ b/criu/pipes.c
@@ -10,6 +10,7 @@
 #include "files.h"
 #include "pipes.h"
 #include "util-pie.h"
+#include "autofs.h"
 
 #include "protobuf.h"
 #include "images/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