diff options
Diffstat (limited to 'kernel/pid_namespace.c')
-rw-r--r-- | kernel/pid_namespace.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 17b232869a04..57bc1fd35b3c 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/acct.h> | 15 | #include <linux/acct.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
18 | #include <linux/reboot.h> | ||
18 | 19 | ||
19 | #define BITS_PER_PAGE (PAGE_SIZE*8) | 20 | #define BITS_PER_PAGE (PAGE_SIZE*8) |
20 | 21 | ||
@@ -183,6 +184,9 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) | |||
183 | rc = sys_wait4(-1, NULL, __WALL, NULL); | 184 | rc = sys_wait4(-1, NULL, __WALL, NULL); |
184 | } while (rc != -ECHILD); | 185 | } while (rc != -ECHILD); |
185 | 186 | ||
187 | if (pid_ns->reboot) | ||
188 | current->signal->group_exit_code = pid_ns->reboot; | ||
189 | |||
186 | acct_exit_ns(pid_ns); | 190 | acct_exit_ns(pid_ns); |
187 | return; | 191 | return; |
188 | } | 192 | } |
@@ -217,6 +221,35 @@ static struct ctl_table pid_ns_ctl_table[] = { | |||
217 | 221 | ||
218 | static struct ctl_path kern_path[] = { { .procname = "kernel", }, { } }; | 222 | static struct ctl_path kern_path[] = { { .procname = "kernel", }, { } }; |
219 | 223 | ||
224 | int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd) | ||
225 | { | ||
226 | if (pid_ns == &init_pid_ns) | ||
227 | return 0; | ||
228 | |||
229 | switch (cmd) { | ||
230 | case LINUX_REBOOT_CMD_RESTART2: | ||
231 | case LINUX_REBOOT_CMD_RESTART: | ||
232 | pid_ns->reboot = SIGHUP; | ||
233 | break; | ||
234 | |||
235 | case LINUX_REBOOT_CMD_POWER_OFF: | ||
236 | case LINUX_REBOOT_CMD_HALT: | ||
237 | pid_ns->reboot = SIGINT; | ||
238 | break; | ||
239 | default: | ||
240 | return -EINVAL; | ||
241 | } | ||
242 | |||
243 | read_lock(&tasklist_lock); | ||
244 | force_sig(SIGKILL, pid_ns->child_reaper); | ||
245 | read_unlock(&tasklist_lock); | ||
246 | |||
247 | do_exit(0); | ||
248 | |||
249 | /* Not reached */ | ||
250 | return 0; | ||
251 | } | ||
252 | |||
220 | static __init int pid_namespaces_init(void) | 253 | static __init int pid_namespaces_init(void) |
221 | { | 254 | { |
222 | pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC); | 255 | pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC); |