[CRIU] [PATCH 06/12] posix-timer: Add dump functionality

Pavel Tikhomirov snorcht at gmail.com
Thu Jun 27 12:32:22 EDT 2013


Signed-off-by: Pavel Tikhomirov <snorcht at gmail.com>
---
 cr-dump.c                  |   17 +++++++++--
 include/parasite-syscall.h |    6 +++-
 parasite-syscall.c         |   69 ++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 86 insertions(+), 6 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index 6ea17a7..003724b 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1328,7 +1328,7 @@ static int pre_dump_one_task(struct pstree_item *item, struct list_head *ctls)
 	}
 
 	ret = -1;
-	parasite_ctl = parasite_infect_seized(pid, item, &vmas, NULL);
+	parasite_ctl = parasite_infect_seized(pid, item, &vmas, NULL, 0);
 	if (!parasite_ctl) {
 		pr_err("Can't infect (pid: %d) with parasite\n", pid);
 		goto err_free;
@@ -1369,6 +1369,7 @@ static int dump_one_task(struct pstree_item *item)
 	struct parasite_dump_misc misc;
 	struct cr_fdset *cr_fdset = NULL;
 	struct parasite_drain_fd *dfds;
+	struct proc_posix_timers_stat proc_args;
 
 	pr_info("========================================\n");
 	pr_info("Dumping task (pid: %d)\n", pid);
@@ -1403,8 +1404,14 @@ static int dump_one_task(struct pstree_item *item)
 		goto err;
 	}
 
+	ret = parse_posix_timers(pid, &proc_args);
+	if (ret < 0){
+		pr_err("Can't read posix timers file (pid: %d)\n", pid);
+		goto err;
+	}
+
 	ret = -1;
-	parasite_ctl = parasite_infect_seized(pid, item, &vmas, dfds);
+	parasite_ctl = parasite_infect_seized(pid, item, &vmas, dfds, proc_args.timer_n);
 	if (!parasite_ctl) {
 		pr_err("Can't infect (pid: %d) with parasite\n", pid);
 		goto err;
@@ -1488,6 +1495,12 @@ static int dump_one_task(struct pstree_item *item)
 		goto err_cure;
 	}
 
+	ret = parasite_dump_posix_timers_seized(&proc_args, parasite_ctl, cr_fdset);
+	if (ret) {
+		pr_err("Can't dump posix timers (pid: %d)\n", pid);
+		goto err_cure;
+	}
+
 	ret = dump_task_core_all(parasite_ctl, item->core[0], &pps_buf, &misc, &vmas, cr_fdset);
 	if (ret) {
 		pr_err("Dump core (pid: %d) failed with %d\n", pid, ret);
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 9b6937a..3157e27 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -53,6 +53,9 @@ 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);
 
+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);
+
 #define parasite_args(ctl, type)					\
 	({								\
 		BUILD_BUG_ON(sizeof(type) > PARASITE_ARG_SIZE_MIN);	\
@@ -83,7 +86,8 @@ extern int parasite_cure_seized(struct parasite_ctl *ctl);
 extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
 						   struct pstree_item *item,
 						   struct vm_area_list *vma_area_list,
-						   struct parasite_drain_fd *dfds);
+						   struct parasite_drain_fd *dfds,
+						   int timer_n);
 extern struct parasite_ctl *parasite_prep_ctl(pid_t pid,
 					      struct vm_area_list *vma_area_list);
 extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size);
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 0fb9b5a..90a8a29 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -26,6 +26,7 @@
 #include "mem.h"
 #include "vdso.h"
 #include "restorer.h"
+#include "proc_parse.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -590,6 +591,65 @@ int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
 	return ret;
 }
 
+static int dump_one_posix_timer(struct posix_timer *v, struct proc_posix_timer *vp, int fd)
+{
+	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 = (long unsigned int)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;
+
+	return pb_write_one(fd, &pte, PB_POSIX_TIMERS);
+}
+
+int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args, struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
+{
+	struct parasite_dump_posix_timers_args * args;
+	struct proc_posix_timer *temp;
+	int i, fd;
+	int ret = 0;
+
+	args = parasite_args_s(ctl, posix_timers_dump_size(proc_args->timer_n));
+	args->timer_n = proc_args->timer_n;
+
+	i = 0;
+	list_for_each_entry(temp, &proc_args->timers, list) {
+		args->timer[i].it_id = temp->spt.it_id;
+		i++;
+	}
+
+	ret = parasite_execute_daemon(PARASITE_CMD_DUMP_POSIX_TIMERS, ctl);
+	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);
+		i++;
+		if (ret)
+			goto end_posix;
+	}
+
+end_posix:
+	while (!list_empty(&proc_args->timers)) {
+		temp = list_first_entry(&proc_args->timers, struct proc_posix_timer, list);
+		list_del(&temp->list);
+		xfree(temp);
+	}
+	return ret;
+}
+
 int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_misc *misc)
 {
 	struct parasite_dump_misc *ma;
@@ -940,19 +1000,22 @@ int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size)
 	return 0;
 }
 
-static unsigned long parasite_args_size(struct vm_area_list *vmas, struct parasite_drain_fd *dfds)
+static unsigned long parasite_args_size(struct vm_area_list *vmas, struct parasite_drain_fd *dfds, int timer_n)
 {
 	unsigned long size = PARASITE_ARG_SIZE_MIN;
 
 	if (dfds)
 		size = max(size, (unsigned long)drain_fds_size(dfds));
+	if (timer_n)
+		size = max(size, (unsigned long)posix_timers_dump_size(timer_n));
 	size = max(size, (unsigned long)dump_pages_args_size(vmas));
 
 	return round_up(size, PAGE_SIZE);
 }
 
 struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
-		struct vm_area_list *vma_area_list, struct parasite_drain_fd *dfds)
+		struct vm_area_list *vma_area_list, struct parasite_drain_fd *dfds,
+		int timer_n)
 {
 	int ret;
 	struct parasite_ctl *ctl;
@@ -974,7 +1037,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 	 * without using ptrace at all.
 	 */
 
-	ctl->args_size = parasite_args_size(vma_area_list, dfds);
+	ctl->args_size = parasite_args_size(vma_area_list, dfds, timer_n);
 	map_exchange_size = parasite_size + ctl->args_size;
 	map_exchange_size += RESTORE_STACK_SIGFRAME + PARASITE_STACK_SIZE;
 	if (item->nr_threads > 1)
-- 
1.7.9.5



More information about the CRIU mailing list