2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-22 01:51:51 +00:00

criu: move timers dump/restore code into separate file

Fixes: #335

Signed-off-by: ccccrrrr <zcr1006@gmail.com>
This commit is contained in:
ccccrrrr 2024-02-29 16:02:06 +08:00 committed by Andrei Vagin
parent 231ba0cd29
commit 52623cca16
7 changed files with 419 additions and 396 deletions

View File

@ -92,6 +92,7 @@ obj-y += servicefd.o
obj-y += pie-util-vdso.o
obj-y += vdso.o
obj-y += timens.o
obj-y += timer.o
obj-$(CONFIG_HAS_LIBBPF) += bpfmap.o
obj-$(CONFIG_COMPAT) += pie-util-vdso-elf32.o
CFLAGS_pie-util-vdso-elf32.o += -DCONFIG_VDSO_32

View File

@ -86,6 +86,7 @@
#include "pidfd-store.h"
#include "apparmor.h"
#include "asm/dump.h"
#include "timer.h"
/*
* Architectures can overwrite this function to restore register sets that

View File

@ -98,6 +98,7 @@
#include "restore.h"
#include "cr-errno.h"
#include "timer.h"
#ifndef arch_export_restore_thread
#define arch_export_restore_thread __export_restore_thread
@ -118,7 +119,6 @@ static int restore_task_with_children(void *);
static int sigreturn_restore(pid_t pid, struct task_restore_args *ta, unsigned long alen, CoreEntry *core);
static int prepare_restorer_blob(void);
static int prepare_rlimits(int pid, struct task_restore_args *, CoreEntry *core);
static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);
static int prepare_signals(int pid, struct task_restore_args *, CoreEntry *core);
/*
@ -882,7 +882,6 @@ static int prepare_proc_misc(pid_t pid, TaskCoreEntry *tc, struct task_restore_a
return 0;
}
static int prepare_itimers(int pid, struct task_restore_args *args, CoreEntry *core);
static int prepare_mm(pid_t pid, struct task_restore_args *args);
static int restore_one_alive_task(int pid, CoreEntry *core)
@ -2719,245 +2718,6 @@ static long restorer_get_vma_hint(struct list_head *tgt_vma_list, struct list_he
return -1;
}
static inline int timeval_valid(struct timeval *tv)
{
return (tv->tv_sec >= 0) && ((unsigned long)tv->tv_usec < USEC_PER_SEC);
}
static inline int decode_itimer(char *n, ItimerEntry *ie, struct itimerval *val)
{
if (ie->isec == 0 && ie->iusec == 0) {
memzero_p(val);
return 0;
}
val->it_interval.tv_sec = ie->isec;
val->it_interval.tv_usec = ie->iusec;
if (!timeval_valid(&val->it_interval)) {
pr_err("Invalid timer interval\n");
return -1;
}
if (ie->vsec == 0 && ie->vusec == 0) {
/*
* Remaining time was too short. Set it to
* interval to make the timer armed and work.
*/
val->it_value.tv_sec = ie->isec;
val->it_value.tv_usec = ie->iusec;
} else {
val->it_value.tv_sec = ie->vsec;
val->it_value.tv_usec = ie->vusec;
}
if (!timeval_valid(&val->it_value)) {
pr_err("Invalid timer value\n");
return -1;
}
pr_info("Restored %s timer to %ld.%ld -> %ld.%ld\n", n, val->it_value.tv_sec, val->it_value.tv_usec,
val->it_interval.tv_sec, val->it_interval.tv_usec);
return 0;
}
/*
* Legacy itimers restore from CR_FD_ITIMERS
*/
static int prepare_itimers_from_fd(int pid, struct task_restore_args *args)
{
int ret = -1;
struct cr_img *img;
ItimerEntry *ie;
if (!deprecated_ok("Itimers"))
return -1;
img = open_image(CR_FD_ITIMERS, O_RSTR, pid);
if (!img)
return -1;
ret = pb_read_one(img, &ie, PB_ITIMER);
if (ret < 0)
goto out;
ret = decode_itimer("real", ie, &args->itimers[0]);
itimer_entry__free_unpacked(ie, NULL);
if (ret < 0)
goto out;
ret = pb_read_one(img, &ie, PB_ITIMER);
if (ret < 0)
goto out;
ret = decode_itimer("virt", ie, &args->itimers[1]);
itimer_entry__free_unpacked(ie, NULL);
if (ret < 0)
goto out;
ret = pb_read_one(img, &ie, PB_ITIMER);
if (ret < 0)
goto out;
ret = decode_itimer("prof", ie, &args->itimers[2]);
itimer_entry__free_unpacked(ie, NULL);
if (ret < 0)
goto out;
out:
close_image(img);
return ret;
}
static int prepare_itimers(int pid, struct task_restore_args *args, CoreEntry *core)
{
int ret = 0;
TaskTimersEntry *tte = core->tc->timers;
if (!tte)
return prepare_itimers_from_fd(pid, args);
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;
}
static inline int timespec_valid(struct timespec *ts)
{
return (ts->tv_sec >= 0) && ((unsigned long)ts->tv_nsec < NSEC_PER_SEC);
}
static inline int decode_posix_timer(PosixTimerEntry *pte, struct restore_posix_timer *pt)
{
pt->val.it_interval.tv_sec = pte->isec;
pt->val.it_interval.tv_nsec = pte->insec;
if (!timespec_valid(&pt->val.it_interval)) {
pr_err("Invalid timer interval(posix)\n");
return -1;
}
if (pte->vsec == 0 && pte->vnsec == 0) {
/*
* Remaining time was too short. Set it to
* interval to make the timer armed and work.
*/
pt->val.it_value.tv_sec = pte->isec;
pt->val.it_value.tv_nsec = pte->insec;
} else {
pt->val.it_value.tv_sec = pte->vsec;
pt->val.it_value.tv_nsec = pte->vnsec;
}
if (!timespec_valid(&pt->val.it_value)) {
pr_err("Invalid timer value(posix)\n");
return -1;
}
pt->spt.it_id = pte->it_id;
pt->spt.clock_id = pte->clock_id;
pt->spt.si_signo = pte->si_signo;
pt->spt.it_sigev_notify = pte->it_sigev_notify;
pt->spt.sival_ptr = decode_pointer(pte->sival_ptr);
pt->spt.notify_thread_id = pte->notify_thread_id;
pt->overrun = pte->overrun;
return 0;
}
static int cmp_posix_timer_proc_id(const void *p1, const void *p2)
{
return ((struct restore_posix_timer *)p1)->spt.it_id - ((struct restore_posix_timer *)p2)->spt.it_id;
}
static void sort_posix_timers(struct task_restore_args *ta)
{
void *tmem;
/*
* This is required for restorer's create_posix_timers(),
* it will probe them one-by-one for the desired ID, since
* kernel doesn't provide another API for timer creation
* with given ID.
*/
if (ta->posix_timers_n > 0) {
tmem = rst_mem_remap_ptr((unsigned long)ta->posix_timers, RM_PRIVATE);
qsort(tmem, ta->posix_timers_n, sizeof(struct restore_posix_timer), cmp_posix_timer_proc_id);
}
}
/*
* Legacy posix timers restoration from CR_FD_POSIX_TIMERS
*/
static int prepare_posix_timers_from_fd(int pid, struct task_restore_args *ta)
{
struct cr_img *img;
int ret = -1;
struct restore_posix_timer *t;
if (!deprecated_ok("Posix timers"))
return -1;
img = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid);
if (!img)
return -1;
ta->posix_timers_n = 0;
while (1) {
PosixTimerEntry *pte;
ret = pb_read_one_eof(img, &pte, PB_POSIX_TIMER);
if (ret <= 0)
break;
t = rst_mem_alloc(sizeof(struct restore_posix_timer), RM_PRIVATE);
if (!t)
break;
ret = decode_posix_timer(pte, t);
if (ret < 0)
break;
posix_timer_entry__free_unpacked(pte, NULL);
ta->posix_timers_n++;
}
close_image(img);
if (!ret)
sort_posix_timers(ta);
return ret;
}
static int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core)
{
int i, ret = -1;
TaskTimersEntry *tte = core->tc->timers;
struct restore_posix_timer *t;
ta->posix_timers = (struct restore_posix_timer *)rst_mem_align_cpos(RM_PRIVATE);
if (!tte)
return prepare_posix_timers_from_fd(pid, ta);
ta->posix_timers_n = tte->n_posix;
for (i = 0; i < ta->posix_timers_n; 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;
sort_posix_timers(ta);
out:
return ret;
}
static int prepare_mm(pid_t pid, struct task_restore_args *args)
{
int exe_fd, i, ret = -1;

View File

@ -22,11 +22,6 @@ struct parasite_ctl;
struct parasite_thread_ctl;
extern int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct pstree_item *);
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 pstree_item *);
extern int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_misc *misc);
extern int parasite_dump_creds(struct parasite_ctl *ctl, CredsEntry *ce);

