mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Improve general quality of libcontainer
Docker-DCO-1.1-Signed-off-by: Guillaume J. Charmes <guillaume.charmes@docker.com> (github: creack)
This commit is contained in:
		
							parent
							
								
									1142945769
								
							
						
					
					
						commit
						93d41e53ae
					
				
					 12 changed files with 159 additions and 238 deletions
				
			
		| 
						 | 
					@ -10,6 +10,9 @@ import (
 | 
				
			||||||
	"github.com/dotcloud/docker/pkg/libcontainer/network"
 | 
						"github.com/dotcloud/docker/pkg/libcontainer/network"
 | 
				
			||||||
	"github.com/dotcloud/docker/pkg/libcontainer/utils"
 | 
						"github.com/dotcloud/docker/pkg/libcontainer/utils"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
						exec_ "os/exec"
 | 
				
			||||||
 | 
						"path"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
| 
						 | 
					@ -52,6 +55,18 @@ func exec(container *libcontainer.Container) error {
 | 
				
			||||||
		container.NetNsFd = netFile.Fd()
 | 
							container.NetNsFd = netFile.Fd()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						self, err := exec_.LookPath(os.Args[0])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if output, err := exec_.Command("cp", self, path.Join(container.RootFs, ".nsinit")).CombinedOutput(); err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("Error exec cp: %s, (%s)", err, output)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							println(self, container.RootFs)
 | 
				
			||||||
 | 
							fmt.Printf("-----> %s\n", output)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						println("----")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pid, err := namespaces.ExecContainer(container)
 | 
						pid, err := namespaces.ExecContainer(container)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("error exec container %s", err)
 | 
							return fmt.Errorf("error exec container %s", err)
 | 
				
			||||||
| 
						 | 
					@ -77,25 +92,25 @@ func exec(container *libcontainer.Container) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func execIn(container *libcontainer.Container) error {
 | 
					func execIn(container *libcontainer.Container) error {
 | 
				
			||||||
	f, err := os.Open("/root/nsroot/test")
 | 
						// f, err := os.Open("/root/nsroot/test")
 | 
				
			||||||
	if err != nil {
 | 
						// if err != nil {
 | 
				
			||||||
		return err
 | 
						// 	return err
 | 
				
			||||||
	}
 | 
						// }
 | 
				
			||||||
	container.NetNsFd = f.Fd()
 | 
						// container.NetNsFd = f.Fd()
 | 
				
			||||||
	pid, err := namespaces.ExecIn(container, &libcontainer.Command{
 | 
						// pid, err := namespaces.ExecIn(container, &libcontainer.Command{
 | 
				
			||||||
		Env: container.Command.Env,
 | 
						// 	Env: container.Command.Env,
 | 
				
			||||||
		Args: []string{
 | 
						// 	Args: []string{
 | 
				
			||||||
			newCommand,
 | 
						// 		newCommand,
 | 
				
			||||||
		},
 | 
						// 	},
 | 
				
			||||||
	})
 | 
						// })
 | 
				
			||||||
	if err != nil {
 | 
						// if err != nil {
 | 
				
			||||||
		return fmt.Errorf("error exexin container %s", err)
 | 
						// 	return fmt.Errorf("error exexin container %s", err)
 | 
				
			||||||
	}
 | 
						// }
 | 
				
			||||||
	exitcode, err := utils.WaitOnPid(pid)
 | 
						// exitcode, err := utils.WaitOnPid(pid)
 | 
				
			||||||
	if err != nil {
 | 
						// if err != nil {
 | 
				
			||||||
		return fmt.Errorf("error waiting on child %s", err)
 | 
						// 	return fmt.Errorf("error waiting on child %s", err)
 | 
				
			||||||
	}
 | 
						// }
 | 
				
			||||||
	os.Exit(exitcode)
 | 
						// os.Exit(exitcode)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,11 +158,13 @@ func printErr(err error) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	var (
 | 
						cliCmd := flag.Arg(0)
 | 
				
			||||||
		err    error
 | 
					
 | 
				
			||||||
		cliCmd = flag.Arg(0)
 | 
						config, err := filepath.Abs(flag.Arg(1))
 | 
				
			||||||
		config = "/root/development/gocode/src/github.com/dotcloud/docker/pkg/libcontainer/container.json" //flag.Arg(1)
 | 
						if err != nil {
 | 
				
			||||||
	)
 | 
							printErr(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						println("cli:", cliCmd, "config:", config)
 | 
				
			||||||
	f, err := os.Open(config)
 | 
						f, err := os.Open(config)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		printErr(err)
 | 
							printErr(err)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@
 | 
				
			||||||
            "TERM=xterm"
 | 
					            "TERM=xterm"
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "rootfs": "/root/main/mycontainer",
 | 
					    "rootfs": "/var/lib/docker/containers/ee76122136d691d63e09d24168a91ddb2ef9fdcf210b4de5c50aa76354892f4b/root",
 | 
				
			||||||
    "namespaces": [
 | 
					    "namespaces": [
 | 
				
			||||||
        "NEWIPC",
 | 
					        "NEWIPC",
 | 
				
			||||||
        "NEWNS",
 | 
					        "NEWNS",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,8 @@ package namespaces
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"github.com/dotcloud/docker/pkg/libcontainer"
 | 
						"github.com/dotcloud/docker/pkg/libcontainer"
 | 
				
			||||||
 | 
						"github.com/dotcloud/docker/pkg/system"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
| 
						 | 
					@ -44,12 +44,15 @@ func ExecContainer(container *libcontainer.Container) (pid int, err error) {
 | 
				
			||||||
	// we need CLONE_VFORK so we can wait on the child
 | 
						// we need CLONE_VFORK so we can wait on the child
 | 
				
			||||||
	flag := uintptr(getNamespaceFlags(container.Namespaces) | CLONE_VFORK)
 | 
						flag := uintptr(getNamespaceFlags(container.Namespaces) | CLONE_VFORK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	command := exec.Command(nsinit, "-master", strconv.Itoa(int(master.Fd())), "-console", console, "init")
 | 
						command := exec.Command(nsinit, "-master", strconv.Itoa(int(master.Fd())), "-console", console, "init", "container.json")
 | 
				
			||||||
 | 
						// command.Stdin = os.Stdin
 | 
				
			||||||
 | 
						// command.Stdout = os.Stdout
 | 
				
			||||||
 | 
						// command.Stderr = os.Stderr
 | 
				
			||||||
	command.SysProcAttr = &syscall.SysProcAttr{}
 | 
						command.SysProcAttr = &syscall.SysProcAttr{}
 | 
				
			||||||
	command.SysProcAttr.Cloneflags = flag
 | 
						command.SysProcAttr.Cloneflags = flag
 | 
				
			||||||
	command.ExtraFiles = []*os.File{master}
 | 
						//command.ExtraFiles = []*os.File{master}
 | 
				
			||||||
	//	command.SysProcAttr.Setctty = true
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						println("vvvvvvvvv")
 | 
				
			||||||
	if err := command.Start(); err != nil {
 | 
						if err := command.Start(); err != nil {
 | 
				
			||||||
		return -1, err
 | 
							return -1, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -68,104 +71,18 @@ func ExecContainer(container *libcontainer.Container) (pid int, err error) {
 | 
				
			||||||
	return pid, nil
 | 
						return pid, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ExecIn will spawn a new command inside an existing container's namespaces.  The existing container's
 | 
					 | 
				
			||||||
// pid and namespace configuration is needed along with the specific capabilities that should
 | 
					 | 
				
			||||||
// be dropped once inside the namespace.
 | 
					 | 
				
			||||||
func ExecIn(container *libcontainer.Container, cmd *libcontainer.Command) (int, error) {
 | 
					 | 
				
			||||||
	return -1, fmt.Errorf("not implemented")
 | 
					 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
		if container.NsPid <= 0 {
 | 
					 | 
				
			||||||
			return -1, libcontainer.ErrInvalidPid
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		fds, err := getNsFds(container)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return -1, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if container.NetNsFd > 0 {
 | 
					 | 
				
			||||||
			fds = append(fds, container.NetNsFd)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		pid, err := fork()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			for _, fd := range fds {
 | 
					 | 
				
			||||||
				syscall.Close(int(fd))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return -1, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if pid == 0 {
 | 
					 | 
				
			||||||
			for _, fd := range fds {
 | 
					 | 
				
			||||||
				if fd > 0 {
 | 
					 | 
				
			||||||
					if err := JoinExistingNamespace(fd, ""); err != nil {
 | 
					 | 
				
			||||||
						for _, fd := range fds {
 | 
					 | 
				
			||||||
							syscall.Close(int(fd))
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						writeError("join existing namespace for %d %s", fd, err)
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				syscall.Close(int(fd))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if container.Namespaces.Contains(libcontainer.CLONE_NEWNS) &&
 | 
					 | 
				
			||||||
				container.Namespaces.Contains(libcontainer.CLONE_NEWPID) {
 | 
					 | 
				
			||||||
				// important:
 | 
					 | 
				
			||||||
				//
 | 
					 | 
				
			||||||
				// we need to fork and unshare so that re can remount proc and sys within
 | 
					 | 
				
			||||||
				// the namespace so the CLONE_NEWPID namespace will take effect
 | 
					 | 
				
			||||||
				// if we don't fork we would end up unmounting proc and sys for the entire
 | 
					 | 
				
			||||||
				// namespace
 | 
					 | 
				
			||||||
				child, err := fork()
 | 
					 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					writeError("fork child %s", err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if child == 0 {
 | 
					 | 
				
			||||||
					if err := unshare(CLONE_NEWNS); err != nil {
 | 
					 | 
				
			||||||
						writeError("unshare newns %s", err)
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if err := remountProc(); err != nil {
 | 
					 | 
				
			||||||
						writeError("remount proc %s", err)
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if err := remountSys(); err != nil {
 | 
					 | 
				
			||||||
						writeError("remount sys %s", err)
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if err := capabilities.DropCapabilities(container); err != nil {
 | 
					 | 
				
			||||||
						writeError("drop caps %s", err)
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if err := exec(cmd.Args[0], cmd.Args[0:], cmd.Env); err != nil {
 | 
					 | 
				
			||||||
						writeError("exec %s", err)
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					panic("unreachable")
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				exit, err := utils.WaitOnPid(child)
 | 
					 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					writeError("wait on child %s", err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				os.Exit(exit)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if err := exec(cmd.Args[0], cmd.Args[0:], cmd.Env); err != nil {
 | 
					 | 
				
			||||||
				writeError("exec %s", err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			panic("unreachable")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return pid, err
 | 
					 | 
				
			||||||
	*/
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func createMasterAndConsole() (*os.File, string, error) {
 | 
					func createMasterAndConsole() (*os.File, string, error) {
 | 
				
			||||||
	master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
 | 
						master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, "", err
 | 
							return nil, "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	console, err := Ptsname(master)
 | 
						console, err := system.Ptsname(master)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, "", err
 | 
							return nil, "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := Unlockpt(master); err != nil {
 | 
						if err := system.Unlockpt(master); err != nil {
 | 
				
			||||||
		return nil, "", err
 | 
							return nil, "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return master, console, nil
 | 
						return master, console, nil
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@ package namespaces
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"github.com/dotcloud/docker/pkg/system"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
| 
						 | 
					@ -14,16 +15,16 @@ var (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SetupNewMountNamespace(rootfs, console string, readonly bool) error {
 | 
					func SetupNewMountNamespace(rootfs, console string, readonly bool) error {
 | 
				
			||||||
	if err := Mount("", "/", "", syscall.MS_SLAVE|syscall.MS_REC, ""); err != nil {
 | 
						if err := system.Mount("", "/", "", syscall.MS_SLAVE|syscall.MS_REC, ""); err != nil {
 | 
				
			||||||
		return fmt.Errorf("mounting / as slave %s", err)
 | 
							return fmt.Errorf("mounting / as slave %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
 | 
						if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
 | 
				
			||||||
		return fmt.Errorf("mouting %s as bind %s", rootfs, err)
 | 
							return fmt.Errorf("mouting %s as bind %s", rootfs, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if readonly {
 | 
						if readonly {
 | 
				
			||||||
		if err := Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, ""); err != nil {
 | 
							if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, ""); err != nil {
 | 
				
			||||||
			return fmt.Errorf("mounting %s as readonly %s", rootfs, err)
 | 
								return fmt.Errorf("mounting %s as readonly %s", rootfs, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -52,29 +53,30 @@ func SetupNewMountNamespace(rootfs, console string, readonly bool) error {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := Chdir(rootfs); err != nil {
 | 
						if err := system.Chdir(rootfs); err != nil {
 | 
				
			||||||
		return fmt.Errorf("chdir into %s %s", rootfs, err)
 | 
							return fmt.Errorf("chdir into %s %s", rootfs, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
 | 
						if err := system.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
 | 
				
			||||||
		return fmt.Errorf("mount move %s into / %s", rootfs, err)
 | 
							return fmt.Errorf("mount move %s into / %s", rootfs, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := Chroot("."); err != nil {
 | 
						if err := system.Chroot("."); err != nil {
 | 
				
			||||||
		return fmt.Errorf("chroot . %s", err)
 | 
							return fmt.Errorf("chroot . %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := Chdir("/"); err != nil {
 | 
						if err := system.Chdir("/"); err != nil {
 | 
				
			||||||
		return fmt.Errorf("chdir / %s", err)
 | 
							return fmt.Errorf("chdir / %s", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Umask(0022)
 | 
						system.Umask(0022)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func copyDevNodes(rootfs string) error {
 | 
					func copyDevNodes(rootfs string) error {
 | 
				
			||||||
	Umask(0000)
 | 
						oldMask := system.Umask(0000)
 | 
				
			||||||
 | 
						defer system.Umask(oldMask)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, node := range []string{
 | 
						for _, node := range []string{
 | 
				
			||||||
		"null",
 | 
							"null",
 | 
				
			||||||
| 
						 | 
					@ -95,7 +97,7 @@ func copyDevNodes(rootfs string) error {
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log.Printf("copy %s to %s %d\n", node, dest, st.Rdev)
 | 
							log.Printf("copy %s to %s %d\n", node, dest, st.Rdev)
 | 
				
			||||||
		if err := Mknod(dest, st.Mode, int(st.Rdev)); err != nil && !os.IsExist(err) {
 | 
							if err := system.Mknod(dest, st.Mode, int(st.Rdev)); err != nil && !os.IsExist(err) {
 | 
				
			||||||
			return fmt.Errorf("copy %s %s", node, err)
 | 
								return fmt.Errorf("copy %s %s", node, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -125,7 +127,8 @@ func setupDev(rootfs string) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func setupConsole(rootfs, console string) error {
 | 
					func setupConsole(rootfs, console string) error {
 | 
				
			||||||
	Umask(0000)
 | 
						oldMask := system.Umask(0000)
 | 
				
			||||||
 | 
						defer system.Umask(oldMask)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stat, err := os.Stat(console)
 | 
						stat, err := os.Stat(console)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -145,11 +148,11 @@ func setupConsole(rootfs, console string) error {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := Mknod(dest, (st.Mode&^07777)|0600, int(st.Rdev)); err != nil {
 | 
						if err := system.Mknod(dest, (st.Mode&^07777)|0600, int(st.Rdev)); err != nil {
 | 
				
			||||||
		return fmt.Errorf("mknod %s %s", dest, err)
 | 
							return fmt.Errorf("mknod %s %s", dest, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := Mount(console, dest, "bind", syscall.MS_BIND, ""); err != nil {
 | 
						if err := system.Mount(console, dest, "bind", syscall.MS_BIND, ""); err != nil {
 | 
				
			||||||
		return fmt.Errorf("bind %s to %s %s", console, dest, err)
 | 
							return fmt.Errorf("bind %s to %s %s", console, dest, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					@ -158,7 +161,7 @@ func setupConsole(rootfs, console string) error {
 | 
				
			||||||
// mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts
 | 
					// mountSystem sets up linux specific system mounts like sys, proc, shm, and devpts
 | 
				
			||||||
// inside the mount namespace
 | 
					// inside the mount namespace
 | 
				
			||||||
func mountSystem(rootfs string) error {
 | 
					func mountSystem(rootfs string) error {
 | 
				
			||||||
	mounts := []struct {
 | 
						for _, m := range []struct {
 | 
				
			||||||
		source string
 | 
							source string
 | 
				
			||||||
		path   string
 | 
							path   string
 | 
				
			||||||
		device string
 | 
							device string
 | 
				
			||||||
| 
						 | 
					@ -171,12 +174,11 @@ func mountSystem(rootfs string) error {
 | 
				
			||||||
		{source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaults, data: "mode=1777"},
 | 
							{source: "shm", path: filepath.Join(rootfs, "dev", "shm"), device: "tmpfs", flags: defaults, data: "mode=1777"},
 | 
				
			||||||
		{source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: "newinstance,ptmxmode=0666,mode=620,gid=5"},
 | 
							{source: "devpts", path: filepath.Join(rootfs, "dev", "pts"), device: "devpts", flags: syscall.MS_NOSUID | syscall.MS_NOEXEC, data: "newinstance,ptmxmode=0666,mode=620,gid=5"},
 | 
				
			||||||
		{source: "tmpfs", path: filepath.Join(rootfs, "run"), device: "tmpfs", flags: syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_STRICTATIME, data: "mode=755"},
 | 
							{source: "tmpfs", path: filepath.Join(rootfs, "run"), device: "tmpfs", flags: syscall.MS_NOSUID | syscall.MS_NODEV | syscall.MS_STRICTATIME, data: "mode=755"},
 | 
				
			||||||
	}
 | 
						} {
 | 
				
			||||||
	for _, m := range mounts {
 | 
					 | 
				
			||||||
		if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) {
 | 
							if err := os.MkdirAll(m.path, 0755); err != nil && !os.IsExist(err) {
 | 
				
			||||||
			return fmt.Errorf("mkdirall %s %s", m.path, err)
 | 
								return fmt.Errorf("mkdirall %s %s", m.path, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err := Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil {
 | 
							if err := system.Mount(m.source, m.path, m.device, uintptr(m.flags), m.data); err != nil {
 | 
				
			||||||
			return fmt.Errorf("mounting %s into %s %s", m.source, m.path, err)
 | 
								return fmt.Errorf("mounting %s into %s %s", m.source, m.path, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -184,22 +186,22 @@ func mountSystem(rootfs string) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func remountProc() error {
 | 
					func remountProc() error {
 | 
				
			||||||
	if err := Unmount("/proc", syscall.MNT_DETACH); err != nil {
 | 
						if err := system.Unmount("/proc", syscall.MNT_DETACH); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := Mount("proc", "/proc", "proc", uintptr(defaults), ""); err != nil {
 | 
						if err := system.Mount("proc", "/proc", "proc", uintptr(defaults), ""); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func remountSys() error {
 | 
					func remountSys() error {
 | 
				
			||||||
	if err := Unmount("/sys", syscall.MNT_DETACH); err != nil {
 | 
						if err := system.Unmount("/sys", syscall.MNT_DETACH); err != nil {
 | 
				
			||||||
		if err != syscall.EINVAL {
 | 
							if err != syscall.EINVAL {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if err := Mount("sysfs", "/sys", "sysfs", uintptr(defaults), ""); err != nil {
 | 
							if err := system.Mount("sysfs", "/sys", "sysfs", uintptr(defaults), ""); err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,32 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
   TODO
 | 
					 | 
				
			||||||
   pivot root
 | 
					 | 
				
			||||||
   cgroups
 | 
					 | 
				
			||||||
   more mount stuff that I probably am forgetting
 | 
					 | 
				
			||||||
   apparmor
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package namespaces
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"github.com/dotcloud/docker/pkg/libcontainer"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// JoinExistingNamespace uses the fd of an existing linux namespace and
 | 
					 | 
				
			||||||
// has the current process join that namespace or the spacespace specified by ns
 | 
					 | 
				
			||||||
func JoinExistingNamespace(fd uintptr, ns libcontainer.Namespace) error {
 | 
					 | 
				
			||||||
	flag := namespaceMap[ns]
 | 
					 | 
				
			||||||
	if err := Setns(fd, uintptr(flag)); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// getNamespaceFlags parses the container's Namespaces options to set the correct
 | 
					 | 
				
			||||||
// flags on clone, unshare, and setns
 | 
					 | 
				
			||||||
func getNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {
 | 
					 | 
				
			||||||
	for _, ns := range namespaces {
 | 
					 | 
				
			||||||
		flag |= namespaceMap[ns]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -33,3 +33,12 @@ var namespaceFileMap = map[libcontainer.Namespace]string{
 | 
				
			||||||
	libcontainer.CLONE_NEWPID:  "pid",
 | 
						libcontainer.CLONE_NEWPID:  "pid",
 | 
				
			||||||
	libcontainer.CLONE_NEWNET:  "net",
 | 
						libcontainer.CLONE_NEWNET:  "net",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// getNamespaceFlags parses the container's Namespaces options to set the correct
 | 
				
			||||||
 | 
					// flags on clone, unshare, and setns
 | 
				
			||||||
 | 
					func getNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {
 | 
				
			||||||
 | 
						for _, ns := range namespaces {
 | 
				
			||||||
 | 
							flag |= namespaceMap[ns]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ import (
 | 
				
			||||||
	"github.com/dotcloud/docker/pkg/libcontainer"
 | 
						"github.com/dotcloud/docker/pkg/libcontainer"
 | 
				
			||||||
	"github.com/dotcloud/docker/pkg/libcontainer/capabilities"
 | 
						"github.com/dotcloud/docker/pkg/libcontainer/capabilities"
 | 
				
			||||||
	"github.com/dotcloud/docker/pkg/libcontainer/namespaces"
 | 
						"github.com/dotcloud/docker/pkg/libcontainer/namespaces"
 | 
				
			||||||
 | 
						"github.com/dotcloud/docker/pkg/system"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
| 
						 | 
					@ -14,10 +15,12 @@ import (
 | 
				
			||||||
// InitNamespace should be run inside an existing namespace to setup
 | 
					// InitNamespace should be run inside an existing namespace to setup
 | 
				
			||||||
// common mounts, drop capabilities, and setup network interfaces
 | 
					// common mounts, drop capabilities, and setup network interfaces
 | 
				
			||||||
func InitNamespace(container *libcontainer.Container) error {
 | 
					func InitNamespace(container *libcontainer.Container) error {
 | 
				
			||||||
 | 
						println("|||||||||||||")
 | 
				
			||||||
	if err := setLogFile(container); err != nil {
 | 
						if err := setLogFile(container); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						println(container.LogFile)
 | 
				
			||||||
 | 
						log.Printf("--------->")
 | 
				
			||||||
	rootfs, err := resolveRootfs(container)
 | 
						rootfs, err := resolveRootfs(container)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
| 
						 | 
					@ -26,7 +29,7 @@ func InitNamespace(container *libcontainer.Container) error {
 | 
				
			||||||
	// any errors encoutered inside the namespace we should write
 | 
						// any errors encoutered inside the namespace we should write
 | 
				
			||||||
	// out to a log or a pipe to our parent and exit(1)
 | 
						// out to a log or a pipe to our parent and exit(1)
 | 
				
			||||||
	// because writing to stderr will not work after we close
 | 
						// because writing to stderr will not work after we close
 | 
				
			||||||
	if err := closeMasterAndStd(container.Master); err != nil {
 | 
						if err := closeMasterAndStd(os.NewFile(container.Master, "/dev/ptmx")); err != nil {
 | 
				
			||||||
		log.Fatalf("close master and std %s", err)
 | 
							log.Fatalf("close master and std %s", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -49,15 +52,15 @@ func InitNamespace(container *libcontainer.Container) error {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if _, err := namespaces.Setsid(); err != nil {
 | 
						if _, err := system.Setsid(); err != nil {
 | 
				
			||||||
		log.Fatalf("setsid %s", err)
 | 
							log.Fatalf("setsid %s", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := namespaces.Setctty(); err != nil {
 | 
						if err := system.Setctty(); err != nil {
 | 
				
			||||||
		log.Fatalf("setctty %s", err)
 | 
							log.Fatalf("setctty %s", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := namespaces.ParentDeathSignal(); err != nil {
 | 
						if err := system.ParentDeathSignal(); err != nil {
 | 
				
			||||||
		log.Fatalf("parent deth signal %s", err)
 | 
							log.Fatalf("parent deth signal %s", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -65,7 +68,7 @@ func InitNamespace(container *libcontainer.Container) error {
 | 
				
			||||||
		log.Fatalf("setup mount namespace %s", err)
 | 
							log.Fatalf("setup mount namespace %s", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := namespaces.Sethostname(container.ID); err != nil {
 | 
						if err := system.Sethostname(container.ID); err != nil {
 | 
				
			||||||
		log.Fatalf("sethostname %s", err)
 | 
							log.Fatalf("sethostname %s", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -78,12 +81,12 @@ func InitNamespace(container *libcontainer.Container) error {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if container.WorkingDir != "" {
 | 
						if container.WorkingDir != "" {
 | 
				
			||||||
		if err := namespaces.Chdir(container.WorkingDir); err != nil {
 | 
							if err := system.Chdir(container.WorkingDir); err != nil {
 | 
				
			||||||
			log.Fatalf("chdir to %s %s", container.WorkingDir, err)
 | 
								log.Fatalf("chdir to %s %s", container.WorkingDir, err)
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := namespaces.Exec(container.Command.Args[0], container.Command.Args[0:], container.Command.Env); err != nil {
 | 
						if err := system.Exec(container.Command.Args[0], container.Command.Args[0:], container.Command.Env); err != nil {
 | 
				
			||||||
		log.Fatalf("exec %s", err)
 | 
							log.Fatalf("exec %s", err)
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -98,24 +101,23 @@ func resolveRootfs(container *libcontainer.Container) (string, error) {
 | 
				
			||||||
	return filepath.EvalSymlinks(rootfs)
 | 
						return filepath.EvalSymlinks(rootfs)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func closeMasterAndStd(master uintptr) error {
 | 
					func closeMasterAndStd(master *os.File) error {
 | 
				
			||||||
	namespaces.Closefd(master)
 | 
						master.Close()
 | 
				
			||||||
	namespaces.Closefd(0)
 | 
						os.Stdin.Close()
 | 
				
			||||||
	namespaces.Closefd(1)
 | 
						os.Stdout.Close()
 | 
				
			||||||
	namespaces.Closefd(2)
 | 
						os.Stderr.Close()
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func setupUser(container *libcontainer.Container) error {
 | 
					func setupUser(container *libcontainer.Container) error {
 | 
				
			||||||
	// TODO: honor user passed on container
 | 
						// TODO: honor user passed on container
 | 
				
			||||||
	if err := namespaces.Setgroups(nil); err != nil {
 | 
						if err := system.Setgroups(nil); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := namespaces.Setresgid(0, 0, 0); err != nil {
 | 
						if err := system.Setresgid(0, 0, 0); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := namespaces.Setresuid(0, 0, 0); err != nil {
 | 
						if err := system.Setresuid(0, 0, 0); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
| 
						 | 
					@ -126,15 +128,16 @@ func dupSlave(slave *os.File) error {
 | 
				
			||||||
	if slave.Fd() != 0 {
 | 
						if slave.Fd() != 0 {
 | 
				
			||||||
		return fmt.Errorf("slave fd not 0 %d", slave.Fd())
 | 
							return fmt.Errorf("slave fd not 0 %d", slave.Fd())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := namespaces.Dup2(slave.Fd(), 1); err != nil {
 | 
						if err := system.Dup2(slave.Fd(), 1); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := namespaces.Dup2(slave.Fd(), 2); err != nil {
 | 
						if err := system.Dup2(slave.Fd(), 2); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// openTerminal is a clone of os.OpenFile without the O_CLOEXEC addition.
 | 
				
			||||||
func openTerminal(name string, flag int) (*os.File, error) {
 | 
					func openTerminal(name string, flag int) (*os.File, error) {
 | 
				
			||||||
	r, e := syscall.Open(name, flag, 0)
 | 
						r, e := syscall.Open(name, flag, 0)
 | 
				
			||||||
	if e != nil {
 | 
						if e != nil {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -72,17 +72,3 @@ func setupEnvironment(container *libcontainer.Container) {
 | 
				
			||||||
	addEnvIfNotSet(container, "USER", "root")
 | 
						addEnvIfNotSet(container, "USER", "root")
 | 
				
			||||||
	addEnvIfNotSet(container, "LOGNAME", "root")
 | 
						addEnvIfNotSet(container, "LOGNAME", "root")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func getMasterAndConsole(container *libcontainer.Container) (string, *os.File, error) {
 | 
					 | 
				
			||||||
	master, err := Openpmtx()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	console, err := Ptsname(master)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		master.Close()
 | 
					 | 
				
			||||||
		return "", nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return console, master, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,15 +1,7 @@
 | 
				
			||||||
package namespaces
 | 
					package system
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
	"unsafe"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	TIOCGPTN   = 0x80045430
 | 
					 | 
				
			||||||
	TIOCSPTLCK = 0x40045431
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Chroot(dir string) error {
 | 
					func Chroot(dir string) error {
 | 
				
			||||||
| 
						 | 
					@ -60,14 +52,6 @@ func Clone(flags uintptr) (int, error) {
 | 
				
			||||||
	return int(pid), nil
 | 
						return int(pid), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Setns(fd uintptr, flags uintptr) error {
 | 
					 | 
				
			||||||
	_, _, err := syscall.RawSyscall(SYS_SETNS, fd, flags, 0)
 | 
					 | 
				
			||||||
	if err != 0 {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func UsetCloseOnExec(fd uintptr) error {
 | 
					func UsetCloseOnExec(fd uintptr) error {
 | 
				
			||||||
	if _, _, err := syscall.Syscall(syscall.SYS_FCNTL, fd, syscall.F_SETFD, 0); err != 0 {
 | 
						if _, _, err := syscall.Syscall(syscall.SYS_FCNTL, fd, syscall.F_SETFD, 0); err != 0 {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
| 
						 | 
					@ -95,11 +79,6 @@ func Setsid() (int, error) {
 | 
				
			||||||
	return syscall.Setsid()
 | 
						return syscall.Setsid()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Unlockpt(f *os.File) error {
 | 
					 | 
				
			||||||
	var u int
 | 
					 | 
				
			||||||
	return Ioctl(f.Fd(), TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func Ioctl(fd uintptr, flag, data uintptr) error {
 | 
					func Ioctl(fd uintptr, flag, data uintptr) error {
 | 
				
			||||||
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, flag, data); err != 0 {
 | 
						if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, flag, data); err != 0 {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
| 
						 | 
					@ -107,18 +86,6 @@ func Ioctl(fd uintptr, flag, data uintptr) error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Ptsname(f *os.File) (string, error) {
 | 
					 | 
				
			||||||
	var n int
 | 
					 | 
				
			||||||
	if err := Ioctl(f.Fd(), TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return fmt.Sprintf("/dev/pts/%d", n), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func Openpmtx() (*os.File, error) {
 | 
					 | 
				
			||||||
	return os.OpenFile("/dev/ptmx", syscall.O_RDONLY|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func Closefd(fd uintptr) error {
 | 
					func Closefd(fd uintptr) error {
 | 
				
			||||||
	return syscall.Close(int(fd))
 | 
						return syscall.Close(int(fd))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -132,7 +99,7 @@ func Mknod(path string, mode uint32, dev int) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ParentDeathSignal() error {
 | 
					func ParentDeathSignal() error {
 | 
				
			||||||
	if _, _, err := syscall.RawSyscall6(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, uintptr(syscall.SIGKILL), 0, 0, 0, 0); err != 0 {
 | 
						if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, uintptr(syscall.SIGKILL), 0); err != 0 {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
							
								
								
									
										31
									
								
								pkg/system/pty_linux.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								pkg/system/pty_linux.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					package system
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
 | 
						"unsafe"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
 | 
				
			||||||
 | 
					// Unlockpt should be called before opening the slave side of a pseudoterminal.
 | 
				
			||||||
 | 
					func Unlockpt(f *os.File) error {
 | 
				
			||||||
 | 
						var u int
 | 
				
			||||||
 | 
						return Ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Ptsname retrieves the name of the first available pts for the given master.
 | 
				
			||||||
 | 
					func Ptsname(f *os.File) (string, error) {
 | 
				
			||||||
 | 
						var n int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := Ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return fmt.Sprintf("/dev/pts/%d", n), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OpenPtmx opens /dev/ptmx, i.e. the PTY master.
 | 
				
			||||||
 | 
					func OpenPtmx() (*os.File, error) {
 | 
				
			||||||
 | 
						// O_NOCTTY and O_CLOEXEC are not present in os package so we use the syscall's one for all.
 | 
				
			||||||
 | 
						return os.OpenFile("/dev/ptmx", syscall.O_RDONLY|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								pkg/system/setns_linux.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								pkg/system/setns_linux.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					package system
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Setns(fd uintptr, flags uintptr) error {
 | 
				
			||||||
 | 
						_, _, err := syscall.RawSyscall(SYS_SETNS, fd, flags, 0)
 | 
				
			||||||
 | 
						if err != 0 {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								pkg/system/setns_linux_amd64.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								pkg/system/setns_linux_amd64.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					// +build linux,amd64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package system
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Via http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=7b21fddd087678a70ad64afc0f632e0f1071b092
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						SYS_SETNS = 308
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue