[CRIU] [PATCH 2/2] seize: Simplify processes_to_wait calc
Pavel Emelyanov
xemul at virtuozzo.com
Tue Sep 27 10:45:19 PDT 2016
Localize the processes_to_wait calculations in seize.c. In
order to distinguish dead tasks which has already been wait()-ed
from dead tasks that hasn't introduce internal 'zombie' state
for seize_wait_task().
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
criu/cr-exec.c | 6 ++++++
criu/include/pid.h | 1 +
criu/include/pstree.h | 7 ++++++-
criu/include/ptrace.h | 2 --
criu/ptrace.c | 10 +++++-----
criu/seize.c | 23 +++++++++++++++++++----
6 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/criu/cr-exec.c b/criu/cr-exec.c
index d1424fc..d767b3c 100644
--- a/criu/cr-exec.c
+++ b/criu/cr-exec.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include "crtools.h"
#include "ptrace.h"
+#include "pstree.h"
#include "parasite-syscall.h"
#include "vma.h"
#include "log.h"
@@ -146,6 +147,11 @@ int cr_exec(int pid, char **opt)
goto out;
}
+ if (!is_alive_state(prev_state)) {
+ pr_err("Only can exec on running/stopped tasks\n");
+ goto out;
+ }
+
ret = collect_mappings(pid, &vmas, NULL);
if (ret) {
pr_err("Can't collect vmas for %d\n", pid);
diff --git a/criu/include/pid.h b/criu/include/pid.h
index bf978b4..aa9d502 100644
--- a/criu/include/pid.h
+++ b/criu/include/pid.h
@@ -30,6 +30,7 @@ struct pid {
#define TASK_STOPPED 0x3
#define TASK_HELPER 0x4
#define TASK_THREAD 0x5
+#define TASK_ZOMBIE 0x6
/*
* When we have to restore a shared resource, we mush select which
diff --git a/criu/include/pstree.h b/criu/include/pstree.h
index 3f31d55..d5053f4 100644
--- a/criu/include/pstree.h
+++ b/criu/include/pstree.h
@@ -59,9 +59,14 @@ static inline int shared_fdtable(struct pstree_item *item)
item->ids->files_id == item->parent->ids->files_id);
}
+static inline bool is_alive_state(int state)
+{
+ return (state == TASK_ALIVE) || (state == TASK_STOPPED);
+}
+
static inline bool task_alive(struct pstree_item *i)
{
- return (i->pid.state == TASK_ALIVE) || (i->pid.state == TASK_STOPPED);
+ return is_alive_state(i->pid.state);
}
extern void free_pstree(struct pstree_item *root_item);
diff --git a/criu/include/ptrace.h b/criu/include/ptrace.h
index b30d4ba..72da972 100644
--- a/criu/include/ptrace.h
+++ b/criu/include/ptrace.h
@@ -73,8 +73,6 @@ struct ptrace_peeksiginfo_args {
#define SI_EVENT(_si_code) (((_si_code) & 0xFFFF) >> 8)
-extern int processes_to_wait;
-
extern int seize_catch_task(pid_t pid);
extern int seize_wait_task(pid_t pid, pid_t ppid, struct proc_status_creds *creds);
extern int suspend_seccomp(pid_t pid);
diff --git a/criu/ptrace.c b/criu/ptrace.c
index a449487..155600d 100644
--- a/criu/ptrace.c
+++ b/criu/ptrace.c
@@ -161,7 +161,6 @@ int seize_wait_task(pid_t pid, pid_t ppid, struct proc_status_creds *creds)
* we might need at that early point.
*/
- processes_to_wait--;
try_again:
ret = wait4(pid, &status, __WALL, NULL);
@@ -171,10 +170,8 @@ try_again:
* if a task is zombie. If we are here from try_again,
* this means that we are tracing this task.
*
- * processes_to_wait should be descrimented only once in this
- * function if a first wait was success.
+ * So here we can be only once in this function.
*/
- processes_to_wait++;
wait_errno = errno;
}
@@ -192,7 +189,10 @@ try_again:
return -1;
}
- return TASK_DEAD;
+ if (ret < 0)
+ return TASK_ZOMBIE;
+ else
+ return TASK_DEAD;
}
if ((ppid != -1) && (creds->ppid != ppid)) {
diff --git a/criu/seize.c b/criu/seize.c
index 0a9a750..56d11d0 100644
--- a/criu/seize.c
+++ b/criu/seize.c
@@ -89,6 +89,10 @@ static int freezer_restore_state(void)
return 0;
}
+/* A number of tasks in a freezer cgroup which are not going to be dumped */
+static int processes_to_wait;
+static pid_t *processes_to_wait_pids;
+
static int seize_cgroup_tree(char *root_path, const char *state)
{
DIR *dir;
@@ -175,10 +179,6 @@ static int seize_cgroup_tree(char *root_path, const char *state)
return 0;
}
-/* A number of tasks in a freezer cgroup which are not going to be dumped */
-int processes_to_wait;
-static pid_t *processes_to_wait_pids;
-
/*
* A freezer cgroup can contain tasks which will not be dumped
* and we need to wait them, because the are interupted them by ptrace.
@@ -484,6 +484,11 @@ static int collect_children(struct pstree_item *item)
continue;
}
+ if (ret == TASK_ZOMBIE)
+ ret = TASK_DEAD;
+ else
+ processes_to_wait--;
+
dmpi(c)->pi_creds = creds;
c->pid.real = pid;
c->parent = item;
@@ -701,6 +706,11 @@ static int collect_threads(struct pstree_item *item)
continue;
}
+ if (ret == TASK_ZOMBIE)
+ ret = TASK_DEAD;
+ else
+ processes_to_wait--;
+
BUG_ON(item->nr_threads + 1 > nr_threads);
item->threads[item->nr_threads].real = pid;
item->nr_threads++;
@@ -826,6 +836,11 @@ int collect_pstree(void)
if (ret < 0)
goto err;
+ if (ret == TASK_ZOMBIE)
+ ret = TASK_DEAD;
+ else
+ processes_to_wait--;
+
pr_info("Seized task %d, state %d\n", pid, ret);
root_item->pid.state = ret;
dmpi(root_item)->pi_creds = creds;
--
2.5.0
More information about the CRIU
mailing list