[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