[CRIU] [PATCH 3/3] flock: Merge all file lock entries into single image file

Pavel Emelyanov xemul at parallels.com
Wed Aug 6 10:08:42 PDT 2014


They are now in per-pid images, but every entry contains a
pid to which it "belongs". This belonging is fake -- it's
just a pid of a task who placed the lock, while locks really
belong to files. We even have a bug when task that locked
a file exited and "delegated" the lock to its child.

This images merge reduces the amount of image files criu 
generates and may simplify the fix of mentioned above issue.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 cr-restore.c         |  2 ++
 file-lock.c          | 45 +++++++++++++++++++++++++++++++++++++++++++--
 image-desc.c         |  7 ++++++-
 include/file-lock.h  |  1 +
 include/image-desc.h |  3 ++-
 5 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 7569afa..de6e9e9 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -70,6 +70,7 @@
 #include "plugin.h"
 #include "cgroup.h"
 #include "timerfd.h"
+#include "file-lock.h"
 
 #include "parasite-syscall.h"
 
@@ -155,6 +156,7 @@ static struct collect_image_info *cinfos[] = {
 	&tunfile_cinfo,
 	&ext_file_cinfo,
 	&timerfd_cinfo,
+	&file_locks_cinfo,
 };
 
 static int root_prepare_shared(void)
diff --git a/file-lock.c b/file-lock.c
index dbc687c..5dc8794 100644
--- a/file-lock.c
+++ b/file-lock.c
@@ -14,8 +14,31 @@
 #include "parasite.h"
 #include "parasite-syscall.h"
 
+struct file_lock_rst {
+	FileLockEntry *fle;
+	struct list_head l;
+};
+
 struct list_head file_lock_list = LIST_HEAD_INIT(file_lock_list);
 
+static int collect_one_file_lock(void *o, ProtobufCMessage *m)
+{
+	struct file_lock_rst *lr = o;
+
+	lr->fle = pb_msg(m, FileLockEntry);
+	list_add_tail(&lr->l, &file_lock_list);
+
+	return 0;
+}
+
+struct collect_image_info file_locks_cinfo = {
+	.fd_type = CR_FD_FILE_LOCKS,
+	.pb_type = PB_FILE_LOCK,
+	.priv_size = sizeof(struct file_lock_rst),
+	.collect = collect_one_file_lock,
+	.flags = COLLECT_OPTIONAL,
+};
+
 struct file_lock *alloc_file_lock(void)
 {
 	struct file_lock *flock;
@@ -45,7 +68,7 @@ static int dump_one_file_lock(FileLockEntry *fle, const struct cr_fdset *fdset)
 	pr_info("flag: %d,type: %d,pid: %d,fd: %d,start: %8"PRIx64",len: %8"PRIx64"\n",
 		fle->flag, fle->type, fle->pid,	fle->fd, fle->start, fle->len);
 
-	return pb_write_one(fdset_fd(fdset, CR_FD_FILE_LOCKS),
+	return pb_write_one(fdset_fd(glob_fdset, CR_FD_FILE_LOCKS),
 			fle, PB_FILE_LOCK);
 }
 
@@ -223,6 +246,22 @@ err:
 
 static int restore_file_locks(int pid)
 {
+	int ret = 0;
+	struct file_lock_rst *lr;
+
+	list_for_each_entry(lr, &file_lock_list, l) {
+		if (lr->fle->pid == pid) {
+			ret = restore_file_lock(lr->fle);
+			if (ret)
+				break;
+		}
+	}
+
+	return ret;
+}
+
+static int restore_file_locks_legacy(int pid)
+{
 	int fd, ret = -1;
 	FileLockEntry *fle;
 
@@ -255,6 +294,8 @@ int prepare_file_locks(int pid)
 		return 0;
 
 	pr_info("Restore file locks.\n");
+	if (file_locks_cinfo.flags & COLLECT_HAPPENED)
+		return restore_file_locks(pid);
 
-	return restore_file_locks(pid);
+	return restore_file_locks_legacy(pid);
 }
diff --git a/image-desc.c b/image-desc.c
index 1e0e3f0..49dc29d 100644
--- a/image-desc.c
+++ b/image-desc.c
@@ -69,7 +69,7 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
 	FD_ENTRY(TMPFS_DEV,	"tmpfs-dev-%d.tar.gz"),
 	FD_ENTRY(TTY_FILES,	"tty"),
 	FD_ENTRY(TTY_INFO,	"tty-info"),
-	FD_ENTRY(FILE_LOCKS,	"filelocks-%d"),
+	FD_ENTRY(FILE_LOCKS,	"filelocks"),
 	FD_ENTRY(RLIMIT,	"rlimit-%d"),
 	FD_ENTRY(PAGES,		"pages-%u"),
 	FD_ENTRY(PAGES_OLD,	"pages-%d"),
@@ -89,4 +89,9 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
 		.fmt	= "irmap-cache",
 		.magic	= IRMAP_CACHE_MAGIC,
 	},
+
+	[CR_FD_FILE_LOCKS_PID] = {
+		.fmt	= "filelocks-%d",
+		.magic	= FILE_LOCKS_MAGIC,
+	},
 };
diff --git a/include/file-lock.h b/include/file-lock.h
index 56de975..536ce94 100644
--- a/include/file-lock.h
+++ b/include/file-lock.h
@@ -53,6 +53,7 @@ extern int dump_task_file_locks(struct parasite_ctl *ctl,
 			struct cr_fdset *fdset,	struct parasite_drain_fd *dfds);
 
 extern int prepare_file_locks(int pid);
+extern struct collect_image_info file_locks_cinfo;
 
 #define OPT_FILE_LOCKS	"file-locks"
 
diff --git a/include/image-desc.h b/include/image-desc.h
index eb42990..93b3392 100644
--- a/include/image-desc.h
+++ b/include/image-desc.h
@@ -11,7 +11,6 @@ enum {
 	 */
 
 	_CR_FD_TASK_FROM,
-	CR_FD_FILE_LOCKS,
 	CR_FD_CORE,
 	CR_FD_IDS,
 	CR_FD_MM,
@@ -76,6 +75,7 @@ enum {
 	CR_FD_TUNFILE,
 	CR_FD_CGROUP,
 	CR_FD_TIMERFD,
+	CR_FD_FILE_LOCKS,
 	_CR_FD_GLOB_TO,
 
 	CR_FD_TMPFS_IMG,
@@ -89,6 +89,7 @@ enum {
 	CR_FD_RLIMIT,
 	CR_FD_ITIMERS,
 	CR_FD_POSIX_TIMERS,
+	CR_FD_FILE_LOCKS_PID,
 
 	CR_FD_IRMAP_CACHE,
 
-- 
1.8.4.2




More information about the CRIU mailing list