diff --git a/notify_socket.go b/notify_socket.go index 9e30e4780..2bd678893 100644 --- a/notify_socket.go +++ b/notify_socket.go @@ -63,7 +63,9 @@ func (s *notifySocket) setupSocket() error { return nil } -func (notifySocket *notifySocket) run() { +// pid1 must be set only with -d, as it is used to set the new process as the main process +// for the service in systemd +func (notifySocket *notifySocket) run(pid1 int) { buf := make([]byte, 512) notifySocketHostAddr := net.UnixAddr{Name: notifySocket.host, Net: "unixgram"} client, err := net.DialUnix("unixgram", nil, ¬ifySocketHostAddr) @@ -93,6 +95,12 @@ func (notifySocket *notifySocket) run() { if err != nil { return } + + // now we can inform systemd to use pid1 as the pid to monitor + if pid1 > 0 { + newPid := fmt.Sprintf("MAINPID=%d\n", pid1) + client.Write([]byte(newPid)) + } return } } diff --git a/restore.go b/restore.go index a238205a0..4dbdf304d 100644 --- a/restore.go +++ b/restore.go @@ -188,10 +188,7 @@ func restoreContainer(context *cli.Context, spec *specs.Spec, config *configs.Co return -1, err } } - if detach { - return 0, nil - } - return handler.forward(process, tty) + return handler.forward(process, tty, detach) } func criuOptions(context *cli.Context) *libcontainer.CriuOpts { diff --git a/signals.go b/signals.go index 0171da375..d787c940b 100644 --- a/signals.go +++ b/signals.go @@ -51,16 +51,25 @@ type signalHandler struct { // forward handles the main signal event loop forwarding, resizing, or reaping depending // on the signal received. -func (h *signalHandler) forward(process *libcontainer.Process, tty *tty) (int, error) { +func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach bool) (int, error) { // make sure we know the pid of our main process so that we can return // after it dies. + if detach && h.notifySocket == nil { + return 0, nil + } + pid1, err := process.Pid() if err != nil { return -1, err } if h.notifySocket != nil { - go h.notifySocket.run() + if detach { + h.notifySocket.run(pid1) + return 0, nil + } else { + go h.notifySocket.run(0) + } } // perform the initial tty resize. diff --git a/utils_linux.go b/utils_linux.go index b8c105a9e..a9cb33950 100644 --- a/utils_linux.go +++ b/utils_linux.go @@ -219,10 +219,6 @@ func (r *runner) run(config *specs.Process) (int, error) { r.destroy() return -1, fmt.Errorf("cannot use console socket if runc will not detach or allocate tty") } - if detach && r.notifySocket != nil { - r.destroy() - return -1, fmt.Errorf("cannot detach when using NOTIFY_SOCKET") - } startFn := r.container.Start if !r.create { @@ -294,13 +290,13 @@ func (r *runner) run(config *specs.Process) (int, error) { return -1, err } } - if detach { - return 0, nil - } - status, err := handler.forward(process, tty) + status, err := handler.forward(process, tty, detach) if err != nil { r.terminate(process) } + if detach { + return 0, nil + } r.destroy() return status, err }