Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/criu
diff options
context:
space:
mode:
authorYuriy Vasiliev <yuriy.vasiliev@openvz.org>2022-01-20 19:13:59 +0300
committerAndrei Vagin <avagin@gmail.com>2022-07-02 19:06:30 +0300
commit7968e71db86f92b09a207bb580924265892fe8ec (patch)
tree1b4bf3f79677c1392a7d4544d7bb5dddec379788 /criu
parent029ca223767f41ab8aeee6441c04aba3f3e5765b (diff)
infect: add SIGTSTP support
Add SIGTSTP signal dump and restore. Add a corresponding field in the image, save it only if a task is in the stopped state. Restore task state by sending desired stop signal if it is present in the image. Fallback to SIGSTOP if it's absent. Signed-off-by: Yuriy Vasiliev <yuriy.vasiliev@openvz.org>
Diffstat (limited to 'criu')
-rw-r--r--criu/cr-dump.c5
-rw-r--r--criu/cr-restore.c11
-rw-r--r--criu/include/pid.h4
-rw-r--r--criu/proc_parse.c15
-rw-r--r--criu/pstree.c1
-rw-r--r--criu/seize.c8
6 files changed, 40 insertions, 4 deletions
diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index 60e90baed..e60da88ed 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -781,6 +781,11 @@ static int dump_task_core_all(struct parasite_ctl *ctl, struct pstree_item *item
core->thread_core->creds->lsm_profile = dmpi(item)->thread_lsms[0]->profile;
core->thread_core->creds->lsm_sockcreate = dmpi(item)->thread_lsms[0]->sockcreate;
+ if (core->tc->task_state == TASK_STOPPED) {
+ core->tc->has_stop_signo = true;
+ core->tc->stop_signo = item->pid->stop_signo;
+ }
+
ret = parasite_dump_thread_leader_seized(ctl, pid, core);
if (ret)
goto err;
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 398faf048..279246c19 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -1350,6 +1350,9 @@ static inline int fork_with_pid(struct pstree_item *item)
item->pid->state = ca.core->tc->task_state;
rsti(item)->cg_set = ca.core->tc->cg_set;
+ if (ca.core->tc->has_stop_signo)
+ item->pid->stop_signo = ca.core->tc->stop_signo;
+
if (item->pid->state != TASK_DEAD && !task_alive(item)) {
pr_err("Unknown task state %d\n", item->pid->state);
return -1;
@@ -2104,8 +2107,14 @@ static void finalize_restore(void)
xfree(ctl);
- if ((item->pid->state == TASK_STOPPED) || (opts.final_state == TASK_STOPPED))
+ if (opts.final_state == TASK_STOPPED)
kill(item->pid->real, SIGSTOP);
+ else if (item->pid->state == TASK_STOPPED) {
+ if (item->pid->stop_signo > 0)
+ kill(item->pid->real, item->pid->stop_signo);
+ else
+ kill(item->pid->real, SIGSTOP);
+ }
}
}
diff --git a/criu/include/pid.h b/criu/include/pid.h
index 49cb2d322..b2b7a361a 100644
--- a/criu/include/pid.h
+++ b/criu/include/pid.h
@@ -31,6 +31,10 @@ struct pid {
pid_t real;
int state; /* TASK_XXX constants */
+ /* If an item is in stopped state it has a signal number
+ * that caused task to stop.
+ */
+ int stop_signo;
/*
* The @virt pid is one which used in the image itself and keeps
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index 6b41a81db..946b0fc40 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -1027,12 +1027,13 @@ int parse_pid_status(pid_t pid, struct seize_task_status *ss, void *data)
cr->s.sigpnd = 0;
cr->s.shdpnd = 0;
+ cr->s.sigblk = 0;
cr->s.seccomp_mode = SECCOMP_MODE_DISABLED;
if (bfdopenr(&f))
return -1;
- while (done < 13) {
+ while (done < 14) {
str = breadline(&f);
if (str == NULL)
break;
@@ -1146,10 +1147,20 @@ int parse_pid_status(pid_t pid, struct seize_task_status *ss, void *data)
done++;
continue;
}
+ if (!strncmp(str, "SigBlk:", 7)) {
+ unsigned long long sigblk = 0;
+
+ if (sscanf(str + 7, "%llx", &sigblk) != 1)
+ goto err_parse;
+ cr->s.sigblk |= sigblk;
+
+ done++;
+ continue;
+ }
}
/* seccomp and nspids are optional */
- expected_done = (parsed_seccomp ? 11 : 10);
+ expected_done = (parsed_seccomp ? 12 : 11);
if (kdat.has_nspid)
expected_done++;
if (done == expected_done)
diff --git a/criu/pstree.c b/criu/pstree.c
index f4d77b3a4..72c4a3502 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -222,6 +222,7 @@ struct pstree_item *__alloc_pstree_item(bool rst)
item->pid->ns[0].virt = -1;
item->pid->real = -1;
item->pid->state = TASK_UNDEF;
+ item->pid->stop_signo = -1;
item->born_sid = -1;
item->pid->item = item;
futex_init(&item->task_st);
diff --git a/criu/seize.c b/criu/seize.c
index 58564ca74..1333d6db9 100644
--- a/criu/seize.c
+++ b/criu/seize.c
@@ -615,6 +615,9 @@ static int collect_children(struct pstree_item *item)
else
processes_to_wait--;
+ if (ret == TASK_STOPPED)
+ c->pid->stop_signo = compel_parse_stop_signo(pid);
+
c->pid->real = pid;
c->parent = item;
c->pid->state = ret;
@@ -646,7 +649,7 @@ static void unseize_task_and_threads(const struct pstree_item *item, int st)
* the item->state is the state task was in when we seized one.
*/
- compel_resume_task(item->pid->real, item->pid->state, st);
+ compel_resume_task_sig(item->pid->real, item->pid->state, st, item->pid->stop_signo);
if (st == TASK_DEAD)
return;
@@ -950,6 +953,9 @@ int collect_pstree(void)
else
processes_to_wait--;
+ if (ret == TASK_STOPPED)
+ root_item->pid->stop_signo = compel_parse_stop_signo(pid);
+
pr_info("Seized task %d, state %d\n", pid, ret);
root_item->pid->state = ret;