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  }