github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/containerizer/system/rootfs_linux.go (about)

     1  package system
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"syscall"
     7  )
     8  
     9  type RootFS struct {
    10  	Root string
    11  }
    12  
    13  func must(err error) {
    14  	if err != nil {
    15  		panic(err)
    16  	}
    17  }
    18  
    19  func (r *RootFS) Enter() error {
    20  	if err := checkDirectory(r.Root); err != nil {
    21  		return err
    22  	}
    23  
    24  	if err := syscall.Mount(r.Root, r.Root, "", uintptr(syscall.MS_BIND|syscall.MS_REC), ""); err != nil {
    25  		return fmt.Errorf("system: failed to bind mount the root filesystem onto itself: %s", err)
    26  	}
    27  
    28  	if err := os.Chdir(r.Root); err != nil {
    29  		return fmt.Errorf("system: failed to change directory into the bind mounted rootfs dir: %s", err)
    30  	}
    31  
    32  	if err := os.MkdirAll("tmp/garden-host", 0700); err != nil {
    33  		return fmt.Errorf("system: mkdir: %s", err)
    34  	}
    35  
    36  	if err := syscall.PivotRoot(".", "tmp/garden-host"); err != nil {
    37  		return fmt.Errorf("system: failed to pivot root: %s", err)
    38  	}
    39  
    40  	if err := os.Chdir("/"); err != nil {
    41  		return fmt.Errorf("system: failed to chdir to new root: %s", err)
    42  	}
    43  
    44  	return nil
    45  }
    46  
    47  func checkDirectory(dir string) error {
    48  	if fi, err := os.Stat(dir); err != nil {
    49  		return fmt.Errorf("system: validate root file system: %v", err)
    50  	} else if !fi.IsDir() {
    51  		return fmt.Errorf("system: validate root file system: %s is not a directory", dir)
    52  	}
    53  
    54  	return nil
    55  }