Merge pull request #5792 from bernerdschaefer/nsinit-supports-pdeathsig

Add PDEATHSIG support to nsinit library
This commit is contained in:
Victor Marmol 2014-05-19 11:13:23 -07:00
commit c3b01dfb59
3 changed files with 55 additions and 0 deletions

View file

@ -123,6 +123,7 @@ func DefaultCreateCommand(container *libcontainer.Container, console, rootfs, da
command.Env = append(os.Environ(), env...) command.Env = append(os.Environ(), env...)
system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces))) system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces)))
command.SysProcAttr.Pdeathsig = syscall.SIGKILL
command.ExtraFiles = []*os.File{pipe} command.ExtraFiles = []*os.File{pipe}
return command return command

View file

@ -85,12 +85,53 @@ func Init(container *libcontainer.Container, uncleanRootfs, consolePath string,
return err return err
} }
} }
pdeathSignal, err := system.GetParentDeathSignal()
if err != nil {
return fmt.Errorf("get parent death signal %s", err)
}
if err := FinalizeNamespace(container); err != nil { if err := FinalizeNamespace(container); err != nil {
return fmt.Errorf("finalize namespace %s", err) return fmt.Errorf("finalize namespace %s", err)
} }
// FinalizeNamespace can change user/group which clears the parent death
// signal, so we restore it here.
if err := RestoreParentDeathSignal(pdeathSignal); err != nil {
return fmt.Errorf("restore parent death signal %s", err)
}
return system.Execv(args[0], args[0:], container.Env) return system.Execv(args[0], args[0:], container.Env)
} }
// RestoreParentDeathSignal sets the parent death signal to old.
func RestoreParentDeathSignal(old int) error {
if old == 0 {
return nil
}
current, err := system.GetParentDeathSignal()
if err != nil {
return fmt.Errorf("get parent death signal %s", err)
}
if old == current {
return nil
}
if err := system.ParentDeathSignal(uintptr(old)); err != nil {
return fmt.Errorf("set parent death signal %s", err)
}
// Signal self if parent is already dead. Does nothing if running in a new
// PID namespace, as Getppid will always return 0.
if syscall.Getppid() == 1 {
return syscall.Kill(syscall.Getpid(), syscall.Signal(old))
}
return nil
}
// SetupUser changes the groups, gid, and uid for the user inside the container // SetupUser changes the groups, gid, and uid for the user inside the container
func SetupUser(u string) error { func SetupUser(u string) error {
uid, gid, suppGids, err := user.GetUserGroupSupplementary(u, syscall.Getuid(), syscall.Getgid()) uid, gid, suppGids, err := user.GetUserGroupSupplementary(u, syscall.Getuid(), syscall.Getgid())

View file

@ -3,6 +3,7 @@ package system
import ( import (
"os/exec" "os/exec"
"syscall" "syscall"
"unsafe"
) )
func Chroot(dir string) error { func Chroot(dir string) error {
@ -122,6 +123,18 @@ func ParentDeathSignal(sig uintptr) error {
return nil return nil
} }
func GetParentDeathSignal() (int, error) {
var sig int
_, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_GET_PDEATHSIG, uintptr(unsafe.Pointer(&sig)), 0)
if err != 0 {
return -1, err
}
return sig, nil
}
func Setctty() error { func Setctty() error {
if _, _, err := syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0); err != 0 { if _, _, err := syscall.RawSyscall(syscall.SYS_IOCTL, 0, uintptr(syscall.TIOCSCTTY), 0); err != 0 {
return err return err