Commit 0a820d8d authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Andrei Vagin

restore: Do not allocate heads for post-prep actions

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: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent d73a08b1
...@@ -531,6 +531,8 @@ typedef struct autofs_info_s { ...@@ -531,6 +531,8 @@ typedef struct autofs_info_s {
AutofsEntry *entry; AutofsEntry *entry;
char *mnt_path; char *mnt_path;
dev_t mnt_dev; dev_t mnt_dev;
struct mount_info *mi;
struct pprep_head ph;
} autofs_info_t; } autofs_info_t;
static int dup_pipe_info(struct pipe_info *pi, int flags, 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, ...@@ -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); 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; autofs_info_t *info = mi->private;
AutofsEntry *entry = info->entry; AutofsEntry *entry = info->entry;
autofs_info_t *i; autofs_info_t *i;
...@@ -1063,11 +1066,11 @@ int autofs_mount(struct mount_info *mi, const char *source, const ...@@ -1063,11 +1066,11 @@ int autofs_mount(struct mount_info *mi, const char *source, const
/* Otherwise we have to add shared object creation callback */ /* Otherwise we have to add shared object creation callback */
if (entry->fd != AUTOFS_CATATONIC_FD) { if (entry->fd != AUTOFS_CATATONIC_FD) {
ret = add_post_prepare_cb(autofs_add_mount_info, mi); info->ph.actor = autofs_add_mount_info;
if (ret < 0) add_post_prepare_cb(&info->ph);
goto free_info;
} }
info->mi = mi;
mi->private = info; mi->private = info;
free_opts: free_opts:
......
...@@ -285,36 +285,22 @@ static struct collect_image_info *before_ns_cinfos[] = { ...@@ -285,36 +285,22 @@ static struct collect_image_info *before_ns_cinfos[] = {
&tty_cdata, &tty_cdata,
}; };
struct post_prepare_cb { static struct pprep_head *post_prepare_heads = NULL;
struct list_head list;
int (*actor)(void *data);
void *data;
};
static struct list_head post_prepare_cbs = LIST_HEAD_INIT(post_prepare_cbs);
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; ph->next = post_prepare_heads;
post_prepare_heads = ph;
cb = xmalloc(sizeof(*cb));
if (!cb)
return -1;
cb->actor = actor;
cb->data = data;
list_add(&cb->list, &post_prepare_cbs);
return 0;
} }
static int run_post_prepare(void) static int run_post_prepare(void)
{ {
struct post_prepare_cb *o; struct pprep_head *ph;
list_for_each_entry(o, &post_prepare_cbs, list) { for (ph = post_prepare_heads; ph != NULL; ph = ph->next)
if (o->actor(o->data)) if (ph->actor(ph))
return -1; return -1;
}
return 0; return 0;
} }
......
...@@ -13,7 +13,11 @@ ...@@ -13,7 +13,11 @@
extern int check_img_inventory(void); extern int check_img_inventory(void);
extern int write_img_inventory(InventoryEntry *he); extern int write_img_inventory(InventoryEntry *he);
extern int prepare_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 bool deprecated_ok(char *what);
extern int cr_dump_tasks(pid_t pid); extern int cr_dump_tasks(pid_t pid);
extern int cr_pre_dump_tasks(pid_t pid); extern int cr_pre_dump_tasks(pid_t pid);
...@@ -25,17 +29,11 @@ extern int cr_dedup(void); ...@@ -25,17 +29,11 @@ extern int cr_dedup(void);
extern int check_add_feature(char *arg); extern int check_add_feature(char *arg);
extern void pr_check_features(const char *offset, const char *sep, int width); extern void pr_check_features(const char *offset, const char *sep, int width);
#define add_post_prepare_cb_once(actor, data) \ #define add_post_prepare_cb_once(phead) do { \
({ \ static int __cb_called = 0; \
static int __cb_called = 0; \ if (!__cb_called) \
int ret = 0; \ add_post_prepare_cb(phead); \
\ __cb_called = 1; \
if (!__cb_called) { \ } while (0)
ret = add_post_prepare_cb(actor, data); \
__cb_called = 1; \
} \
\
ret; \
})
#endif /* __CR_CRTOOLS_H__ */ #endif /* __CR_CRTOOLS_H__ */
...@@ -75,7 +75,7 @@ int do_collect_pipe_data(struct pipe_data_rst *r, ProtobufCMessage *msg, ...@@ -75,7 +75,7 @@ int do_collect_pipe_data(struct pipe_data_rst *r, ProtobufCMessage *msg,
} }
/* Choose who will restore a pipe. */ /* 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); LIST_HEAD(head);
...@@ -141,6 +141,10 @@ static int mark_pipe_master(void *unused) ...@@ -141,6 +141,10 @@ static int mark_pipe_master(void *unused)
return 0; 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]; 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) 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 * ...@@ -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); list_add(&pi->pipe_list, &tmp->pipe_list);
} }
if (add_post_prepare_cb_once(mark_pipe_master, NULL)) add_post_prepare_cb_once(&mark_pipe_master);
return -1;
list_add_tail(&pi->list, &pipes); list_add_tail(&pi->list, &pipes);
return 0; return 0;
......
...@@ -1359,7 +1359,10 @@ static void unlink_stale(struct unix_sk_info *ui) ...@@ -1359,7 +1359,10 @@ static void unlink_stale(struct unix_sk_info *ui)
revert_unix_sk_cwd(&cwd_fd, &root_fd); 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) static int collect_one_unixsk(void *o, ProtobufCMessage *base, struct cr_img *i)
{ {
...@@ -1373,8 +1376,7 @@ static int collect_one_unixsk(void *o, ProtobufCMessage *base, struct cr_img *i) ...@@ -1373,8 +1376,7 @@ static int collect_one_unixsk(void *o, ProtobufCMessage *base, struct cr_img *i)
if (ui->ue->peer && !post_queued) { if (ui->ue->peer && !post_queued) {
post_queued = true; post_queued = true;
if (add_post_prepare_cb(resolve_unix_peers, NULL)) add_post_prepare_cb(&resolve_unix_peers);
return -1;
} }
if (ui->ue->name.len) { if (ui->ue->name.len) {
...@@ -1460,7 +1462,7 @@ static void interconnected_pair(struct unix_sk_info *ui, struct unix_sk_info *pe ...@@ -1460,7 +1462,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; struct unix_sk_info *ui, *peer;
......
...@@ -1559,7 +1559,7 @@ struct collect_image_info tty_info_cinfo = { ...@@ -1559,7 +1559,7 @@ struct collect_image_info tty_info_cinfo = {
.collect = collect_one_tty_info_entry, .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()) if (tty_verify_active_pairs())
return -1; return -1;
...@@ -1568,6 +1568,11 @@ static int prep_tty_restore(void *unused) ...@@ -1568,6 +1568,11 @@ static int prep_tty_restore(void *unused)
return 0; 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) static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i)
{ {
struct tty_info *info = obj; struct tty_info *info = obj;
...@@ -1638,8 +1643,7 @@ static int collect_one_tty(void *obj, ProtobufCMessage *msg, struct cr_img *i) ...@@ -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); pr_info("Collected tty ID %#x (%s)\n", info->tfe->id, info->driver->name);
if (add_post_prepare_cb_once(prep_tty_restore, NULL)) add_post_prepare_cb_once(&prep_tty_restore);
return -1;
/* /*
* Call it explicitly. Post-callbacks will be called after * Call it explicitly. Post-callbacks will be called after
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment