8000 Merge pull request #47932 from thaJeztah/reexec_clean · moby/moby@6e514e8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6e514e8

Browse files
authored
Merge pull request #47932 from thaJeztah/reexec_clean
pkg/reexec: cleanup and remove some dependencies
2 parents aa22d13 + cf796aa commit 6e514e8

File tree

7 files changed

+78
-86
lines changed

7 files changed

+78
-86
lines changed

pkg/reexec/command_linux.go

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,26 @@
1-
package reexec // import "github.com/docker/docker/pkg/reexec"
1+
package reexec
22

33
import (
44
"os/exec"
55
"syscall"
6-
7-
"golang.org/x/sys/unix"
86
)
97

10-
// Self returns the path to the current process's binary.
11-
// Returns "/proc/self/exe".
12-
func Self() string {
13-
return "/proc/self/exe"
14-
}
15-
16-
// Command returns *exec.Cmd which has Path as current binary. Also it setting
17-
// SysProcAttr.Pdeathsig to SIGTERM.
18-
// This will use the in-memory version (/proc/self/exe) of the current binary,
19-
// it is thus safe to delete or replace the on-disk binary (os.Args[0]).
8+
// Command returns an [*exec.Cmd] which has Path as current binary which,
9+
// on Linux, is set to the in-memory version (/proc/self/exe) of the current
10+
// binary, it is thus safe to delete or replace the on-disk binary (os.Args[0]).
11+
//
12+
// On Linux, the Pdeathsig of [*exec.Cmd.SysProcAttr] is set to SIGTERM.
13+
// This signal will be sent to the process when the OS thread which created
14+
// the process dies.
2015
//
21-
// As SysProcAttr.Pdeathsig is set, the signal will be sent to the process when
22-
// the OS thread which created the process dies. It is the caller's
23-
// responsibility to ensure that the creating thread is not terminated
24-
// prematurely. See https://go.dev/issue/27505 for more details.
16+
// It is the caller's responsibility to ensure that the creating thread is
17+
// not terminated prematurely. See https://go.dev/issue/27505 for more details.
2518
func Command(args ...string) *exec.Cmd {
2619
return &exec.Cmd{
2720
Path: Self(),
2821
Args: args,
2922
SysProcAttr: &syscall.SysProcAttr{
30-
Pdeathsig: unix.SIGTERM,
23+
Pdeathsig: syscall.SIGTERM,
3124
},
3225
}
3326
}

pkg/reexec/command_other.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//go:build freebsd || darwin || windows
2+
3+
package reexec
4+
5+
import (
6+
"os/exec"
7+
)
8+
9+
// Command returns *exec.Cmd with its Path set to the path of the current
10+
// binary using the result of [Self]. For example if current binary is
11+
// "my-binary" at "/usr/bin/" (or "my-binary.exe" at "C:\" on Windows),
12+
// then cmd.Path is set to "/usr/bin/my-binary" and "C:\my-binary.exe"
13+
// respectively.
14+
func Command(args ...string) *exec.Cmd {
15+
return &exec.Cmd{
16+
Path: Self(),
17+
Args: args,
18+
}
19+
}

pkg/reexec/command_unix.go

Lines changed: 0 additions & 23 deletions
This file was deleted.

pkg/reexec/command_unsupported.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
//go:build !linux && !windows && !freebsd && !darwin
22

3-
package reexec // import "github.com/docker/docker/pkg/reexec"
3+
package reexec
44

55
import (
66
"os/exec"
77
)
88

