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  }