[CRIU] [PATCH 08/28] rst: introduces helpers for adding and searching of shared files

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


From: Stanislav Kinsbursky <skinsbursky at openvz.org>

Based or RB tree.

Signed-off-by: Stanislav Kinsbursky <skinsbursky at openvz.org>
---
 file-ids.c         |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 files.c            |    1 +
 include/file-ids.h |    7 ++++-
 3 files changed, 85 insertions(+), 1 deletions(-)
-------------- next part --------------
diff --git a/file-ids.c b/file-ids.c
index e155c93..0ba9797 100644
--- a/file-ids.c
+++ b/file-ids.c
@@ -76,6 +76,8 @@ struct file_node {
 
 static struct rb_root dump_file_forest[FD_INFO_MAX];
 
+static struct rb_root *restore_file_forest;
+
 static int compare_map_files(pid_t pid1, pid_t pid2, u8 fd1, u8 fd2)
 {
 	return 0;
@@ -197,3 +199,79 @@ long file_collect(pid_t pid, int fd, const struct file_entry *p, u8 *new_entry)
 		return -ENOMEM;
 	return e->u.id;
 }
+
+static struct file_node *file_search_tree(struct rb_root *root, u64 id)
+{
+	struct rb_node *node = root->rb_node;
+
+	while (node) {
+		struct file_node *this = rb_entry(node, struct file_node, node);
+
+		if (id < this->u.id)
+			node = node->rb_left;
+		else if (id > this->u.id)
+			node = node->rb_right;
+		else
+			return this;
+	}
+	return NULL;
+}
+
+struct file_info *file_search(u8 type, u64 id)
+{
+	struct file_node *node;
+
+	BUG_ON(restore_file_forest == NULL);
+	node = file_search_tree(&restore_file_forest[type], id);
+	if (node)
+		return &node->info;
+	return NULL;
+}
+
+int file_add(const struct file_entry *rfe)
+{
+	struct rb_node *node;
+	struct rb_node **new;
+	struct rb_node *parent = NULL;
+	struct rb_root *fd_root;
+	struct file_node *e;
+
+	if (rfe->type >= FD_INFO_MAX)
+		return -ENOTSUP;
+
+	if (restore_file_forest == NULL) {
+		restore_file_forest = xmalloc_shm(sizeof(struct rb_root) * FD_INFO_MAX);
+		if (restore_file_forest == NULL)
+			return -ENOMEM;
+	}
+
+	fd_root = &restore_file_forest[rfe->type];
+	node = fd_root->rb_node;
+	new = &fd_root->rb_node;
+
+	while (node) {
+		struct file_node *this = rb_entry(node, struct file_node, node);
+
+		parent = *new;
+		if (rfe->id < this->u.id)
+			node = node->rb_left, new = &((*new)->rb_left);
+		else if (rfe->id > this->u.id)
+			node = node->rb_right, new = &((*new)->rb_right);
+		else
+			return -EEXIST;
+	}
+
+	e = xmalloc_shm(sizeof(*e));
+	if (!e)
+		return -ENOMEM;
+
+	e->u.id		= rfe->id;
+	e->info.rfe	= rfe;
+	e->info.fd	= FD_ID_INVALID;
+	e->info.pid	= 0;
+	INIT_LIST_HEAD(&e->info.recipients);
+
+	rb_init_node(&e->node);
+	rb_link_and_balance(fd_root, &e->node, parent, new);
+	return 0;
+}
diff --git a/files.c b/files.c
index bacd671..6a18bd6 100644
--- a/files.c
+++ b/files.c
@@ -19,6 +19,7 @@
 #include "util.h"
 #include "util-net.h"
 #include "lock.h"
+#include "file-ids.h"
 
 static struct fdinfo_desc *fdinfo_descs;
 static int nr_fdinfo_descs;
diff --git a/include/file-ids.h b/include/file-ids.h
index 7833ef3..c9d49be 100644
--- a/include/file-ids.h
+++ b/include/file-ids.h
@@ -5,8 +5,9 @@
 #include "types.h"
 #include "rbtree.h"
 #include "image.h"
+#include "list.h"
 
-#define FD_ID_INVALID		(-1UL)
+#define FD_ID_INVALID		(-1U)
 #define FD_PID_INVALID		((int)-2UL)
 
 #define MAKE_FD_GENID(dev, ino, pos) \
@@ -16,8 +17,12 @@ struct file_info {
 	int			fd;
 	int			pid;
 	const struct file_entry	*rfe;
+	struct list_head	recipients;
 };
 
 extern long file_collect(pid_t pid, int fd, const struct file_entry *p, u8 *new_entry);
 
+extern struct file_info *file_search(u8 type, u64 id);
+extern int file_add(const struct file_entry *rfe);
+
 #endif /* FILE_IDS_H__ */


More information about the CRIU mailing list