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 {
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:
......
......@@ -285,36 +285,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;
}
......
......@@ -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);
......@@ -25,17 +29,11 @@ extern int cr_dedup(void);
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__ */
......@@ -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;
......
......@@ -1359,7 +1359,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)
{
......@@ -1373,8 +1376,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) {
......@@ -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;
......
......@@ -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
......
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