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 }