github.com/hhrutter/nomad@v0.6.0-rc2.0.20170723054333-80c4b03f0705/client/allocdir/task_dir_linux.go (about)

     1  package allocdir
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"syscall"
     8  
     9  	"github.com/hashicorp/go-multierror"
    10  )
    11  
    12  // mountSpecialDirs mounts the dev and proc file system from the host to the
    13  // chroot
    14  func (t *TaskDir) mountSpecialDirs() error {
    15  	// Mount dev
    16  	dev := filepath.Join(t.Dir, "dev")
    17  	if !pathExists(dev) {
    18  		if err := os.Mkdir(dev, 0777); err != nil {
    19  			return fmt.Errorf("Mkdir(%v) failed: %v", dev, err)
    20  		}
    21  	}
    22  	devEmpty, err := pathEmpty(dev)
    23  	if err != nil {
    24  		return fmt.Errorf("error listing %q: %v", dev, err)
    25  	}
    26  	if devEmpty {
    27  		if err := syscall.Mount("none", dev, "devtmpfs", syscall.MS_RDONLY, ""); err != nil {
    28  			return fmt.Errorf("Couldn't mount /dev to %v: %v", dev, err)
    29  		}
    30  	}
    31  
    32  	// Mount proc
    33  	proc := filepath.Join(t.Dir, "proc")
    34  	if !pathExists(proc) {
    35  		if err := os.Mkdir(proc, 0777); err != nil {
    36  			return fmt.Errorf("Mkdir(%v) failed: %v", proc, err)
    37  		}
    38  	}
    39  	procEmpty, err := pathEmpty(proc)
    40  	if err != nil {
    41  		return fmt.Errorf("error listing %q: %v", proc, err)
    42  	}
    43  	if procEmpty {
    44  		if err := syscall.Mount("none", proc, "proc", syscall.MS_RDONLY, ""); err != nil {
    45  			return fmt.Errorf("Couldn't mount /proc to %v: %v", proc, err)
    46  		}
    47  	}
    48  
    49  	return nil
    50  }
    51  
    52  // unmountSpecialDirs unmounts the dev and proc file system from the chroot. No
    53  // error is returned if the directories do not exist or have already been
    54  // unmounted.
    55  func (t *TaskDir) unmountSpecialDirs() error {
    56  	errs := new(multierror.Error)
    57  	dev := filepath.Join(t.Dir, "dev")
    58  	if pathExists(dev) {
    59  		if err := unlinkDir(dev); err != nil {
    60  			errs = multierror.Append(errs, fmt.Errorf("Failed to unmount dev %q: %v", dev, err))
    61  		} else if err := os.RemoveAll(dev); err != nil {
    62  			errs = multierror.Append(errs, fmt.Errorf("Failed to delete dev directory %q: %v", dev, err))
    63  		}
    64  	}
    65  
    66  	// Unmount proc.
    67  	proc := filepath.Join(t.Dir, "proc")
    68  	if pathExists(proc) {
    69  		if err := unlinkDir(proc); err != nil {
    70  			errs = multierror.Append(errs, fmt.Errorf("Failed to unmount proc %q: %v", proc, err))
    71  		} else if err := os.RemoveAll(proc); err != nil {
    72  			errs = multierror.Append(errs, fmt.Errorf("Failed to delete proc directory %q: %v", dev, err))
    73  		}
    74  	}
    75  
    76  	return errs.ErrorOrNil()
    77  }