9-
func Self() string {
10-
return ""
11-
}
12-
139
// Command is unsupported on operating systems apart from Linux, Windows, and Darwin.
1410
func Command(args ...string) *exec.Cmd {
1511
return nil

pkg/reexec/command_windows.go

Lines changed: 0 additions & 21 deletions
This file was deleted.

pkg/reexec/reexec.go

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
1-
// Package reexec facilitates the busybox style reexec of the docker binary that
2-
// we require because of the forking limitations of using Go. Handlers can be
3-
// registered with a name and the argv 0 of the exec of the binary will be used
4-
// to find and execute custom init paths.
5-
package reexec // import "github.com/docker/docker/pkg/reexec"
1+
// Package reexec facilitates the busybox style reexec of a binary.
2+
//
3+
// Handlers can be registered with a name and the argv 0 of the exec of
4+
// the binary will be used to find and execute custom init paths.
5+
//
6+
// It is used in dockerd to work around forking limitations when using Go.
7+
package reexec
68

79
import (
810
"fmt"
911
"os"
1012
"os/exec"
1113
"path/filepath"
14+
"runtime"
1215
)
1316

1417
var registeredInitializers = make(map[string]func())
1518

16-
// Register adds an initialization func under the specified name
19+
// Register adds an initialization func under the specified name. It panics
20+
// if the given name is already registered.
1721
func Register(name string, initializer func()) {
1822
if _, exists := registeredInitializers[name]; exists {
1923
panic(fmt.Sprintf("reexec func already registered under name %q", name))
@@ -25,15 +29,24 @@ func Register(name string, initializer func()) {
2529
// Init is called as the first part of the exec process and returns true if an
2630
// initialization function was called.
2731
func Init() bool {
28-
initializer, exists := registeredInitializers[os.Args[0]]
29-
if exists {
32+
if initializer, ok := registeredInitializers[os.Args[0]]; ok {
3033
initializer()
31-
3234
return true
3335
}
3436
return false
3537
}
3638

39+
// Self returns the path to the current process's binary. On Linux, it
40+
// returns "/proc/self/exe", which provides the in-memory version of the
41+
// current binary, whereas on other platforms it attempts to looks up the
42+
// absolute path for os.Args[0], or otherwise returns os.Args[0] as-is.
43+
func Self() string {
44+
if runtime.GOOS == "linux" {
45+
return "/proc/self/exe"
46+
}
47+
return naiveSelf()
48+
}
49+
3750
func naiveSelf() string {
3851
name := os.Args[0]
3952
if filepath.Base(name) == name {

pkg/reexec/reexec_test.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
package reexec // import "github.com/docker/docker/pkg/reexec"
1+
package reexec
22

33
import (
44
"os"
55
"os/exec"
66
"testing"
7-
8-
"gotest.tools/v3/assert"
97
)
108

119
func init() {
@@ -18,7 +16,10 @@ func init() {
1816
func TestRegister(t *testing.T) {
1917
defer func() {
2018
if r := recover(); r != nil {
21-
assert.Equal(t, `reexec func already registered under name "reexec"`, r)
19+
const expected = `reexec func already registered under name "reexec"`
20+
if r != expected {
21+
t.Errorf("got %q, want %q", r, expected)
22+
}
2223
}
2324
}()
2425
Register("reexec", func() {})
@@ -27,13 +28,20 @@ func TestRegister(t *testing.T) {
2728
func TestCommand(t *testing.T) {
2829
cmd := Command("reexec")
2930
w, err := cmd.StdinPipe()
30-
assert.NilError(t, err, "Error on pipe creation: %v", err)
31+
if err != nil {
32+
t.Fatalf("Error on pipe creation: %v", err)
33+
}
3134
defer w.Close()
3235

3336
err = cmd.Start()
34-
assert.NilError(t, err, "Error on re-exec cmd: %v", err)
37+
if err != nil {
38+
t.Fatalf("Error on re-exec cmd: %v", err)
39+
}
3540
err = cmd.Wait()
36-
assert.Error(t, err, "exit status 2")
41+
const expected = "exit status 2"
42+
if err == nil || err.Error() != expected {
43+
t.Fatalf("got %v, want %v", err, expected)
44+
}
3745
}
3846

3947
func TestNaiveSelf(t *testing.T) {
@@ -43,10 +51,17 @@ func TestNaiveSelf(t *testing.T) {
4351
cmd := exec.Command(naiveSelf(), "-test.run=TestNaiveSelf")
4452
cmd.Env = append(os.Environ(), "TEST_CHECK=1")
4553
err := cmd.Start()
46-
assert.NilError(t, err, "Unable to start command")
54+
if err != nil {
55+
t.Fatalf("Unable to start command: %v", err)
56+
}
4757
err = cmd.Wait()
48-
assert.Error(t, err, "exit status 2")
58+
const expected = "exit status 2"
59+
if err == nil || err.Error() != expected {
60+
t.Fatalf("got %v, want %v", err, expected)
61+
}
4962

5063
os.Args[0] = "mkdir"
51-
assert.Check 49FF (t, naiveSelf() != os.Args[0])
64+
if naiveSelf() == os.Args[0] {
65+
t.Fatalf("Expected naiveSelf to resolve the location of mkdir")
66+
}
5267
}

0 commit comments

Comments
 (0)
0