mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-08-03 15:23:04 +00:00
Merge 5b30f6d5a0 into b7bdc14736
This commit is contained in:
commit
575bd247fb
4 changed files with 104 additions and 10 deletions
41
criu/timer.c
41
criu/timer.c
|
|
@ -306,6 +306,16 @@ static int encode_notify_thread_id(pid_t rtid, struct pstree_item *item, PosixTi
|
|||
|
||||
if (!(root_ns_mask & CLONE_NEWPID)) {
|
||||
/* Non-pid-namespace case */
|
||||
for (i = 0; i < item->nr_threads; i++) {
|
||||
if (item->threads[i].real == rtid)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == item->nr_threads) {
|
||||
pr_warn("Skipping timer because notify thread %d is dead\n", rtid);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pte->notify_thread_id = rtid;
|
||||
pte->has_notify_thread_id = true;
|
||||
return 0;
|
||||
|
|
@ -326,8 +336,8 @@ static int encode_notify_thread_id(pid_t rtid, struct pstree_item *item, PosixTi
|
|||
}
|
||||
|
||||
if (vtid == 0) {
|
||||
pr_err("Unable to convert the notify thread id %d\n", rtid);
|
||||
return -1;
|
||||
pr_warn("Skipping timer because notify thread %d is dead\n", rtid);
|
||||
return 1;
|
||||
}
|
||||
|
||||
pte->notify_thread_id = vtid;
|
||||
|
|
@ -351,10 +361,7 @@ static int encode_posix_timer(struct pstree_item *item, struct posix_timer *v, s
|
|||
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;
|
||||
return encode_notify_thread_id(vp->spt.notify_thread_id, item, pte);
|
||||
}
|
||||
|
||||
int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args, struct parasite_ctl *ctl,
|
||||
|
|
@ -367,7 +374,7 @@ int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args,
|
|||
struct parasite_dump_posix_timers_args *args;
|
||||
int ret, exit_code = -1;
|
||||
int args_size;
|
||||
int i;
|
||||
int i, j;
|
||||
|
||||
if (core_alloc_posix_timers(tte, proc_args->timer_n, &pte))
|
||||
return -1;
|
||||
|
|
@ -386,14 +393,28 @@ int parasite_dump_posix_timers_seized(struct proc_posix_timers_stat *proc_args,
|
|||
if (ret < 0)
|
||||
goto end_posix;
|
||||
|
||||
/*
|
||||
* i advances every iteration (indexes parasite-filled args->timer[]);
|
||||
* j advances only for timers we keep, both the next output slot
|
||||
* and the final count. Timers whose notify thread has exited are
|
||||
* skipped (i.e., j <= i).
|
||||
*/
|
||||
i = 0;
|
||||
j = 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]))
|
||||
posix_timer_entry__init(&pte[j]);
|
||||
ret = encode_posix_timer(item, &args->timer[i], temp, &pte[j]);
|
||||
if (ret < 0)
|
||||
goto end_posix;
|
||||
tte->posix[i] = &pte[i];
|
||||
if (ret == 1) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
tte->posix[j] = &pte[j];
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
tte->n_posix = j;
|
||||
|
||||
exit_code = 0;
|
||||
end_posix:
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ TST_NOFILE := \
|
|||
pthread_timers \
|
||||
pthread_timers_h \
|
||||
leader_posix_timer \
|
||||
dead_thread_posix_timer \
|
||||
rseq00 \
|
||||
membarrier \
|
||||
vdso00 \
|
||||
|
|
@ -638,6 +639,7 @@ pthread02: LDLIBS += -pthread
|
|||
pthread_timers: LDLIBS += -lrt -pthread
|
||||
pthread_timers_h: LDLIBS += -lrt -pthread
|
||||
leader_posix_timer: LDLIBS += -lrt -pthread
|
||||
dead_thread_posix_timer: LDLIBS += -lrt -pthread
|
||||
different_creds: LDLIBS += -pthread
|
||||
sigpending: LDLIBS += -pthread
|
||||
sigaltstack: LDLIBS += -pthread
|
||||
|
|
|
|||
70
test/zdtm/static/dead_thread_posix_timer.c
Normal file
70
test/zdtm/static/dead_thread_posix_timer.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "zdtmtst.h"
|
||||
|
||||
#ifndef SIGEV_THREAD_ID
|
||||
#define SIGEV_THREAD_ID 4
|
||||
#endif
|
||||
|
||||
const char *test_doc = "Check that a SIGEV_THREAD_ID timer targeting a dead thread doesn't break dump";
|
||||
const char *test_author = "Felicitas Pojtinger <felicitaspojtinger@loopholelabs.io>";
|
||||
|
||||
static timer_t timerid;
|
||||
|
||||
static void *worker(void *arg)
|
||||
{
|
||||
pid_t tid;
|
||||
struct sigevent evp = {};
|
||||
|
||||
tid = syscall(SYS_gettid);
|
||||
|
||||
evp.sigev_notify = SIGEV_THREAD_ID;
|
||||
#ifdef __GLIBC__
|
||||
evp._sigev_un._tid = tid;
|
||||
#else
|
||||
evp.sigev_notify_thread_id = tid;
|
||||
#endif
|
||||
evp.sigev_signo = SIGRTMIN;
|
||||
|
||||
if (timer_create(CLOCK_MONOTONIC, &evp, &timerid)) {
|
||||
pr_perror("timer_create");
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pthread_t thr;
|
||||
void *ret;
|
||||
|
||||
test_init(argc, argv);
|
||||
|
||||
if (pthread_create(&thr, NULL, worker, NULL)) {
|
||||
pr_perror("pthread_create");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pthread_join(thr, &ret)) {
|
||||
pr_perror("pthread_join");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ret != NULL) {
|
||||
fail("Timer creation thread failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
test_daemon();
|
||||
test_waitsig();
|
||||
|
||||
pass();
|
||||
|
||||
timer_delete(timerid);
|
||||
return 0;
|
||||
}
|
||||
1
test/zdtm/static/dead_thread_posix_timer.desc
Normal file
1
test/zdtm/static/dead_thread_posix_timer.desc
Normal file
|
|
@ -0,0 +1 @@
|
|||
{'feature': 'ns_pid'}
|
||||
Loading…
Add table
Add a link
Reference in a new issue