On 12/04, Daniel Lezcano wrote: > > This patch propose to store the reboot value in the 16 upper bits of the > exit code from the processes belonging to a pid namespace which has > rebooted. When the reboot syscall is called and we are not in the initial > pid namespace, we kill the pid namespace. > > By this way the parent process of the child pid namespace to know if > it rebooted or not and take the right decision. > > Signed-off-by: Daniel Lezcano <daniel.lezcano@xxxxxxx> > Acked-by: Serge Hallyn <serge.hallyn@xxxxxxxxxxxxx> > --- > include/linux/pid_namespace.h | 8 +++++++- > kernel/pid_namespace.c | 33 +++++++++++++++++++++++++++++++++ > kernel/sys.c | 3 +++ > 3 files changed, 43 insertions(+), 1 deletions(-) Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx> > diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h > index e7cf666..3279596 100644 > --- a/include/linux/pid_namespace.h > +++ b/include/linux/pid_namespace.h > @@ -32,6 +32,7 @@ struct pid_namespace { > #endif > gid_t pid_gid; > int hide_pid; > + int reboot; > }; > > extern struct pid_namespace init_pid_ns; > @@ -47,6 +48,7 @@ static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns) > extern struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *ns); > extern void free_pid_ns(struct kref *kref); > extern void zap_pid_ns_processes(struct pid_namespace *pid_ns); > +extern int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd); > > static inline void put_pid_ns(struct pid_namespace *ns) > { > @@ -74,11 +76,15 @@ static inline void put_pid_ns(struct pid_namespace *ns) > { > } > > - > static inline void zap_pid_ns_processes(struct pid_namespace *ns) > { > BUG(); > } > + > +static inline int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd) > +{ > + BUG(); > +} > #endif /* CONFIG_PID_NS */ > > extern struct pid_namespace *task_active_pid_ns(struct task_struct *tsk); > diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c > index a896839..c7a85ea 100644 > --- a/kernel/pid_namespace.c > +++ b/kernel/pid_namespace.c > @@ -15,6 +15,7 @@ > #include <linux/acct.h> > #include <linux/slab.h> > #include <linux/proc_fs.h> > +#include <linux/reboot.h> > > #define BITS_PER_PAGE (PAGE_SIZE*8) > > @@ -187,6 +188,9 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) > rc = sys_wait4(-1, NULL, __WALL, NULL); > } while (rc != -ECHILD); > > + if (pid_ns->reboot) > + current->signal->group_exit_code = pid_ns->reboot; > + > acct_exit_ns(pid_ns); > return; > } > @@ -221,6 +225,35 @@ static struct ctl_table pid_ns_ctl_table[] = { > > static struct ctl_path kern_path[] = { { .procname = "kernel", }, { } }; > > +int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd) > +{ > + switch(cmd) { > + case LINUX_REBOOT_CMD_RESTART2: > + case LINUX_REBOOT_CMD_RESTART: > + pid_ns->reboot = SYSTEM_RESTART << 16; > + break; > + > + case LINUX_REBOOT_CMD_HALT: > + pid_ns->reboot = SYSTEM_HALT << 16; > + break; > + > + case LINUX_REBOOT_CMD_POWER_OFF: > + pid_ns->reboot = SYSTEM_POWER_OFF << 16; > + break; > + default: > + return -EINVAL; > + } > + > + read_lock(&tasklist_lock); > + force_sig(SIGKILL, pid_ns->child_reaper); > + read_unlock(&tasklist_lock); > + > + do_exit(0); > + > + /* Not reached */ > + return 0; > +} > + > static __init int pid_namespaces_init(void) > { > pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC); > diff --git a/kernel/sys.c b/kernel/sys.c > index ddf8155..31acf63 100644 > --- a/kernel/sys.c > +++ b/kernel/sys.c > @@ -444,6 +444,9 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, > magic2 != LINUX_REBOOT_MAGIC2C)) > return -EINVAL; > > + if (task_active_pid_ns(current) != &init_pid_ns) > + return reboot_pid_ns(task_active_pid_ns(current), cmd); > + > /* Instead of trying to make the power_off code look like > * halt when pm_power_off is not set do it the easy way. > */ > -- > 1.7.5.4 > _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/containers