diff options
Diffstat (limited to 'kernel/pid_namespace.c')
| -rw-r--r-- | kernel/pid_namespace.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 16b20e38c4a1..b3c7fd554250 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c | |||
| @@ -184,11 +184,31 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) | |||
| 184 | } | 184 | } |
| 185 | read_unlock(&tasklist_lock); | 185 | read_unlock(&tasklist_lock); |
| 186 | 186 | ||
| 187 | /* Firstly reap the EXIT_ZOMBIE children we may have. */ | ||
| 187 | do { | 188 | do { |
| 188 | clear_thread_flag(TIF_SIGPENDING); | 189 | clear_thread_flag(TIF_SIGPENDING); |
| 189 | rc = sys_wait4(-1, NULL, __WALL, NULL); | 190 | rc = sys_wait4(-1, NULL, __WALL, NULL); |
| 190 | } while (rc != -ECHILD); | 191 | } while (rc != -ECHILD); |
| 191 | 192 | ||
| 193 | /* | ||
| 194 | * sys_wait4() above can't reap the TASK_DEAD children. | ||
| 195 | * Make sure they all go away, see __unhash_process(). | ||
| 196 | */ | ||
| 197 | for (;;) { | ||
| 198 | bool need_wait = false; | ||
| 199 | |||
| 200 | read_lock(&tasklist_lock); | ||
| 201 | if (!list_empty(¤t->children)) { | ||
| 202 | __set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 203 | need_wait = true; | ||
| 204 | } | ||
| 205 | read_unlock(&tasklist_lock); | ||
| 206 | |||
| 207 | if (!need_wait) | ||
| 208 | break; | ||
| 209 | schedule(); | ||
| 210 | } | ||
| 211 | |||
| 192 | if (pid_ns->reboot) | 212 | if (pid_ns->reboot) |
| 193 | current->signal->group_exit_code = pid_ns->reboot; | 213 | current->signal->group_exit_code = pid_ns->reboot; |
| 194 | 214 | ||
