github.com/anuvu/storage@v1.12.13/drivers/overlay/mount.go (about)

     1  // +build linux
     2  
     3  package overlay
     4  
     5  import (
     6  	"bytes"
     7  	"encoding/json"
     8  	"flag"
     9  	"fmt"
    10  	"os"
    11  	"runtime"
    12  
    13  	"github.com/containers/storage/pkg/reexec"
    14  	"golang.org/x/sys/unix"
    15  )
    16  
    17  func init() {
    18  	reexec.Register("storage-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("storage-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  	if err := cmd.Start(); err != nil {
    53  		w.Close()
    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  		w.Close()
    59  		return fmt.Errorf("mountfrom json encode to pipe failed: %v", err)
    60  	}
    61  	w.Close()
    62  
    63  	if err := cmd.Wait(); err != nil {
    64  		return fmt.Errorf("mountfrom re-exec error: %v: output: %v", err, output)
    65  	}
    66  	return nil
    67  }
    68  
    69  // mountfromMain is the entry-point for storage-mountfrom on re-exec.
    70  func mountFromMain() {
    71  	runtime.LockOSThread()
    72  	flag.Parse()
    73  
    74  	var options *mountOptions
    75  
    76  	if err := json.NewDecoder(os.Stdin).Decode(&options); err != nil {
    77  		fatal(err)
    78  	}
    79  
    80  	if err := os.Chdir(flag.Arg(0)); err != nil {
    81  		fatal(err)
    82  	}
    83  
    84  	if err := unix.Mount(options.Device, options.Target, options.Type, uintptr(options.Flag), options.Label); err != nil {
    85  		fatal(err)
    86  	}
    87  
    88  	os.Exit(0)
    89  }