17
criu/include/timer.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef __CR_TIMER_H__
#define __CR_TIMER_H__
#include "images/core.pb-c.h"
struct task_restore_args;
struct pstree_item;
struct parasite_ctl;
struct proc_posix_timers_stat;
extern int prepare_itimers(int pid, struct task_restore_args *args, CoreEntry *core);
extern int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core);
extern int parasite_dump_itimers_seized(struct parasite_ctl *ctl, struct pstree_item *item);
extern int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args, struct parasite_ctl *ctl,
struct pstree_item *item);
#endif

View File

@ -278,156 +278,6 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct pstree_item *i
return 0;
}
static void encode_itimer(struct itimerval *v, ItimerEntry *ie)
{
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 pstree_item *item)
{
CoreEntry *core = item->core[0];
struct parasite_dump_itimers_args *args;
int ret;
args = compel_parasite_args(ctl, struct parasite_dump_itimers_args);
ret = compel_rpc_call_sync(PARASITE_CMD_DUMP_ITIMERS, ctl);
if (ret < 0)
return ret;
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 0;
}
static int core_alloc_posix_timers(TaskTimersEntry *tte, int n, PosixTimerEntry **pte)
{
int sz;
/*
* Will be free()-ed in core_entry_free()
*/
sz = n * (sizeof(PosixTimerEntry *) + sizeof(PosixTimerEntry));
tte->posix = xmalloc(sz);
if (!tte->posix)
return -1;
tte->n_posix = n;
*pte = (PosixTimerEntry *)(tte->posix + n);
return 0;
}
static int encode_notify_thread_id(pid_t rtid, struct pstree_item *item, PosixTimerEntry *pte)
{
pid_t vtid = 0;
int i;
if (rtid == 0)
return 0;
if (!(root_ns_mask & CLONE_NEWPID)) {
/* Non-pid-namespace case */
pte->notify_thread_id = rtid;
pte->has_notify_thread_id = true;
return 0;
}
/* Pid-namespace case */
if (!kdat.has_nspid) {
pr_err("Have no NSpid support to dump notify thread id in pid namespace\n");
return -1;
}
for (i = 0; i < item->nr_threads; i++) {
if (item->threads[i].real != rtid)
continue;
vtid = item->threads[i].ns[0].virt;
break;
}
if (vtid == 0) {
pr_err("Unable to convert the notify thread id %d\n", rtid);
return -1;
}
pte->notify_thread_id = vtid;
pte->has_notify_thread_id = true;
return 0;
}
static int encode_posix_timer(struct pstree_item *item, struct posix_timer *v, struct proc_posix_timer *vp,
PosixTimerEntry *pte)
{
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;
if (encode_notify_thread_id(vp->spt.notify_thread_id, item, pte))
return -1;
return 0;
}
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 proc_posix_timer *temp;
struct parasite_dump_posix_timers_args *args;
int ret, exit_code = -1;
int args_size;
int i;
if (core_alloc_posix_timers(tte, proc_args->timer_n, &pte))
return -1;
args_size = posix_timers_dump_size(proc_args->timer_n);
args = compel_parasite_args_s(ctl, args_size);
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 = compel_rpc_call_sync(PARASITE_CMD_DUMP_POSIX_TIMERS, ctl);
if (ret < 0)
goto end_posix;
i = 0;
list_for_each_entry(temp, &proc_args->timers, list) {
posix_timer_entry__init(&pte[i]);
if (encode_posix_timer(item, &args->timer[i], temp, &pte[i]))
goto end_posix;
tte->posix[i] = &pte[i];
i++;
}
exit_code = 0;
end_posix:
free_posix_timers(proc_args);
return exit_code;
}
int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_misc *misc)
{
struct parasite_dump_misc *ma;

399
criu/timer.c Normal file
View File

@ -0,0 +1,399 @@
#include "types.h"
#include "crtools.h"
#include "infect.h"
#include "protobuf.h"
#include "pstree.h"
#include "posix-timer.h"
#include "parasite.h"
#include "namespaces.h"
#include "rst-malloc.h"
#include "restorer.h"
static inline int timeval_valid(struct timeval *tv)
{
return (tv->tv_sec >= 0) && ((unsigned long)tv->tv_usec < USEC_PER_SEC);
}
static inline int decode_itimer(char *n, ItimerEntry *ie, struct itimerval *val)
{
if (ie->isec == 0 && ie->iusec == 0) {
memzero_p(val);
return 0;
}
val->it_interval.tv_sec = ie->isec;
val->it_interval.tv_usec = ie->iusec;
if (!timeval_valid(&val->it_interval)) {
pr_err("Invalid timer interval\n");
return -1;
}
if (ie->vsec == 0 && ie->vusec == 0) {
/*
* Remaining time was too short. Set it to
* interval to make the timer armed and work.
*/
val->it_value.tv_sec = ie->isec;
val->it_value.tv_usec = ie->iusec;
} else {
val->it_value.tv_sec = ie->vsec;
val->it_value.tv_usec = ie->vusec;
}
if (!timeval_valid(&val->it_value)) {
pr_err("Invalid timer value\n");
return -1;
}
pr_info("Restored %s timer to %ld.%ld -> %ld.%ld\n", n, val->it_value.tv_sec, val->it_value.tv_usec,
val->it_interval.tv_sec, val->it_interval.tv_usec);
return 0;
}
/*
* Legacy itimers restore from CR_FD_ITIMERS
*/
int prepare_itimers_from_fd(int pid, struct task_restore_args *args)
{
int ret = -1;
struct cr_img *img;
ItimerEntry *ie;
if (!deprecated_ok("Itimers"))
return -1;
img = open_image(CR_FD_ITIMERS, O_RSTR, pid);
if (!img)
return -1;
ret = pb_read_one(img, &ie, PB_ITIMER);
if (ret < 0)
goto out;
ret = decode_itimer("real", ie, &args->itimers[0]);
itimer_entry__free_unpacked(ie, NULL);
if (ret < 0)
goto out;
ret = pb_read_one(img, &ie, PB_ITIMER);
if (ret < 0)
goto out;
ret = decode_itimer("virt", ie, &args->itimers[1]);
itimer_entry__free_unpacked(ie, NULL);
if (ret < 0)
goto out;
ret = pb_read_one(img, &ie, PB_ITIMER);
if (ret < 0)
goto out;
ret = decode_itimer("prof", ie, &args->itimers[2]);
itimer_entry__free_unpacked(ie, NULL);
if (ret < 0)
goto out;
out:
close_image(img);
return ret;
}
int prepare_itimers(int pid, struct task_restore_args *args, CoreEntry *core)
{
int ret = 0;
TaskTimersEntry *tte = core->tc->timers;
if (!tte)
return prepare_itimers_from_fd(pid, args);
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;
}
static inline int timespec_valid(struct timespec *ts)
{
return (ts->tv_sec >= 0) && ((unsigned long)ts->tv_nsec < NSEC_PER_SEC);
}
static inline int decode_posix_timer(PosixTimerEntry *pte, struct restore_posix_timer *pt)
{
pt->val.it_interval.tv_sec = pte->isec;
pt->val.it_interval.tv_nsec = pte->insec;
if (!timespec_valid(&pt->val.it_interval)) {
pr_err("Invalid timer interval(posix)\n");
return -1;
}
if (pte->vsec == 0 && pte->vnsec == 0) {
/*
* Remaining time was too short. Set it to
* interval to make the timer armed and work.
*/
pt->val.it_value.tv_sec = pte->isec;
pt->val.it_value.tv_nsec = pte->insec;
} else {
pt->val.it_value.tv_sec = pte->vsec;
pt->val.it_value.tv_nsec = pte->vnsec;
}
if (!timespec_valid(&pt->val.it_value)) {
pr_err("Invalid timer value(posix)\n");
return -1;
}
pt->spt.it_id = pte->it_id;
pt->spt.clock_id = pte->clock_id;
pt->spt.si_signo = pte->si_signo;
pt->spt.it_sigev_notify = pte->it_sigev_notify;
pt->spt.sival_ptr = decode_pointer(pte->sival_ptr);
pt->spt.notify_thread_id = pte->notify_thread_id;
pt->overrun = pte->overrun;
return 0;
}
static int cmp_posix_timer_proc_id(const void *p1, const void *p2)
{
return ((struct restore_posix_timer *)p1)->spt.it_id - ((struct restore_posix_timer *)p2)->spt.it_id;
}
static void sort_posix_timers(struct task_restore_args *ta)
{
void *tmem;
/*
* This is required for restorer's create_posix_timers(),
* it will probe them one-by-one for the desired ID, since
* kernel doesn't provide another API for timer creation
* with given ID.
*/
if (ta->posix_timers_n > 0) {
tmem = rst_mem_remap_ptr((unsigned long)ta->posix_timers, RM_PRIVATE);
qsort(tmem, ta->posix_timers_n, sizeof(struct restore_posix_timer), cmp_posix_timer_proc_id);
}
}
/*
* Legacy posix timers restoration from CR_FD_POSIX_TIMERS
*/
int prepare_posix_timers_from_fd(int pid, struct task_restore_args *ta)
{
struct cr_img *img;
int ret = -1;
struct restore_posix_timer *t;
if (!deprecated_ok("Posix timers"))
return -1;
img = open_image(CR_FD_POSIX_TIMERS, O_RSTR, pid);
if (!img)
return -1;
ta->posix_timers_n = 0;
while (1) {
PosixTimerEntry *pte;
ret = pb_read_one_eof(img, &pte, PB_POSIX_TIMER);
if (ret <= 0)
break;
t = rst_mem_alloc(sizeof(struct restore_posix_timer), RM_PRIVATE);
if (!t)
break;
ret = decode_posix_timer(pte, t);
if (ret < 0)
break;
posix_timer_entry__free_unpacked(pte, NULL);
ta->posix_timers_n++;
}
close_image(img);
if (!ret)
sort_posix_timers(ta);
return ret;
}
int prepare_posix_timers(int pid, struct task_restore_args *ta, CoreEntry *core)
{
int i, ret = -1;
TaskTimersEntry *tte = core->tc->timers;
struct restore_posix_timer *t;
ta->posix_timers = (struct restore_posix_timer *)rst_mem_align_cpos(RM_PRIVATE);
if (!tte)
return prepare_posix_timers_from_fd(pid, ta);
ta->posix_timers_n = tte->n_posix;
for (i = 0; i < ta->posix_timers_n; 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;
sort_posix_timers(ta);
out:
return ret;
}
static void encode_itimer(struct itimerval *v, ItimerEntry *ie)
{
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 pstree_item *item)
{
CoreEntry *core = item->core[0];
struct parasite_dump_itimers_args *args;
int ret;
args = compel_parasite_args(ctl, struct parasite_dump_itimers_args);
ret = compel_rpc_call_sync(PARASITE_CMD_DUMP_ITIMERS, ctl);
if (ret < 0)
return ret;
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 0;
}
static int core_alloc_posix_timers(TaskTimersEntry *tte, int n, PosixTimerEntry **pte)
{
int sz;
/*
* Will be free()-ed in core_entry_free()
*/
sz = n * (sizeof(PosixTimerEntry *) + sizeof(PosixTimerEntry));
tte->posix = xmalloc(sz);
if (!tte->posix)
return -1;
tte->n_posix = n;
*pte = (PosixTimerEntry *)(tte->posix + n);
return 0;
}
static int encode_notify_thread_id(pid_t rtid, struct pstree_item *item, PosixTimerEntry *pte)
{
pid_t vtid = 0;
int i;
if (rtid == 0)
return 0;
if (!(root_ns_mask & CLONE_NEWPID)) {
/* Non-pid-namespace case */
pte->notify_thread_id = rtid;
pte->has_notify_thread_id = true;
return 0;
}
/* Pid-namespace case */
if (!kdat.has_nspid) {
pr_err("Have no NSpid support to dump notify thread id in pid namespace\n");
return -1;
}
for (i = 0; i < item->nr_threads; i++) {
if (item->threads[i].real != rtid)
continue;
vtid = item->threads[i].ns[0].virt;
break;
}
if (vtid == 0) {
pr_err("Unable to convert the notify thread id %d\n", rtid);
return -1;
}
pte->notify_thread_id = vtid;
pte->has_notify_thread_id = true;
return 0;
}
static int encode_posix_timer(struct pstree_item *item, struct posix_timer *v, struct proc_posix_timer *vp,
PosixTimerEntry *pte)
{
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;
if (encode_notify_thread_id(vp->spt.notify_thread_id, item, pte))
return -1;
return 0;
}
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 proc_posix_timer *temp;
struct parasite_dump_posix_timers_args *args;
int ret, exit_code = -1;
int args_size;
int i;
if (core_alloc_posix_timers(tte, proc_args->timer_n, &pte))
return -1;
args_size = posix_timers_dump_size(proc_args->timer_n);
args = compel_parasite_args_s(ctl, args_size);
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 = compel_rpc_call_sync(PARASITE_CMD_DUMP_POSIX_TIMERS, ctl);
if (ret < 0)
goto end_posix;
i = 0;
list_for_each_entry(temp, &proc_args->timers, list) {
posix_timer_entry__init(&pte[i]);
if (encode_posix_timer(item, &args->timer[i], temp, &pte[i]))
goto end_posix;
tte->posix[i] = &pte[i];
i++;
}
exit_code = 0;
end_posix:
free_posix_timers(proc_args);
return exit_code;
}