github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/client/allocdir/fs_linux.go (about) 1 // +build !android 2 3 package allocdir 4 5 import ( 6 "fmt" 7 "os" 8 "path/filepath" 9 "syscall" 10 11 "golang.org/x/sys/unix" 12 ) 13 14 const ( 15 // secretDirTmpfsSize is the size of the tmpfs per task in MBs 16 secretDirTmpfsSize = 1 17 18 // secretMarker is the filename of the marker created so Nomad doesn't 19 // try to mount the secrets tmpfs more than once 20 secretMarker = ".nomad-mount" 21 ) 22 23 // linkDir bind mounts src to dst as Linux doesn't support hardlinking 24 // directories. 25 func linkDir(src, dst string) error { 26 if err := os.MkdirAll(dst, 0777); err != nil { 27 return err 28 } 29 30 return syscall.Mount(src, dst, "", syscall.MS_BIND, "") 31 } 32 33 // unlinkDir unmounts a bind mounted directory as Linux doesn't support 34 // hardlinking directories. If the dir is already unmounted no error is 35 // returned. 36 func unlinkDir(dir string) error { 37 if err := syscall.Unmount(dir, 0); err != nil { 38 if err != syscall.EINVAL { 39 return err 40 } 41 } 42 return nil 43 } 44 45 // createSecretDir creates the secrets dir folder at the given path using a 46 // tmpfs 47 func createSecretDir(dir string) error { 48 // Only mount the tmpfs if we are root 49 if unix.Geteuid() == 0 { 50 if err := os.MkdirAll(dir, 0777); err != nil { 51 return err 52 } 53 54 // Check for marker file and skip mounting if it exists 55 marker := filepath.Join(dir, secretMarker) 56 if _, err := os.Stat(marker); err == nil { 57 return nil 58 } 59 60 var flags uintptr 61 flags = syscall.MS_NOEXEC 62 options := fmt.Sprintf("size=%dm", secretDirTmpfsSize) 63 if err := syscall.Mount("tmpfs", dir, "tmpfs", flags, options); err != nil { 64 return os.NewSyscallError("mount", err) 65 } 66 67 // Create the marker file so we don't try to mount more than once 68 f, err := os.OpenFile(marker, os.O_RDWR|os.O_CREATE, 0666) 69 if err != nil { 70 // Hard fail since if this fails something is really wrong 71 return err 72 } 73 f.Close() 74 return nil 75 } 76 77 return os.MkdirAll(dir, 0777) 78 } 79 80 // createSecretDir removes the secrets dir folder 81 func removeSecretDir(dir string) error { 82 if unix.Geteuid() == 0 { 83 if err := unlinkDir(dir); err != nil { 84 // Ignore invalid path errors 85 if err != syscall.ENOENT { 86 return os.NewSyscallError("unmount", err) 87 } 88 } 89 90 } 91 return os.RemoveAll(dir) 92 }