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 @@ ...@@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "crtools.h" #include "crtools.h"
#include "ptrace.h" #include "ptrace.h"
#include "pstree.h"
#include "parasite-syscall.h" #include "parasite-syscall.h"
#include "vma.h" #include "vma.h"
#include "log.h" #include "log.h"
...@@ -152,6 +153,11 @@ int cr_exec(int pid, char **opt) ...@@ -152,6 +153,11 @@ int cr_exec(int pid, char **opt)
goto out; 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); ret = collect_mappings(pid, &vmas, NULL);
if (ret) { if (ret) {
pr_err("Can't collect vmas for %d\n", pid); pr_err("Can't collect vmas for %d\n", pid);
......
...@@ -30,6 +30,7 @@ struct pid { ...@@ -30,6 +30,7 @@ struct pid {
#define TASK_STOPPED 0x3 #define TASK_STOPPED 0x3
#define TASK_HELPER 0x4 #define TASK_HELPER 0x4
#define TASK_THREAD 0x5 #define TASK_THREAD 0x5
#define TASK_ZOMBIE 0x6
/* /*
* When we have to restore a shared resource, we mush select which * 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) ...@@ -59,9 +59,14 @@ static inline int shared_fdtable(struct pstree_item *item)
item->ids->files_id == item->parent->ids->files_id); 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) 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); extern void free_pstree(struct pstree_item *root_item);
......
...@@ -73,8 +73,6 @@ struct ptrace_peeksiginfo_args { ...@@ -73,8 +73,6 @@ struct ptrace_peeksiginfo_args {
#define SI_EVENT(_si_code) (((_si_code) & 0xFFFF) >> 8) #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_catch_task(pid_t pid);
extern int seize_wait_task(pid_t pid, pid_t ppid, struct proc_status_creds *creds); extern int seize_wait_task(pid_t pid, pid_t ppid, struct proc_status_creds *creds);
extern int suspend_seccomp(pid_t pid); 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) ...@@ -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. * we might need at that early point.
*/ */
processes_to_wait--;
try_again: try_again:
ret = wait4(pid, &status, __WALL, NULL); ret = wait4(pid, &status, __WALL, NULL);
...@@ -171,10 +170,8 @@ try_again: ...@@ -171,10 +170,8 @@ try_again:
* if a task is zombie. If we are here from try_again, * if a task is zombie. If we are here from try_again,
* this means that we are tracing this task. * this means that we are tracing this task.
* *
* processes_to_wait should be descrimented only once in this * So here we can be only once in this function.
* function if a first wait was success.
*/ */
processes_to_wait++;
wait_errno = errno; wait_errno = errno;
} }
...@@ -192,7 +189,10 @@ try_again: ...@@ -192,7 +189,10 @@ try_again:
return -1; return -1;
} }
return TASK_DEAD; if (ret < 0)
return TASK_ZOMBIE;
else
return TASK_DEAD;
} }
if ((ppid != -1) && (creds->ppid != ppid)) { if ((ppid != -1) && (creds->ppid != ppid)) {
......
...@@ -89,6 +89,10 @@ static int freezer_restore_state(void) ...@@ -89,6 +89,10 @@ static int freezer_restore_state(void)
return 0; 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) static int seize_cgroup_tree(char *root_path, const char *state)
{ {
DIR *dir; DIR *dir;
...@@ -175,10 +179,6 @@ static int seize_cgroup_tree(char *root_path, const char *state) ...@@ -175,10 +179,6 @@ static int seize_cgroup_tree(char *root_path, const char *state)
return 0; 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 * A freezer cgroup can contain tasks which will not be dumped
* and we need to wait them, because the are interupted them by ptrace. * 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) ...@@ -484,6 +484,11 @@ static int collect_children(struct pstree_item *item)
continue; continue;
} }
if (ret == TASK_ZOMBIE)
ret = TASK_DEAD;
else
processes_to_wait--;
dmpi(c)->pi_creds = creds; dmpi(c)->pi_creds = creds;
c->pid.real = pid; c->pid.real = pid;
c->parent = item; c->parent = item;
...@@ -701,6 +706,11 @@ static int collect_threads(struct pstree_item *item) ...@@ -701,6 +706,11 @@ static int collect_threads(struct pstree_item *item)
continue; continue;
} }
if (ret == TASK_ZOMBIE)
ret = TASK_DEAD;
else
processes_to_wait--;
BUG_ON(item->nr_threads + 1 > nr_threads); BUG_ON(item->nr_threads + 1 > nr_threads);
item->threads[item->nr_threads].real = pid; item->threads[item->nr_threads].real = pid;
item->nr_threads++; item->nr_threads++;
...@@ -826,6 +836,11 @@ int collect_pstree(void) ...@@ -826,6 +836,11 @@ int collect_pstree(void)
if (ret < 0) if (ret < 0)
goto err; goto err;
if (ret == TASK_ZOMBIE)
ret = TASK_DEAD;
else
processes_to_wait--;
pr_info("Seized task %d, state %d\n", pid, ret); pr_info("Seized task %d, state %d\n", pid, ret);
root_item->pid.state = ret; root_item->pid.state = ret;
dmpi(root_item)->pi_creds = creds; 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