Пример #1
0
func mountTmpfs(dirname string) bool {
	var statfs syscall.Statfs_t
	if err := syscall.Statfs(dirname, &statfs); err != nil {
		fmt.Fprintf(os.Stderr, "Unable to create Statfs: %s: %s\n",
			dirname, err)
		return false
	}
	if statfs.Type != 0x01021994 {
		err := wsyscall.Mount("none", dirname, "tmpfs", 0,
			"size=65536,mode=0750")
		if err == nil {
			fmt.Printf("Mounted tmpfs on: %s\n", dirname)
		} else {
			fmt.Fprintf(os.Stderr, "Unable to mount tmpfs on: %s: %s\n",
				dirname, err)
			return false
		}
	}
	return true
}
Пример #2
0
func unshareAndBind(workingRootDir string) bool {
	if *unshare {
		// Re-exec myself using the unshare syscall while on a locked thread.
		// This hack is required because syscall.Unshare() operates on only one
		// thread in the process, and Go switches execution between threads
		// randomly. Thus, the namespace can be suddenly switched for running
		// code. This is an aspect of Go that was not well thought out.
		runtime.LockOSThread()
		if err := wsyscall.UnshareMountNamespace(); err != nil {
			fmt.Fprintf(os.Stderr, "Unable to unshare mount namesace: %s\n",
				err)
			return false
		}
		// Ensure the process is slightly niced. Since the Linux implementation
		// of setpriority(2) only applies to a thread, not the whole process
		// (contrary to the POSIX specification), do this in the pinned OS
		// thread so that the whole process (after exec) will be niced.
		syscall.Setpriority(syscall.PRIO_PROCESS, 0, 1)
		args := append(os.Args, "-unshare=false")
		if err := syscall.Exec(args[0], args, os.Environ()); err != nil {
			fmt.Fprintf(os.Stderr, "Unable to Exec:%s: %s\n", args[0], err)
			return false
		}
	}
	syscall.Unmount(workingRootDir, 0)
	err := wsyscall.Mount(*rootDir, workingRootDir, "", wsyscall.MS_BIND, "")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to bind mount %s to %s: %s\n",
			*rootDir, workingRootDir, err)
		return false
	}
	// Clean up -unshare=false so that a subsequent re-exec starts from scratch.
	args := make([]string, 0, len(os.Args)-1)
	for _, arg := range os.Args {
		if arg != "-unshare=false" {
			args = append(args, arg)
		}
	}
	os.Args = args
	return true
}