[CRIU] [PATCH 2/8] core: Move itimers on core

Pavel Emelyanov xemul at parallels.com
Tue Apr 15 10:58:49 PDT 2014


This allows to have one image less per-task, which in turn
reduces live migration time a little bit.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 cr-dump.c                  |  2 +-
 cr-restore.c               | 23 ++++++++++++++++-------
 include/image-desc.h       |  2 +-
 include/parasite-syscall.h |  2 +-
 parasite-syscall.c         | 31 ++++++++++++-------------------
 protobuf/timer.proto       |  3 +++
 pstree.c                   | 12 ++++++++++--
 7 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index 5e3371e..4ae50e8 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1525,7 +1525,7 @@ static int dump_one_task(struct pstree_item *item)
 		goto err_cure;
 	}
 
-	ret = parasite_dump_itimers_seized(parasite_ctl, cr_fdset);
+	ret = parasite_dump_itimers_seized(parasite_ctl, item);
 	if (ret) {
 		pr_err("Can't dump itimers (pid: %d)\n", pid);
 		goto err_cure;
diff --git a/cr-restore.c b/cr-restore.c
index cd2f847..45fdf69 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1694,8 +1694,7 @@ static inline int timeval_valid(struct timeval *tv)
 	return (tv->tv_sec >= 0) && ((unsigned long)tv->tv_usec < USEC_PER_SEC);
 }
 
-static inline int itimer_restore_and_fix(char *n, ItimerEntry *ie,
-		struct itimerval *val)
+static inline int decode_itimer(char *n, ItimerEntry *ie, struct itimerval *val)
 {
 	if (ie->isec == 0 && ie->iusec == 0) {
 		memzero_p(val);
@@ -1734,11 +1733,21 @@ static inline int itimer_restore_and_fix(char *n, ItimerEntry *ie,
 	return 0;
 }
 
-static int prepare_itimers(int pid, struct task_restore_args *args)
+static int prepare_itimers(int pid, CoreEntry *core, struct task_restore_args *args)
 {
 	int fd, ret = -1;
 	ItimerEntry *ie;
 
+	if (core->tc->timers) {
+		TaskTimersEntry *tte = core->tc->timers;
+
+		ret = decode_itimer("real", tte->real, &args->itimers[0]);
+		ret |= decode_itimer("virt", tte->virt, &args->itimers[1]);
+		ret |= decode_itimer("prof", tte->prof, &args->itimers[2]);
+
+		return ret;
+	}
+
 	fd = open_image(CR_FD_ITIMERS, O_RSTR, pid);
 	if (fd < 0)
 		return fd;
@@ -1746,7 +1755,7 @@ static int prepare_itimers(int pid, struct task_restore_args *args)
 	ret = pb_read_one(fd, &ie, PB_ITIMER);
 	if (ret < 0)
 		goto out;
-	ret = itimer_restore_and_fix("real", ie, &args->itimers[0]);
+	ret = decode_itimer("real", ie, &args->itimers[0]);
 	itimer_entry__free_unpacked(ie, NULL);
 	if (ret < 0)
 		goto out;
@@ -1754,7 +1763,7 @@ static int prepare_itimers(int pid, struct task_restore_args *args)
 	ret = pb_read_one(fd, &ie, PB_ITIMER);
 	if (ret < 0)
 		goto out;
-	ret = itimer_restore_and_fix("virt", ie, &args->itimers[1]);
+	ret = decode_itimer("virt", ie, &args->itimers[1]);
 	itimer_entry__free_unpacked(ie, NULL);
 	if (ret < 0)
 		goto out;
@@ -1762,7 +1771,7 @@ static int prepare_itimers(int pid, struct task_restore_args *args)
 	ret = pb_read_one(fd, &ie, PB_ITIMER);
 	if (ret < 0)
 		goto out;
-	ret = itimer_restore_and_fix("prof", ie, &args->itimers[2]);
+	ret = decode_itimer("prof", ie, &args->itimers[2]);
 	itimer_entry__free_unpacked(ie, NULL);
 	if (ret < 0)
 		goto out;
@@ -2488,7 +2497,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
 	/* No longer need it */
 	core_entry__free_unpacked(core, NULL);
 
-	ret = prepare_itimers(pid, task_args);
+	ret = prepare_itimers(pid, core, task_args);
 	if (ret < 0)
 		goto err;
 
diff --git a/include/image-desc.h b/include/image-desc.h
index 84ad2c0..d89081f 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_ITIMERS,
 	CR_FD_POSIX_TIMERS,
 	CR_FD_CREDS,
 	CR_FD_FS,
@@ -86,6 +85,7 @@ enum {
 	CR_FD_PAGES_OLD,
 	CR_FD_SHM_PAGES_OLD,
 	CR_FD_RLIMIT,
+	CR_FD_ITIMERS,
 
 	CR_FD_IRMAP_CACHE,
 
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 023d002..846c14f 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -56,7 +56,7 @@ struct parasite_ctl {
 };
 
 extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset);
-extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset);
+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);
diff --git a/parasite-syscall.c b/parasite-syscall.c
index bb0cf3a..e8ce30b 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -604,22 +604,19 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
 	return 0;
 }
 
