mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
seize: Simplify processes_to_wait calc
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@virtuozzo.com>
This commit is contained in:
@@ -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"
|
||||
@@ -152,6 +153,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);
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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)) {
|
||||
|
23
criu/seize.c
23
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;
|
||||
|
Reference in New Issue
Block a user