gopkg.in/dotcloud/docker.v1@v1.13.1/daemon/graphdriver/overlay2/mount.go (about)

     1  // +build linux
     2  
     3  package overlay2
     4  
     5  import (
     6  	"bytes"
     7  	"encoding/json"
     8  	"flag"
     9  	"fmt"
    10  	"os"
    11  	"runtime"
    12  	"syscall"
    13  
    14  	"github.com/docker/docker/pkg/reexec"
    15  )
    16  
    17  func init() {
    18  	reexec.Register("docker-mountfrom", mountFromMain)
    19  }
    20  
    21  func fatal(err error) {
    22  	fmt.Fprint(os.Stderr, err)
    23  	os.Exit(1)
    24  }
    25  
    26  type mountOptions struct {
    27  	Device string
    28  	Target string
    29  	Type   string
    30  	Label  string
    31  	Flag   uint32
    32  }
    33  
    34  func mountFrom(dir, device, target, mType string, flags uintptr, label string) error {
    35  	options := &mountOptions{
    36  		Device: device,
    37  		Target: target,
    38  		Type:   mType,
    39  		Flag:   uint32(flags),
    40  		Label:  label,
    41  	}
    42  
    43  	cmd := reexec.Command("docker-mountfrom", dir)
    44  	w, err := cmd.StdinPipe()
    45  	if err != nil {
    46  		return fmt.Errorf("mountfrom error on pipe creation: %v", err)
    47  	}
    48  
    49  	output := bytes.NewBuffer(nil)
    50  	cmd.Stdout = output
    51  	cmd.Stderr = output
    52  
    53  	if err := cmd.Start(); err != nil {
    54  		return fmt.Errorf("mountfrom error on re-exec cmd: %v", err)
    55  	}
    56  	//write the options to the pipe for the untar exec to read
    57  	if err := json.NewEncoder(w).Encode(options); err != nil {
    58  		return fmt.Errorf("mountfrom json encode to pipe failed: %v", err)
    59  	}
    60  	w.Close()
    61  
    62  	if err := cmd.Wait(); err != nil {
    63  		return fmt.Errorf("mountfrom re-exec error: %v: output: %s", err, output)
    64  	}
    65  	return nil
    66  }
    67  
    68  // mountfromMain is the entry-point for docker-mountfrom on re-exec.
    69  func mountFromMain() {
    70  	runtime.LockOSThread()
    71  	flag.Parse()
    72  
    73  	var options *mountOptions
    74  
    75  	if err := json.NewDecoder(os.Stdin).Decode(&options); err != nil {
    76  		fatal(err)
    77  	}
    78  
    79  	if err := os.Chdir(flag.Arg(0)); err != nil {
    80  		fatal(err)
    81  	}
    82  
    83  	if err := syscall.Mount(options.Device, options.Target, options.Type, uintptr(options.Flag), options.Label); err != nil {
    84  		fatal(err)
    85  	}
    86  
    87  	os.Exit(0)
    88  }