[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