[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