From 0f4e2be0733ac9806b281627b6c8466e61611435 Mon Sep 17 00:00:00 2001
From: Valentin Rothberg <rothberg@redhat.com>
Date: Thu, 13 Aug 2020 12:53:28 +0200
Subject: podman.service: use sdnotiy

Commit 2b6dd3fb4384 set the killmode of the podman.service to the
systemd default which ultimately lead to the problem that systemd
will kill *all* processes inside the unit's cgroup and hence kill
all containers whenever the service is stopped.

Fix it by setting the type to sdnotify and the killmode to process.
`podman system service` will send the necessary notify messages
when the NOTIFY_SOCKET is set and unset it right after to prevent
the backend and container runtimes from jumping in between and send
messages as well.

Fixes: #7294
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
---
 contrib/systemd/system/podman.service |  3 ++-
 pkg/api/server/server.go              | 27 ++++++++++++++++++++++++++-
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/contrib/systemd/system/podman.service b/contrib/systemd/system/podman.service
index c8751168d..e14bbe078 100644
--- a/contrib/systemd/system/podman.service
+++ b/contrib/systemd/system/podman.service
@@ -6,5 +6,6 @@ Documentation=man:podman-system-service(1)
 StartLimitIntervalSec=0
 
 [Service]
-Type=simple
+Type=notify
+KillMode=process
 ExecStart=/usr/bin/podman system service
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index 18b48a3f6..e7c031234 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -2,6 +2,7 @@ package server
 
 import (
 	"context"
+	"fmt"
 	"log"
 	"net"
 	"net/http"
@@ -17,6 +18,7 @@ import (
 	"github.com/containers/podman/v2/pkg/api/handlers"
 	"github.com/containers/podman/v2/pkg/api/server/idletracker"
 	"github.com/coreos/go-systemd/v22/activation"
+	"github.com/coreos/go-systemd/v22/daemon"
 	"github.com/gorilla/mux"
 	"github.com/gorilla/schema"
 	"github.com/pkg/errors"
@@ -147,8 +149,31 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
 	return &server, nil
 }
 
-// Serve starts responding to HTTP requests
+// If the NOTIFY_SOCKET is set, communicate the PID and readiness, and
+// further unset NOTIFY_SOCKET to prevent containers from sending
+// messages and unset INVOCATION_ID so conmon and containers are in
+// the correct cgroup.
+func setupSystemd() {
+	if len(os.Getenv("NOTIFY_SOCKET")) == 0 {
+		return
+	}
+	payload := fmt.Sprintf("MAINPID=%d", os.Getpid())
+	payload += "\n"
+	payload += daemon.SdNotifyReady
+	if sent, err := daemon.SdNotify(true, payload); err != nil {
+		logrus.Errorf("Error notifying systemd of Conmon PID: %s", err.Error())
+	} else if sent {
+		logrus.Debugf("Notify sent successfully")
+	}
+
+	if err := os.Unsetenv("INVOCATION_ID"); err != nil {
+		logrus.Errorf("Error unsetting INVOCATION_ID: %s", err.Error())
+	}
+}
+
+// Serve starts responding to HTTP requests.
 func (s *APIServer) Serve() error {
+	setupSystemd()
 	sigChan := make(chan os.Signal, 1)
 	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
 	errChan := make(chan error, 1)
-- 
cgit v1.2.3-54-g00ecf