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  }