-static int dump_one_timer(struct itimerval *v, int fd)
+static void encode_itimer(struct itimerval *v, ItimerEntry *ie)
 {
-	ItimerEntry ie = ITIMER_ENTRY__INIT;
-
-	ie.isec = v->it_interval.tv_sec;
-	ie.iusec = v->it_interval.tv_usec;
-	ie.vsec = v->it_value.tv_sec;
-	ie.vusec = v->it_value.tv_usec;
-
-	return pb_write_one(fd, &ie, PB_ITIMER);
+	ie->isec = v->it_interval.tv_sec;
+	ie->iusec = v->it_interval.tv_usec;
+	ie->vsec = v->it_value.tv_sec;
+	ie->vusec = v->it_value.tv_usec;
 }
 
-int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
+int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *item)
 {
+	CoreEntry *core = item->core[0];
 	struct parasite_dump_itimers_args *args;
-	int ret, fd;
+	int ret;
 
 	args = parasite_args(ctl, struct parasite_dump_itimers_args);
 
@@ -627,15 +624,11 @@ int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
 	if (ret < 0)
 		return ret;
 
-	fd = fdset_fd(cr_fdset, CR_FD_ITIMERS);
-
-	ret = dump_one_timer(&args->real, fd);
-	if (!ret)
-		ret = dump_one_timer(&args->virt, fd);
-	if (!ret)
-		ret = dump_one_timer(&args->prof, fd);
+	encode_itimer(&args->real, core->tc->timers->real);
+	encode_itimer(&args->virt, core->tc->timers->virt);
+	encode_itimer(&args->prof, core->tc->timers->prof);
 
-	return ret;
+	return 0;
 }
 
 static int dump_one_posix_timer(struct posix_timer *v, struct proc_posix_timer *vp, int fd)
diff --git a/protobuf/timer.proto b/protobuf/timer.proto
index b5852c3..9c03750 100644
--- a/protobuf/timer.proto
+++ b/protobuf/timer.proto
@@ -20,4 +20,7 @@ message posix_timer_entry {
 }
 
 message task_timers_entry {
+	required itimer_entry		real	= 1;
+	required itimer_entry		virt	= 2;
+	required itimer_entry		prof	= 3;
 }
diff --git a/pstree.c b/pstree.c
index 33a97a8..c87b5dd 100644
--- a/pstree.c
+++ b/pstree.c
@@ -40,6 +40,7 @@ CoreEntry *core_entry_alloc(int th, int tsk)
 			sz += RLIM_NLIMITS * sizeof(RlimitEntry *);
 			sz += RLIM_NLIMITS * sizeof(RlimitEntry);
 			sz += sizeof(TaskTimersEntry);
+			sz += 3 * sizeof(ItimerEntry); /* 3 for real, virt and prof */
 		}
 	}
 	if (th)
@@ -59,6 +60,7 @@ CoreEntry *core_entry_alloc(int th, int tsk)
 
 			if (th) {
 				TaskRlimitsEntry *rls;
+				TaskTimersEntry *tte;
 				int i;
 
 				rls = xptr_pull(&m, TaskRlimitsEntry);
@@ -73,8 +75,14 @@ CoreEntry *core_entry_alloc(int th, int tsk)
 					rlimit_entry__init(rls->rlimits[i]);
 				}
 
-				core->tc->timers = xptr_pull(&m, TaskTimersEntry);
-				task_timers_entry__init(core->tc->timers);
+				tte = core->tc->timers = xptr_pull(&m, TaskTimersEntry);
+				task_timers_entry__init(tte);
+				tte->real = xptr_pull(&m, ItimerEntry);
+				itimer_entry__init(tte->real);
+				tte->virt = xptr_pull(&m, ItimerEntry);
+				itimer_entry__init(tte->virt);
+				tte->prof = xptr_pull(&m, ItimerEntry);
+				itimer_entry__init(tte->prof);
 			}
 		}
 
-- 
1.8.4.2


More information about the CRIU mailing list