[CRIU] [PATCHv0 1/1] tmpfiles: implement user tmp files feature

Eugene Batalov eabatalov89 at gmail.com
Sun Dec 20 09:35:50 PST 2015


From: Svyatoslav Vlasov <svloyso at gmail.com>

Add new command line option --tmp-file, which allows user to
add files that can be lost between checkpoint and restore to the dump.
User files are stored in .tar.gz archive.
Tar command does all the file paths and attributes related work.

This is for issue #65

Signed-off-by: Svyatoslav Vlasov <svloyso at gmail.com>
Signed-off-by: Eugene Batalov <eabatalov89 at gmail.com>
---
 Makefile.crtools     |   1 +
 cr-dump.c            |   4 ++
 cr-restore.c         |   4 ++
 crtools.c            |  12 ++++++
 image-desc.c         |   1 +
 include/cr_options.h |   1 +
 include/image-desc.h |   1 +
 include/magic.h      |   1 +
 include/tmp_files.h  |   8 ++++
 tmp_files.c          | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++
 10 files changed, 145 insertions(+)
 create mode 100644 include/tmp_files.h
 create mode 100644 tmp_files.c

diff --git a/Makefile.crtools b/Makefile.crtools
index 77a7421..9c104b6 100644
--- a/Makefile.crtools
+++ b/Makefile.crtools
@@ -79,6 +79,7 @@ obj-y	+= fault-injection.o
 obj-y	+= pie/util-fd.o
 obj-y	+= pie/util.o
 obj-y	+= seccomp.o
+obj-y	+= tmp_files.o
 
 ifneq ($(MAKECMDGOALS),clean)
 incdeps := y
diff --git a/cr-dump.c b/cr-dump.c
index 20a2c01..d3e565f 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -82,6 +82,7 @@
 #include "seccomp.h"
 #include "seize.h"
 #include "fault-injection.h"
+#include "tmp_files.h"
 
 #include "asm/dump.h"
 
@@ -1583,6 +1584,9 @@ int cr_dump_tasks(pid_t pid)
 	if (dump_pstree(root_item))
 		goto err;
 
+	if (dump_tmp_files())
+		goto err;
+
 	if (root_ns_mask)
 		if (dump_namespaces(root_item, root_ns_mask) < 0)
 			goto err;
diff --git a/cr-restore.c b/cr-restore.c
index 9eea931..979d9b4 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -78,6 +78,7 @@
 #include "seccomp.h"
 #include "bitmap.h"
 #include "fault-injection.h"
+#include "tmp_files.h"
 #include "parasite-syscall.h"
 
 #include "protobuf.h"
@@ -2200,6 +2201,9 @@ int cr_restore_tasks(void)
 	if (criu_signals_setup() < 0)
 		goto err;
 
+	if (restore_tmp_files() < 0)
+		goto err;
+
 	ret = restore_root_task(root_item);
 err:
 	cr_plugin_fini(CR_PLUGIN_STAGE__RESTORE, ret);
diff --git a/crtools.c b/crtools.c
index f357c0c..ccc647f 100644
--- a/crtools.c
+++ b/crtools.c
@@ -42,6 +42,7 @@
 #include "irmap.h"
 #include "fault-injection.h"
 #include "lsm.h"
+#include "tmp_files.h"
 
 #include "setproctitle.h"
 
@@ -60,6 +61,7 @@ void init_opts(void)
 	INIT_LIST_HEAD(&opts.inherit_fds);
 	INIT_LIST_HEAD(&opts.new_cgroup_roots);
 	INIT_LIST_HEAD(&opts.irmap_scan_paths);
+	INIT_LIST_HEAD(&opts.tmp_files);
 
 	opts.cpu_cap = CPU_CAP_DEFAULT;
 	opts.manage_cgroups = CG_MODE_DEFAULT;
@@ -255,6 +257,7 @@ int main(int argc, char *argv[], char *envp[])
 		{ "ghost-limit",		required_argument,	0, 1069 },
 		{ "irmap-scan-path",		required_argument,	0, 1070 },
 		{ "lsm-profile",		required_argument,	0, 1071 },
+		{ "tmp-file",			required_argument,	0, 1072 },
 		{ },
 	};
 
@@ -504,6 +507,12 @@ int main(int argc, char *argv[], char *envp[])
 			if (parse_lsm_arg(optarg) < 0)
 				return -1;
 			break;
