[CRIU] [PATCH 1/5] restore: Do not allocate heads for post-prep actions

Pavel Emelyanov xemul at virtuozzo.com
Fri May 26 05:44:42 PDT 2017


Now the post-prep actions are xmalloc()-ed then added to the list.
Let's make it sit right on the structures that need the post-prep,
this would make some things much simpler and nicer soon.

The approach is inspired by kernel rcu_head-s :)

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/autofs.c          | 13 ++++++++-----
 criu/cr-restore.c      | 30 ++++++++----------------------
 criu/include/crtools.h | 24 +++++++++++-------------
 criu/pipes.c           | 10 ++++++----
 criu/sk-unix.c         | 10 ++++++----
 criu/tty.c             | 10 +++++++---
 6 files changed, 46 insertions(+), 51 deletions(-)

diff --git a/criu/autofs.c b/criu/autofs.c
index 15b0fc4..ad1e4c3 100644
--- a/criu/autofs.c
+++ b/criu/autofs.c
@@ -531,6 +531,8 @@ typedef struct autofs_info_s {
 	AutofsEntry *entry;
 	char *mnt_path;
 	dev_t mnt_dev;
+	struct mount_info *mi;
+	struct pprep_head ph;
 } autofs_info_t;
 
 static int dup_pipe_info(struct pipe_info *pi, int flags,
@@ -927,9 +929,10 @@ static int autofs_create_pipe(struct pstree_item *task, autofs_info_t *i,
 	return autofs_create_fle(task, fe, &i->pi.d);
 }
 
-static int autofs_add_mount_info(void *data)
+static int autofs_add_mount_info(struct pprep_head *ph)
 {
-	struct mount_info *mi = data;
+	autofs_info_t *ai = container_of(ph, autofs_info_t, ph);
+	struct mount_info *mi = ai->mi;
 	autofs_info_t *info = mi->private;
 	AutofsEntry *entry = info->entry;
 	autofs_info_t *i;
@@ -1063,11 +1066,11 @@ int autofs_mount(struct mount_info *mi, const char *source, const
 
 	/* Otherwise we have to add shared object creation callback */
 	if (entry->fd != AUTOFS_CATATONIC_FD) {
-		ret = add_post_prepare_cb(autofs_add_mount_info, mi);
-		if (ret < 0)
-			goto free_info;
+		info->ph.actor = autofs_add_mount_info;
+		add_post_prepare_cb(&info->ph);
 	}
 
+	info->mi = mi;
 	mi->private = info;
 
 free_opts:
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 21ba39e..0aef6e6 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -287,36 +287,22 @@ static struct collect_image_info *before_ns_cinfos[] = {
 	&tty_cdata,
 };
 
-struct post_prepare_cb {
-	struct list_head list;
-	int (*actor)(void *data);
-	void *data;
-};
-
-static struct list_head post_prepare_cbs = LIST_HEAD_INIT(post_prepare_cbs);
+static struct pprep_head *post_prepare_heads = NULL;
 
-int add_post_prepare_cb(int (*actor)(void *data), void *data)
+void add_post_prepare_cb(struct pprep_head *ph)
 {
-	struct post_prepare_cb *cb;
-
-	cb = xmalloc(sizeof(*cb));
-	if (!cb)
-		return -1;
-
-	cb->actor = actor;
-	cb->data = data;
-	list_add(&cb->list, &post_prepare_cbs);
-	return 0;
+	ph->next = post_prepare_heads;
+	post_prepare_heads = ph;
 }
 
 static int run_post_prepare(void)
 {
-	struct post_prepare_cb *o;
+	struct pprep_head *ph;
 
-	list_for_each_entry(o, &post_prepare_cbs, list) {
-		if (o->actor(o->data))
+	for (ph = post_prepare_heads; ph != NULL; ph = ph->next)
+		if (ph->actor(ph))
 			return -1;
-	}
+
 	return 0;
 }
 
diff --git a/criu/include/crtools.h b/criu/include/crtools.h
index 63164bc..02059cb 100644
--- a/criu/include/crtools.h
+++ b/criu/include/crtools.h
@@ -13,7 +13,11 @@
 extern int check_img_inventory(void);
 extern int write_img_inventory(InventoryEntry *he);
 extern int prepare_inventory(InventoryEntry *he);
-extern int add_post_prepare_cb(int (*actor)(void *data), void *data);
+struct pprep_head {
+	int (*actor)(struct pprep_head *);
+	struct pprep_head *next;
+};
+extern void add_post_prepare_cb(struct pprep_head *);
 extern bool deprecated_ok(char *what);
 extern int cr_dump_tasks(pid_t pid);
 extern int cr_pre_dump_tasks(pid_t pid);
@@ -26,17 +30,11 @@ extern int cr_lazy_pages(bool daemon);
 extern int check_add_feature(char *arg);
 extern void pr_check_features(const char *offset, const char *sep, int width);
 
-#define add_post_prepare_cb_once(actor, data)			\
-	({							\
-		static int __cb_called = 0;			\
-		int ret = 0;					\
-								\
-		if (!__cb_called) {				\
-			ret = add_post_prepare_cb(actor, data);	\
-			__cb_called = 1;			\
-		}						\
-								\
-		ret;						\
-	})
+#define add_post_prepare_cb_once(phead) do {		\
+		static int __cb_called = 0;		\
+		if (!__cb_called)			\
+			add_post_prepare_cb(phead);	\
+		__cb_called = 1;			\
+	} while (0)
 
 #endif /* __CR_CRTOOLS_H__ */
diff --git a/criu/pipes.c b/criu/pipes.c
index 8b3fd6f..c20fc61 100644
--- a/criu/pipes.c
+++ b/criu/pipes.c
@@ -75,7 +75,7 @@ int do_collect_pipe_data(struct pipe_data_rst *r, ProtobufCMessage *msg,
 }
 
 /* Choose who will restore a pipe. */
-static int mark_pipe_master(void *unused)
+static int mark_pipe_master_cb(struct pprep_head *ph)
 {
 	LIST_HEAD(head);
 
@@ -141,6 +141,10 @@ static int mark_pipe_master(void *unused)
 	return 0;
 }
 
+static struct pprep_head mark_pipe_master = {
+	.actor = mark_pipe_master_cb,
+};
+
 static struct pipe_data_rst *pd_hash_pipes[PIPE_DATA_HASH_SIZE];
 
 int restore_pipe_data(int img_type, int pfd, u32 id, struct pipe_data_rst **hash)
@@ -372,9 +376,7 @@ int collect_one_pipe_ops(void *o, ProtobufCMessage *base, struct file_desc_ops *
 			list_add(&pi->pipe_list, &tmp->pipe_list);
 	}
 
-	if (add_post_prepare_cb_once(mark_pipe_master, NULL))
-		return -1;
-
+	add_post_prepare_cb_once(&mark_pipe_master);
 	list_add_tail(&pi->list, &pipes);
 
 	return 0;
diff --git a/criu/sk-unix.c b/criu/sk-unix.c
index e051179..866e3c0 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -1375,7 +1375,10 @@ static void unlink_stale(struct unix_sk_info *ui)
 	revert_unix_sk_cwd(&cwd_fd, &root_fd);
 }
 
-static int resolve_unix_peers(void *unused);
+static int resolve_unix_peers_cb(struct pprep_head *ph);
+static struct pprep_head resolve_unix_peers = {
+	.actor = resolve_unix_peers_cb,
+};
 
 static int collect_one_unixsk(void *o, ProtobufCMessage *base, struct cr_img *i)
 {
@@ -1389,8 +1392,7 @@ static int collect_one_unixsk(void *o, ProtobufCMessage *base, struct cr_img *i)
 
 	if (ui->ue->peer && !post_queued) {
 		post_queued = true;
-		if (add_post_prepare_cb(resolve_unix_peers, NULL))
-			return -1;
+		add_post_prepare_cb(&resolve_unix_peers);
 	}
 
 	if (ui->ue->name.len) {
@@ -1476,7 +1478,7 @@ static void interconnected_pair(struct unix_sk_info *ui, struct unix_sk_info *pe
 	}
 }
 
-static int resolve_unix_peers(void *unused)
+static int resolve_unix_peers_cb(struct pprep_head *ph)
 {
 	struct unix_sk_info *ui, *peer;
 
diff --git a/criu/tty.c b/criu/tty.c
index cf21cbd..624e3ff 100644
--- a/criu/tty.c
+++ b/criu/tty.c
@@ -1559,7 +1559,7 @@ struct collect_image_info tty_info_cinfo = {
 	.collect	= collect_one_tty_info_entry,
 };
 
-static int prep_tty_restore(void *unused)
+static int prep_tty_restore_cb(struct pprep_head *ph)
 {
 	if (tty_verify_active_pairs())
 		return -1;
@@ -1568,6 +1568,11 @@ static int prep_tty_restore(void *unused)
 	return 0;
 }
 
+static struct pprep_head prep_tty_restore = {
+	.actor = prep_tty_restore_cb,,
+};
+
+
 static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i)
 {
 	struct tty_info *info = obj;
@@ -1638,8 +1643,7 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i)
 
 	pr_info("Collected tty ID %#x (%s)\n", info->tfe->id, info->driver->name);
 
-	if (add_post_prepare_cb_once(prep_tty_restore, NULL))
-		return -1;
+	add_post_prepare_cb_once(&prep_tty_restore);
 
 	/*
 	 * Call it explicitly. Post-callbacks will be called after
-- 
2.1.4



More information about the CRIU mailing list