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