+		case 1072:
+			if (tmp_file_add(optarg)) {
+				pr_err("Can't add tmp file %s\n", optarg);
+				return 1;
+			}
+			break;
 		case 'M':
 			{
 				char *aux;
@@ -753,6 +762,9 @@ usage:
 "  --enable-fs FSNAMES   a comma separated list of filesystem names or \"all\".\n"
 "                        force criu to (try to) dump/restore these filesystem's\n"
 "                        mountpoints even if fs is not supported.\n"
+"  --tmp-file FILE       Use this option for each file that can be lost between\n"
+"                        checkpoint and restore. File will be stored with the dump.\n"
+"                        The FS root of CRIU dump/restore process is always used.\n"
 "\n"
 "* Logging:\n"
 "  -o|--log-file FILE    log file name\n"
diff --git a/image-desc.c b/image-desc.c
index 9fb96c8..30abd5c 100644
--- a/image-desc.c
+++ b/image-desc.c
@@ -95,6 +95,7 @@ struct cr_fd_desc_tmpl imgset_template[CR_FD_MAX] = {
 	FD_ENTRY(CPUINFO,	"cpuinfo"),
 	FD_ENTRY(SECCOMP,	"seccomp"),
 	FD_ENTRY(USERNS,	"userns-%d"),
+	FD_ENTRY_F(TMP_FILES,	"tmpfiles.tar.gz", O_NOBUF),
 
 	[CR_FD_STATS] = {
 		.fmt	= "stats-%s",
diff --git a/include/cr_options.h b/include/cr_options.h
index 2b1054d..4d596d2 100644
--- a/include/cr_options.h
+++ b/include/cr_options.h
@@ -97,6 +97,7 @@ struct cr_options {
 	struct list_head	irmap_scan_paths;
 	bool			lsm_supplied;
 	char			*lsm_profile;
+	struct list_head	tmp_files;
 };
 
 extern struct cr_options opts;
diff --git a/include/image-desc.h b/include/image-desc.h
index 90933e9..e774a87 100644
--- a/include/image-desc.h
+++ b/include/image-desc.h
@@ -80,6 +80,7 @@ enum {
 	CR_FD_SECCOMP,
 	_CR_FD_GLOB_TO,
 
+	CR_FD_TMP_FILES,
 	CR_FD_TMPFS_IMG,
 	CR_FD_TMPFS_DEV,
 	CR_FD_BINFMT_MISC,
diff --git a/include/magic.h b/include/magic.h
index 3cb3766..3d98c39 100644
--- a/include/magic.h
+++ b/include/magic.h
@@ -100,6 +100,7 @@
 #define TMPFS_DEV_MAGIC		RAW_IMAGE_MAGIC
 #define IPTABLES_MAGIC		RAW_IMAGE_MAGIC
 #define IP6TABLES_MAGIC		RAW_IMAGE_MAGIC
+#define TMP_FILES_MAGIC		RAW_IMAGE_MAGIC
 
 #define PAGES_OLD_MAGIC		PAGEMAP_MAGIC
 #define SHM_PAGES_OLD_MAGIC	PAGEMAP_MAGIC
diff --git a/include/tmp_files.h b/include/tmp_files.h
new file mode 100644
index 0000000..1a83882
--- /dev/null
+++ b/include/tmp_files.h
@@ -0,0 +1,8 @@
+#ifndef __CR_TMP_FILES_H__
+#define __CR_TMP_FILES_H__
+
+int tmp_file_add(const char *filename);
+int dump_tmp_files(void);
+int restore_tmp_files(void);
+
+#endif /* __CR_TMP_FILES_H__ */
diff --git a/tmp_files.c b/tmp_files.c
new file mode 100644
index 0000000..8e9c2c0
--- /dev/null
+++ b/tmp_files.c
@@ -0,0 +1,112 @@
+#include <unistd.h>
+#include <limits.h>
+
+#include "tmp_files.h"
+#include "cr_options.h"
+#include "list.h"
+#include "xmalloc.h"
+#include "image.h"
+#include "util.h"
+
+#define TMP_TAR_NAME "tmpfiles.tar"
+
+struct tmp_file_node {
+	struct	list_head list;
+	char	filepath[PATH_MAX];
+};
+
+int tmp_file_add(const char *filename) {
+	struct tmp_file_node *node = xmalloc(sizeof(*node));
+
+	if (!node)
+		return -1;
+	if (!realpath(filename, node->filepath))
+		return -1;
+	if (access(node->filepath, R_OK))
+		return -1;
+
+	list_add_tail(&node->list, &opts.tmp_files);
+	pr_info("Added tmp file: %s", node->filepath);
+	return 0;
+}
+
+static unsigned long get_tmpfiles_count(void) {
+	struct tmp_file_node *pos;
+	unsigned long count = 0;
+
+	list_for_each_entry(pos, &opts.tmp_files, list) {
+		count += 1;
+	}
+	return count;
+}
+
+int dump_tmp_files(void) {
+	int ret = 0;
+	unsigned long n;
+	char **args;
+	static char *default_args[] = {
+		"tar",
+		"--create",
+		"--absolute-names",
+		"--gzip",
+		"--no-unquote",
+		"--no-wildcards",
+		"--to-stdout",
+		NULL
+	};
+	struct tmp_file_node *pos;
+	struct cr_img *img;
+
+	if (list_empty(&opts.tmp_files))
+		return ret;
+
+	args = xmalloc(get_tmpfiles_count() * sizeof(args[0]) +
+					sizeof(default_args));
+	if (!args)
+		return -1;
+	n = 0;
+	for (; default_args[n]; n++)
+		args[n] = default_args[n];
+	list_for_each_entry(pos, &opts.tmp_files, list) {
+		args[n++] = pos->filepath;
+	}
+	args[n] = NULL;
+
+	img = open_image(CR_FD_TMP_FILES, O_DUMP);
+	if (img) {
+		ret = cr_system(-1, img_raw_fd(img), -1, "tar", args, 0);
+		close_image(img);
+	} else
+		ret = -1;
+
+	xfree(args);
+	while (!list_empty(&opts.tmp_files)) {
+		struct tmp_file_node *node;
+
+		node = list_first_entry(&opts.tmp_files,
+					struct tmp_file_node, list);
+		list_del(&node->list);
+		xfree(node);
+	}
+	if (ret)
+		pr_err("Can't dump tmp files. Please check tar output for details\n");
+	return ret;
+}
+
+int restore_tmp_files(void) {
+	int ret = 0;
+	struct cr_img *img;
+
+	img = open_image(CR_FD_TMP_FILES, O_RSTR);
+	if (!img || empty_image(img))
+		return 0;
+	ret = cr_system(img_raw_fd(img), -1, -1, "tar",
+			(char *[]) {"tar", "--extract", "--gzip",
+				"--no-unquote", "--no-wildcards",
+				"--absolute-names", "--directory",
+				"/", NULL}, 0);
+	close_image(img);
+	if (ret)
+		pr_err("Can't restore tmp files. Please check tar output for details\n");
+	return ret;
+}
-- 
1.9.1



More information about the CRIU mailing list