diff --git a/cr-restore.c b/cr-restore.c index eb5d17cb5..1e7549556 100644 --- a/cr-restore.c +++ b/cr-restore.c @@ -2647,9 +2647,6 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) struct vma_area *vma; unsigned long tgt_vmas; - void *timerfd_mem; - unsigned long timerfd_mem_cpos; - #ifdef CONFIG_VDSO unsigned long vdso_rt_size = 0; unsigned long vdso_rt_delta = 0; @@ -2724,11 +2721,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) * Copy timerfd params for restorer args, we need to proceed * timer setting at the very late. */ - timerfd_mem_cpos = rst_mem_cpos(RM_PRIVATE); - timerfd_mem = rst_mem_alloc(rst_timerfd_len(), RM_PRIVATE); - if (!timerfd_mem) + if (rst_timerfd_prep()) goto err_nv; - memcpy(timerfd_mem, rst_timerfd, rst_timerfd_len()); /* * We're about to search for free VM area and inject the restorer blob @@ -2876,7 +2870,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) remap_array(vmas, vmas->nr, tgt_vmas); remap_array(posix_timers, posix_timers_nr, posix_timers_cpos); - remap_array(timerfd, rst_timerfd_nr, timerfd_mem_cpos); + remap_array(timerfd, rst_timerfd_nr, rst_timerfd_cpos); remap_array(siginfo, siginfo_nr, siginfo_cpos); remap_array(tcp_socks, rst_tcp_socks_nr, rst_tcp_socks_cpos); remap_array(rings, mm->n_aios, aio_rings); diff --git a/include/timerfd.h b/include/timerfd.h index 89525dc07..67b918717 100644 --- a/include/timerfd.h +++ b/include/timerfd.h @@ -19,13 +19,11 @@ struct restore_timerfd { extern const struct fdtype_ops timerfd_dump_ops; extern struct collect_image_info timerfd_cinfo; -extern struct restore_timerfd *rst_timerfd; + +int rst_timerfd_prep(void); +extern unsigned long rst_timerfd_cpos; extern unsigned int rst_timerfd_nr; -static inline unsigned long rst_timerfd_len(void) -{ - return sizeof(*rst_timerfd) * rst_timerfd_nr; -} extern int check_timerfd(void); extern int is_timerfd_link(char *link); diff --git a/timerfd.c b/timerfd.c index cd15c0963..79ddb2b80 100644 --- a/timerfd.c +++ b/timerfd.c @@ -31,10 +31,14 @@ struct timerfd_dump_arg { struct timerfd_info { TimerfdEntry *tfe; struct file_desc d; + int t_fd; + struct list_head rlist; }; -struct restore_timerfd *rst_timerfd; -unsigned int rst_timerfd_nr; +static LIST_HEAD(rst_timerfds); + +unsigned long rst_timerfd_cpos; +unsigned int rst_timerfd_nr = 0; int check_timerfd(void) { @@ -105,24 +109,37 @@ const struct fdtype_ops timerfd_dump_ops = { static int timerfd_post_open(struct file_desc *d, int fd) { struct timerfd_info *info = container_of(d, struct timerfd_info, d); - TimerfdEntry *tfe = info->tfe; + + info->t_fd = fd; + list_add_tail(&info->rlist, &rst_timerfds); + return 0; +} + +int rst_timerfd_prep(void) +{ + struct timerfd_info *ti; struct restore_timerfd *t; - rst_timerfd_nr++; - rst_timerfd = xrealloc(rst_timerfd, rst_timerfd_len()); - if (!rst_timerfd) - return -ENOMEM; + rst_timerfd_cpos = rst_mem_cpos(RM_PRIVATE); + list_for_each_entry(ti, &rst_timerfds, rlist) { + TimerfdEntry *tfe = ti->tfe; - t = &rst_timerfd[rst_timerfd_nr - 1]; - t->id = tfe->id; - t->fd = fd; - t->clockid = tfe->clockid; - t->ticks = (unsigned long)tfe->ticks; - t->settime_flags = tfe->settime_flags; - t->val.it_interval.tv_sec = (time_t)tfe->isec; - t->val.it_interval.tv_nsec = (long)tfe->insec; - t->val.it_value.tv_sec = (time_t)tfe->vsec; - t->val.it_value.tv_nsec = (long)tfe->vnsec; + t = rst_mem_alloc(sizeof(*t), RM_PRIVATE); + if (!t) + return -1; + + t->id = tfe->id; + t->fd = ti->t_fd; + t->clockid = tfe->clockid; + t->ticks = (unsigned long)tfe->ticks; + t->settime_flags = tfe->settime_flags; + t->val.it_interval.tv_sec = (time_t)tfe->isec; + t->val.it_interval.tv_nsec = (long)tfe->insec; + t->val.it_value.tv_sec = (time_t)tfe->vsec; + t->val.it_value.tv_nsec = (long)tfe->vnsec; + + rst_timerfd_nr++; + } return 0; } @@ -186,6 +203,8 @@ static int collect_one_timerfd(void *o, ProtobufCMessage *msg) return -1; } + info->t_fd = -1; + return file_desc_add(&info->d, info->tfe->id, &timerfd_desc_ops); }