Skip to content

Commit f071a65

Browse files
committed
Imported fix for orphan (dead) processed from ctrox#85.
1 parent a00a7b8 commit f071a65

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

cmd/s3driver/main.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ import (
2121
"fmt"
2222
"log"
2323
"os"
24+
"os/signal"
2425
"strings"
26+
"syscall"
2527

2628
"github.com/ctrox/csi-s3/pkg/driver"
2729
)
@@ -50,6 +52,38 @@ var (
5052
func main() {
5153
flag.Parse()
5254

55+
// We're running in the container as PID-1 which gets some special
56+
// treatment by the kernel. In particular, if a process in the container
57+
// terminates and there are still active child processes, the kernel will move
58+
// those orphaned processes to be child processes of PID-1 and signal it
59+
// by sending a SIGCHLD. Init-systems are expected to handle this case by
60+
// reaping those "orphan" processes once they exit.
61+
//
62+
// Since all available mounters are instructed to daemonize, we need to reap
63+
// the daemonized processes since their parent (the mounter) exists once the daemon
64+
// is running.
65+
go func() {
66+
ch := make(chan os.Signal, 1)
67+
68+
signal.Notify(ch, syscall.SIGCHLD)
69+
70+
for range ch {
71+
var status syscall.WaitStatus
72+
pid, err := syscall.Wait4(-1, &status, 0, nil)
73+
if err != nil {
74+
// we might receive ECHILD when the mounter exits after daemonizing.
75+
// We'll be late calling Wait4 here as that process is already reaped
76+
// since we're using exec.Command().Run() which already calls Waitpid
77+
if val, ok := err.(syscall.Errno); !ok || val != syscall.ECHILD {
78+
log.Printf("failed to call wait4: %s\n", err)
79+
}
80+
81+
} else {
82+
log.Printf("repeated child %d: status=%d\n", pid, status.ExitStatus())
83+
}
84+
}
85+
}()
86+
5387
driver, err := driver.New(*nodeID, *endpoint, segments)
5488
if err != nil {
5589
log.Fatal(err)

0 commit comments

Comments
 (0)