-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Properly handle operation as init process
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
- Loading branch information
Showing
4 changed files
with
107 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// +build !linux !cgo | ||
|
||
package cmds | ||
|
||
func HandleInit() error { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// +build linux,cgo | ||
|
||
package cmds | ||
|
||
import ( | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
|
||
"github.com/erikdubbelboer/gspt" | ||
"github.com/pkg/errors" | ||
"github.com/rancher/k3s/pkg/version" | ||
"github.com/rootless-containers/rootlesskit/pkg/parent/cgrouputil" | ||
) | ||
|
||
// HandleInit takes care of things that need to be done when running as process 1, usually in a | ||
// Docker container. This includes evacuating the root cgroup and reaping child pids. | ||
func HandleInit() error { | ||
if os.Getpid() != 1 { | ||
return nil | ||
} | ||
|
||
// The root cgroup has to be empty to enable subtree_control, so evacuate it by placing | ||
// ourselves in the init cgroup. | ||
if err := cgrouputil.EvacuateCgroup2("init"); err != nil { | ||
return errors.Wrap(err, "failed to evacuate root cgroup") | ||
} | ||
|
||
pwd, err := os.Getwd() | ||
if err != nil { | ||
return errors.Wrap(err, "failed to get working directory for init process") | ||
} | ||
|
||
go reapChildren() | ||
|
||
// fork the main process to do work so that this init process can handle reaping pids | ||
// without interfering with any other exec's that the rest of the codebase may do. | ||
var wstatus syscall.WaitStatus | ||
pattrs := &syscall.ProcAttr{ | ||
Dir: pwd, | ||
Env: os.Environ(), | ||
Sys: &syscall.SysProcAttr{Setsid: true}, | ||
Files: []uintptr{ | ||
uintptr(syscall.Stdin), | ||
uintptr(syscall.Stdout), | ||
uintptr(syscall.Stderr), | ||
}, | ||
} | ||
pid, err := syscall.ForkExec(os.Args[0], os.Args, pattrs) | ||
if err != nil { | ||
return errors.Wrap(err, "failed to fork/exec "+version.Program) | ||
} | ||
|
||
gspt.SetProcTitle(os.Args[0] + " init") | ||
// wait for main process to exit, and return its status when it does | ||
_, err = syscall.Wait4(pid, &wstatus, 0, nil) | ||
for err == syscall.EINTR { | ||
_, err = syscall.Wait4(pid, &wstatus, 0, nil) | ||
} | ||
os.Exit(wstatus.ExitStatus()) | ||
return nil | ||
} | ||
|
||
//reapChildren calls Wait4 whenever SIGCHLD is received | ||
func reapChildren() { | ||
sigs := make(chan os.Signal, 1) | ||
signal.Notify(sigs, syscall.SIGCHLD) | ||
for { | ||
select { | ||
case <-sigs: | ||
} | ||
for { | ||
var wstatus syscall.WaitStatus | ||
_, err := syscall.Wait4(-1, &wstatus, 0, nil) | ||
for err == syscall.EINTR { | ||
_, err = syscall.Wait4(-1, &wstatus, 0, nil) | ||
} | ||
if err == nil || err == syscall.ECHILD { | ||
break | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters