diff --git a/daemon/graphdriver/overlay2/mount.go b/daemon/graphdriver/overlay2/mount.go index eff0f781bf..8d6c99195e 100644 --- a/daemon/graphdriver/overlay2/mount.go +++ b/daemon/graphdriver/overlay2/mount.go @@ -4,94 +4,28 @@ package overlay2 // import "github.com/docker/docker/daemon/graphdriver/overlay2" import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "os" "runtime" - "github.com/docker/docker/pkg/reexec" "golang.org/x/sys/unix" ) -func init() { - reexec.Register("docker-mountfrom", mountFromMain) -} - -func fatal(err error) { - fmt.Fprint(os.Stderr, err) - os.Exit(1) -} - -type mountOptions struct { - Device string - Target string - Type string - Label string - Flag uint32 -} - func mountFrom(dir, device, target, mType string, flags uintptr, label string) error { - options := &mountOptions{ - Device: device, - Target: target, - Type: mType, - Flag: uint32(flags), - Label: label, - } + chErr := make(chan error, 1) - cmd := reexec.Command("docker-mountfrom", dir) - w, err := cmd.StdinPipe() - if err != nil { - return fmt.Errorf("mountfrom error on pipe creation: %v", err) - } + go func() { + runtime.LockOSThread() + // Do not unlock this thread as the thread state cannot be restored + // We do not want go to re-use this thread for anything else. - output := bytes.NewBuffer(nil) - cmd.Stdout = output - cmd.Stderr = output - - // reexec.Command() sets cmd.SysProcAttr.Pdeathsig on Linux, which - // causes the started process to be signaled when the creating OS thread - // dies. Ensure that the reexec is not prematurely signaled. See - // https://go.dev/issue/27505 for more information. - runtime.LockOSThread() - defer runtime.UnlockOSThread() - if err := cmd.Start(); err != nil { - w.Close() - return fmt.Errorf("mountfrom error on re-exec cmd: %v", err) - } - // write the options to the pipe for the untar exec to read - if err := json.NewEncoder(w).Encode(options); err != nil { - w.Close() - return fmt.Errorf("mountfrom json encode to pipe failed: %v", err) - } - w.Close() - - if err := cmd.Wait(); err != nil { - return fmt.Errorf("mountfrom re-exec error: %v: output: %v", err, output) - } - return nil -} - -// mountfromMain is the entry-point for docker-mountfrom on re-exec. -func mountFromMain() { - runtime.LockOSThread() - flag.Parse() - - var options *mountOptions - - if err := json.NewDecoder(os.Stdin).Decode(&options); err != nil { - fatal(err) - } - - if err := os.Chdir(flag.Arg(0)); err != nil { - fatal(err) - } - - if err := unix.Mount(options.Device, options.Target, options.Type, uintptr(options.Flag), options.Label); err != nil { - fatal(err) - } - - os.Exit(0) + if err := unix.Unshare(unix.CLONE_FS); err != nil { + chErr <- err + return + } + if err := unix.Chdir(dir); err != nil { + chErr <- err + return + } + chErr <- unix.Mount(device, target, mType, flags, label) + }() + return <-chErr }