@@ -21,7 +21,9 @@ import (
21
21
"fmt"
22
22
"log"
23
23
"os"
24
+ "os/signal"
24
25
"strings"
26
+ "syscall"
25
27
26
28
"github.com/ctrox/csi-s3/pkg/driver"
27
29
)
50
52
func main () {
51
53
flag .Parse ()
52
54
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
+
53
87
driver , err := driver .New (* nodeID , * endpoint , segments )
54
88
if err != nil {
55
89
log .Fatal (err )
0 commit comments