Commit b54e3409 authored by Pavel Emelyanov's avatar Pavel Emelyanov

core: Move posix timers on core entry

This as well gives us minus one image per-task and
allocates more space on core task entry.

One thing to note -- the amount of posix timers is
not easily accessible at the core entry allocation
time, so the respective array is allocated on demand.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent dfd5a62f
......@@ -1531,7 +1531,7 @@ static int dump_one_task(struct pstree_item *item)
goto err_cure;
}
ret = parasite_dump_posix_timers_seized(&proc_args, parasite_ctl, cr_fdset);
ret = parasite_dump_posix_timers_seized(&proc_args, parasite_ctl, item);
if (ret) {
pr_err("Can't dump posix timers (pid: %d)\n", pid);
goto err_cure;
......
......@@ -87,7 +87,7 @@ static int restore_task_with_children(void *);
static int sigreturn_restore(pid_t pid, CoreEntry *core);
static int prepare_restorer_blob(void);
static int prepare_rlimits(int pid, CoreEntry *core);
static int prepare_posix_timers(int pid);
static int prepare_posix_timers(int pid, CoreEntry *core);
static int prepare_signals(int pid);
static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
......@@ -713,7 +713,7 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
if (prepare_signals(pid))
return -1;
if (prepare_posix_timers(pid))
if (prepare_posix_timers(pid, core))
return -1;
if (prepare_rlimits(pid, core) < 0)
......@@ -1785,7 +1785,7 @@ static inline int timespec_valid(struct timespec *ts)
return (ts->tv_sec >= 0) && ((unsigned long)ts->tv_nsec < NSEC_PER_SEC);
}
static inline int posix_timer_restore_and_fix(PosixTimerEntry *pte,
static inline int decode_posix_timer(PosixTimerEntry *pte,
struct restore_posix_timer *pt)
{
pt->val.it_interval.tv_sec = pte->isec;
......@@ -1829,13 +1829,32 @@ static int cmp_posix_timer_proc_id(const void *p1, const void *p2)
static unsigned long posix_timers_cpos;
static unsigned int posix_timers_nr;
static int prepare_posix_timers(int pid)
static int prepare_posix_timers(int pid, CoreEntry *core)
{
int fd;
int fd = -1;
int ret = -1;
struct restore_posix_timer *t;
posix_timers_cpos = rst_mem_cpos(RM_PRIVATE);
if (core->tc->timers) {
int i;
TaskTimersEntry *tte = core->tc->timers;
posix_timers_nr = tte->n_posix;
for (i = 0; i < posix_timers_nr; i++) {
t = rst_mem_alloc(sizeof(struct restore_posix_timer), RM_PRIVATE);
if (!t)
goto out;
if (decode_posix_timer(tte->posix[i], t))
goto out;
}
ret = 0;
goto out;
}
fd = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid);
if (fd < 0) {
if (errno == ENOENT) /* backward compatibility */
......@@ -1856,7 +1875,7 @@ static int prepare_posix_timers(int pid)
if (!t)
goto out;
ret = posix_timer_restore_and_fix(pte, t);
ret = decode_posix_timer(pte, t);
if (ret < 0)
goto out;
......
......@@ -16,7 +16,6 @@ enum {
CR_FD_IDS,
CR_FD_MM,
CR_FD_SIGACT,
CR_FD_POSIX_TIMERS,
CR_FD_CREDS,
CR_FD_FS,
CR_FD_SIGNAL,
......@@ -86,6 +85,7 @@ enum {
CR_FD_SHM_PAGES_OLD,
CR_FD_RLIMIT,
CR_FD_ITIMERS,
CR_FD_POSIX_TIMERS,
CR_FD_IRMAP_CACHE,
......
......@@ -59,7 +59,8 @@ extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdse
extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *);
struct proc_posix_timers_stat;
extern int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args, struct parasite_ctl *ctl, struct cr_fdset *cr_fdset);
extern int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args,
struct parasite_ctl *ctl, struct pstree_item *);
#define parasite_args(ctl, type) \
({ \
......
......@@ -631,33 +631,55 @@ int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *i
return 0;
}
static int dump_one_posix_timer(struct posix_timer *v, struct proc_posix_timer *vp, int fd)
static void encode_posix_timer(struct posix_timer *v, struct proc_posix_timer *vp, PosixTimerEntry *pte)
{
PosixTimerEntry pte = POSIX_TIMER_ENTRY__INIT;
pte->it_id = vp->spt.it_id;
pte->clock_id = vp->spt.clock_id;
pte->si_signo = vp->spt.si_signo;
pte->it_sigev_notify = vp->spt.it_sigev_notify;
pte->sival_ptr = encode_pointer(vp->spt.sival_ptr);
pte->overrun = v->overrun;
pte->isec = v->val.it_interval.tv_sec;
pte->insec = v->val.it_interval.tv_nsec;
pte->vsec = v->val.it_value.tv_sec;
pte->vnsec = v->val.it_value.tv_nsec;
}
pte.it_id = vp->spt.it_id;
pte.clock_id = vp->spt.clock_id;
pte.si_signo = vp->spt.si_signo;
pte.it_sigev_notify = vp->spt.it_sigev_notify;
pte.sival_ptr = encode_pointer(vp->spt.sival_ptr);
static int core_alloc_posix_timers(TaskTimersEntry *tte, int n,
PosixTimerEntry **pte)
{
int sz;
pte.overrun = v->overrun;
/*
* Will be free()-ed in core_entry_free()
*/
pte.isec = v->val.it_interval.tv_sec;
pte.insec = v->val.it_interval.tv_nsec;
pte.vsec = v->val.it_value.tv_sec;
pte.vnsec = v->val.it_value.tv_nsec;
sz = n * (sizeof(PosixTimerEntry *) + sizeof(PosixTimerEntry));
tte->posix = xmalloc(sz);
if (!tte->posix)
return -1;
return pb_write_one(fd, &pte, PB_POSIX_TIMER);
tte->n_posix = n;
*pte = (PosixTimerEntry *)(tte->posix + n);
return 0;
}
int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args, struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args,
struct parasite_ctl *ctl, struct pstree_item *item)
{
CoreEntry *core = item->core[0];
TaskTimersEntry *tte = core->tc->timers;
PosixTimerEntry *pte;
struct parasite_dump_posix_timers_args * args;
struct proc_posix_timer *temp;
int i, fd;
int i;
int ret = 0;
if (core_alloc_posix_timers(tte, proc_args->timer_n, &pte))
return -1;
args = parasite_args_s(ctl, posix_timers_dump_size(proc_args->timer_n));
args->timer_n = proc_args->timer_n;
......@@ -671,14 +693,12 @@ int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args,
if (ret < 0)
goto end_posix;
fd = fdset_fd(cr_fdset, CR_FD_POSIX_TIMERS);
i = 0;
list_for_each_entry(temp, &proc_args->timers, list) {
ret = dump_one_posix_timer(&args->timer[i], temp, fd);
posix_timer_entry__init(&pte[i]);
encode_posix_timer(&args->timer[i], temp, &pte[i]);
tte->posix[i] = &pte[i];
i++;
if (ret)
goto end_posix;
}
end_posix:
......@@ -687,6 +707,7 @@ end_posix:
list_del(&temp->list);
xfree(temp);
}
return ret;
}
......
......@@ -23,4 +23,5 @@ message task_timers_entry {
required itimer_entry real = 1;
required itimer_entry virt = 2;
required itimer_entry prof = 3;
repeated posix_timer_entry posix = 4;
}
......@@ -18,6 +18,8 @@ struct pstree_item *root_item;
void core_entry_free(CoreEntry *core)
{
if (core->tc && core->tc->timers)
xfree(core->tc->timers->posix);
arch_free_thread_info(core);
xfree(core);
}
......
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