[CRIU] [PATCH 07/28] dump: fd tree updated

Kinsbursky Stanislav skinsbursky at openvz.org
Thu Mar 22 13:58:18 EDT 2012


From: Stanislav Kinsbursky <skinsbursky at openvz.org>

1) return id instead of structure instance
2) return new entry flag.
3) fd forest introduced.
4) enum for fd types introduced.

Signed-off-by: Stanislav Kinsbursky <skinsbursky at openvz.org>
---
 cr-dump.c          |   15 ++----
 file-ids.c         |  124 +++++++++++++++++++++++++++++++++++++---------------
 include/file-ids.h |   27 +++--------
 include/image.h    |   14 ++++--
 4 files changed, 111 insertions(+), 69 deletions(-)
-------------- next part --------------
diff --git a/cr-dump.c b/cr-dump.c
index 35c2887..912bb94 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -121,20 +121,15 @@ static int dump_one_reg_file(const struct file_entry *p, pid_t pid,
 	e.fde.id	= FD_ID_INVALID;
 
 	if (likely(!fd_is_special(&e.fde))) {
-		struct fd_id_entry *entry;
+		u8 new;
+		long id;
 
-		/*
-		 * Make sure the union is still correlate with structure
-		 * we write to disk.
-		 */
-		BUILD_BUG_ON(sizeof(entry->u.key) != sizeof(e.fde.id));
-
-		entry = fd_id_entry_collect((u32)p->id, pid, target_fd);
-		if (!entry)
+		id = file_collect(pid, target_fd, p, &new);
+		if (id < 0)
 			goto err;
 
 		/* Now it might have completely new ID here */
-		e.fde.id = entry->u.id;
+		e.fde.id = id;
 	}
 
 	pr_info("fdinfo: type: %2x len: %2x flags: %4x pos: %8lx addr: %16lx\n",
diff --git a/file-ids.c b/file-ids.c
index 9d2608f..e155c93 100644
--- a/file-ids.c
+++ b/file-ids.c
@@ -15,7 +15,6 @@
 
 #include "compiler.h"
 #include "syscall.h"
-#include "image.h"
 #include "util.h"
 
 /*
@@ -58,24 +57,56 @@
  * in one pass.
  */
 
-struct rb_root fd_id_root;
-static unsigned long fd_id_entries_subid = 1;
+struct file_node {
+	struct rb_node	node;
 
-static struct fd_id_entry *alloc_fd_id_entry(u32 genid, pid_t pid, int fd)
+	struct rb_root	subtree_root;
+	struct rb_node	subtree_node;
+
+	union {
+		struct {
+			u32             genid;  /* generic id, may have duplicates */
+			u32             subid;  /* subid is always unique */
+		} key;
+		u64                     id;
+	} u;
+
+	struct file_info	info;
+} __aligned(sizeof(long));
+
+static struct rb_root dump_file_forest[FD_INFO_MAX];
+
+static int compare_map_files(pid_t pid1, pid_t pid2, u8 fd1, u8 fd2)
 {
-	struct fd_id_entry *e;
+	return 0;
+}
+
+static int compare_open_files(pid_t pid1, pid_t pid2, u8 fd1, u8 fd2)
+{
+	return sys_kcmp(pid1, pid2, KCMP_FILE, fd1, fd2);
+}
+
+static struct file_node *alloc_file_node(struct file_node *parent,
+					     u32 genid, pid_t pid, u8 fd,
+					     u8 *new_entry)
+{
+	struct file_node *e;
 
 	e = xmalloc(sizeof(*e));
 	if (!e)
 		goto err;
 
-	e->u.key.subid	= fd_id_entries_subid++;
+	e->u.key.subid	= 0;
 	e->u.key.genid	= genid;
-	e->pid		= pid;
-	e->fd		= fd;
+	e->info.pid	= pid;
+	e->info.fd	= fd;
+	if (parent) {
+		e->u.key.subid = ++parent->u.key.subid;
+		/* Make sure no overflow here */
+		BUG_ON(!parent->u.key.subid);
+	}
 
-	/* Make sure no overflow here */
-	BUG_ON(!e->u.key.subid);
+	*new_entry = 1;
 
 	rb_init_node(&e->node);
 	rb_init_node(&e->subtree_node);
@@ -84,18 +115,20 @@ err:
 	return e;
 }
 
-static struct fd_id_entry *
-lookup_alloc_subtree(struct fd_id_entry *e, u32 genid, pid_t pid, int fd)
+static struct file_node *
+lookup_alloc_subtree(struct file_node *e, pid_t pid, u8 fd,
+		     int (*compare)(pid_t , pid_t , u8 , u8 ), u8 *new_entry)
 {
 	struct rb_node *node = e->subtree_root.rb_node;
-	struct fd_id_entry *sub = NULL;
+	struct file_node *sub = NULL;
 
 	struct rb_node **new = &e->subtree_root.rb_node;
 	struct rb_node *parent = NULL;
 
 	while (node) {
-		struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, subtree_node);
-		int ret = sys_kcmp(this->pid, pid, KCMP_FILE, this->fd, fd);
+		struct file_node *this = rb_entry(node, struct file_node, subtree_node);
+		struct file_info *info = &this->info;
+		int ret = compare(info->pid, pid, info->fd, fd);
 
 		parent = *new;
 		if (ret < 0)
@@ -106,7 +139,7 @@ lookup_alloc_subtree(struct fd_id_entry *e, u32 genid, pid_t pid, int fd)
 			return this;
 	}
 
-	sub = alloc_fd_id_entry(genid, pid, fd);
+	sub = alloc_file_node(e, e->u.key.genid, pid, fd, new_entry);
 	if (!sub)
 		goto err;
 
@@ -115,31 +148,52 @@ err:
 	return sub;
 }
 
-struct fd_id_entry *fd_id_entry_collect(u32 genid, pid_t pid, int fd)
+static struct file_node *lookup_alloc_node(pid_t pid, int fd,
+					     const struct file_entry *p,
+					     u8 *new_entry)
 {
-	struct rb_node *node = fd_id_root.rb_node;
-	struct fd_id_entry *e = NULL;
-
-	struct rb_node **new = &fd_id_root.rb_node;
+	struct rb_node *node;
+	struct rb_node **new;
 	struct rb_node *parent = NULL;
+	struct rb_root *fd_root;
+	struct file_node *e;
+	int (*compare)(pid_t , pid_t , u8 , u8 );
+
+	fd_root = &dump_file_forest[p->type];
+	node = fd_root->rb_node;
+	new = &fd_root->rb_node;
+
+	compare = compare_open_files;
+	if (p->type == FDINFO_MAP)
+		compare = compare_map_files;
 
 	while (node) {
-		struct fd_id_entry *this = rb_entry(node, struct fd_id_entry, node);
+		struct file_node *this = rb_entry(node, struct file_node, node);
 
-		parent = *new;
-		if (genid < this->u.key.genid)
-			node = node->rb_left, new = &((*new)->rb_left);
-		else if (genid > this->u.key.genid)
-			node = node->rb_right, new = &((*new)->rb_right);
+		parent = node;
+		if (p->id < this->u.key.genid)
+			node = node->rb_left, new = &parent->rb_left;
+		else if (p->id > this->u.key.genid)
+			node = node->rb_right, new = &parent->rb_right;
 		else
-			return lookup_alloc_subtree(this, genid, pid, fd);
+			return lookup_alloc_subtree(this, pid, fd,
+						    compare, new_entry);
 	}
-
-	e = alloc_fd_id_entry(genid, pid, fd);
-	if (!e)
-		goto err;
-
-	rb_link_and_balance(&fd_id_root, &e->node, parent, new);
-err:
+	e = alloc_file_node(NULL, p->id, pid, fd, new_entry);
+	if (e)
+		rb_link_and_balance(fd_root, &e->node, parent, new);
 	return e;
 }
+
+long file_collect(pid_t pid, int fd, const struct file_entry *p, u8 *new_entry)
+{
+	struct file_node *e = NULL;
+
+	if (p->type >= FD_INFO_MAX)
+		return -ENOTSUP;
+	*new_entry = 0;
+	e = lookup_alloc_node(pid, fd, p, new_entry);
+	if (e == NULL)
+		return -ENOMEM;
+	return e->u.id;
+}
diff --git a/include/file-ids.h b/include/file-ids.h
index 3001f80..7833ef3 100644
--- a/include/file-ids.h
+++ b/include/file-ids.h
@@ -4,31 +4,20 @@
 #include "compiler.h"
 #include "types.h"
 #include "rbtree.h"
+#include "image.h"
 
 #define FD_ID_INVALID		(-1UL)
 #define FD_PID_INVALID		((int)-2UL)
 
-struct fd_id_entry {
-	struct rb_node	node;
-
-	struct rb_root	subtree_root;
-	struct rb_node	subtree_node;
-
-	union {
-		struct {
-			u32		genid;	/* generic id, may have duplicates */
-			u32		subid;	/* subid is always unique */
-		} key;
-		u64			id;
-	} u;
-
-	pid_t		pid;
-	int		fd;
-} __aligned(sizeof(long));
-
 #define MAKE_FD_GENID(dev, ino, pos) \
 	(((u32)(dev) ^ (u32)(ino) ^ (u32)(pos)))
 
-extern struct fd_id_entry *fd_id_entry_collect(u32 genid, pid_t pid, int fd);
+struct file_info {
+	int			fd;
+	int			pid;
+	const struct file_entry	*rfe;
+};
+
+extern long file_collect(pid_t pid, int fd, const struct file_entry *p, u8 *new_entry);
 
 #endif /* FILE_IDS_H__ */
diff --git a/include/image.h b/include/image.h
index bf77d77..5b76a67 100644
--- a/include/image.h
+++ b/include/image.h
@@ -29,12 +29,16 @@
 
 #define PIPEFS_MAGIC	0x50495045
 
-#define FDINFO_REG	1
-#define FDINFO_MAP	2
+enum fd_types {
+	FDINFO_UND,
+	FDINFO_REG,
+	FDINFO_MAP,
 
-/* Specials */
-#define FDINFO_CWD	3
-#define FDINFO_EXE	4
+	FDINFO_CWD,
+	FDINFO_EXE,
+
+	FD_INFO_MAX
+};
 
 #define PAGE_IMAGE_SIZE	4096
 #define PAGE_RSS	1


More information about the CRIU mailing list