[CRIU] [PATCH 3/8] core: Move posix timers on core entry
Pavel Emelyanov
xemul at parallels.com
Tue Apr 15 10:59:05 PDT 2014
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: Pavel Emelyanov <xemul at parallels.com>
---
cr-dump.c | 2 +-
cr-restore.c | 31 ++++++++++++++++++-----
include/image-desc.h | 2 +-
include/parasite-syscall.h | 3 ++-
parasite-syscall.c | 61 +++++++++++++++++++++++++++++++---------------
protobuf/timer.proto | 1 +
pstree.c | 2 ++
7 files changed, 73 insertions(+), 29 deletions(-)
diff --git a/cr-dump.c b/cr-dump.c
index 4ae50e8..0f4e983 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -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;
diff --git a/cr-restore.c b/cr-restore.c
index 45fdf69..6536277 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -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;
diff --git a/include/image-desc.h b/include/image-desc.h
index d89081f..b92394f 100644
--- a/include/image-desc.h
+++ b/include/image-desc.h
@@ -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,
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 846c14f..1fdb87b 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -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) \
({ \
diff --git a/parasite-syscall.c b/parasite-syscall.c
index e8ce30b..8250184 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -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;
}
diff --git a/protobuf/timer.proto b/protobuf/timer.proto
index 9c03750..c584dec 100644
--- a/protobuf/timer.proto
+++ b/protobuf/timer.proto
@@ -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;
}
diff --git a/pstree.c b/pstree.c
index c87b5dd..bdbcb63 100644
--- a/pstree.c
+++ b/pstree.c
@@ -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);
}
--
1.8.4.2
More information about the CRIU
mailing list