Commit 8e85aed8 authored by Pavel Emelyanov's avatar Pavel Emelyanov

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: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 5773ad84
......@@ -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,6 +189,9 @@ try_again:
return -1;
}
if (ret < 0)
return TASK_ZOMBIE;
else
return TASK_DEAD;
}
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment