github.com/mattyr/nomad@v0.3.3-0.20160919021406-3485a065154a/client/allocdir/alloc_dir_linux.go (about) 1 package allocdir 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "syscall" 8 9 "golang.org/x/sys/unix" 10 11 "github.com/hashicorp/go-multierror" 12 ) 13 14 const ( 15 // secretDirTmpfsSize is the size of the tmpfs per task in MBs 16 secretDirTmpfsSize = 1 17 ) 18 19 // Bind mounts the shared directory into the task directory. Must be root to 20 // run. 21 func (d *AllocDir) mountSharedDir(taskDir string) error { 22 if err := os.MkdirAll(taskDir, 0777); err != nil { 23 return err 24 } 25 26 return syscall.Mount(d.SharedDir, taskDir, "", syscall.MS_BIND, "") 27 } 28 29 func (d *AllocDir) unmountSharedDir(dir string) error { 30 return syscall.Unmount(dir, 0) 31 } 32 33 // createSecretDir creates the secrets dir folder at the given path using a 34 // tmpfs 35 func (d *AllocDir) createSecretDir(dir string) error { 36 // Only mount the tmpfs if we are root 37 if unix.Geteuid() == 0 { 38 if err := os.MkdirAll(dir, 0777); err != nil { 39 return err 40 } 41 42 var flags uintptr 43 flags = syscall.MS_NOEXEC 44 options := fmt.Sprintf("size=%dm", secretDirTmpfsSize) 45 err := syscall.Mount("tmpfs", dir, "tmpfs", flags, options) 46 return os.NewSyscallError("mount", err) 47 } 48 49 return os.MkdirAll(dir, 0777) 50 } 51 52 // createSecretDir removes the secrets dir folder 53 func (d *AllocDir) removeSecretDir(dir string) error { 54 if unix.Geteuid() == 0 { 55 if err := syscall.Unmount(dir, 0); err != nil { 56 return os.NewSyscallError("unmount", err) 57 } 58 } 59 60 return os.RemoveAll(dir) 61 } 62 63 // MountSpecialDirs mounts the dev and proc file system from the host to the 64 // chroot 65 func (d *AllocDir) MountSpecialDirs(taskDir string) error { 66 // Mount dev 67 dev := filepath.Join(taskDir, "dev") 68 if !d.pathExists(dev) { 69 if err := os.MkdirAll(dev, 0777); err != nil { 70 return fmt.Errorf("Mkdir(%v) failed: %v", dev, err) 71 } 72 73 if err := syscall.Mount("none", dev, "devtmpfs", syscall.MS_RDONLY, ""); err != nil { 74 return fmt.Errorf("Couldn't mount /dev to %v: %v", dev, err) 75 } 76 } 77 78 // Mount proc 79 proc := filepath.Join(taskDir, "proc") 80 if !d.pathExists(proc) { 81 if err := os.MkdirAll(proc, 0777); err != nil { 82 return fmt.Errorf("Mkdir(%v) failed: %v", proc, err) 83 } 84 85 if err := syscall.Mount("none", proc, "proc", syscall.MS_RDONLY, ""); err != nil { 86 return fmt.Errorf("Couldn't mount /proc to %v: %v", proc, err) 87 } 88 } 89 90 return nil 91 } 92 93 // unmountSpecialDirs unmounts the dev and proc file system from the chroot 94 func (d *AllocDir) unmountSpecialDirs(taskDir string) error { 95 errs := new(multierror.Error) 96 dev := filepath.Join(taskDir, "dev") 97 if d.pathExists(dev) { 98 if err := syscall.Unmount(dev, 0); err != nil { 99 errs = multierror.Append(errs, fmt.Errorf("Failed to unmount dev (%v): %v", dev, err)) 100 } else if err := os.RemoveAll(dev); err != nil { 101 errs = multierror.Append(errs, fmt.Errorf("Failed to delete dev directory (%v): %v", dev, err)) 102 } 103 } 104 105 // Unmount proc. 106 proc := filepath.Join(taskDir, "proc") 107 if d.pathExists(proc) { 108 if err := syscall.Unmount(proc, 0); err != nil { 109 errs = multierror.Append(errs, fmt.Errorf("Failed to unmount proc (%v): %v", proc, err)) 110 } else if err := os.RemoveAll(proc); err != nil { 111 errs = multierror.Append(errs, fmt.Errorf("Failed to delete proc directory (%v): %v", dev, err)) 112 } 113 } 114 115 return errs.ErrorOrNil() 116 }