Commit 9a9424ee authored by Pavel Tikhomirov's avatar Pavel Tikhomirov Committed by Pavel Emelyanov

posix-timer: Add dump functionality

Signed-off-by: 's avatarPavel Tikhomirov <snorcht@gmail.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 335a158e
......@@ -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);
......
......@@ -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);
......
......@@ -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 = 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;
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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment