2f7d91
From 017d1bc2a34946336dbafcc1c9c390ea45a2a3bd Mon Sep 17 00:00:00 2001
2f7d91
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
2f7d91
Date: Sat, 22 Oct 2016 22:16:02 -0400
2f7d91
Subject: [PATCH] core: when restarting services, don't close fds
2f7d91
2f7d91
We would close all the stored fds in service_release_resources(), which of
2f7d91
course broke the whole concept of storing fds over service restart.
2f7d91
2f7d91
Fixes #4408.
2f7d91
2f7d91
(cherry picked from commit f0bfbfac43b7faa68ef1bb2ad659c191b9ec85d2)
2f7d91
(cherry picked from commit 4c271437cd695c31e76adb191013009689a7797c)
2f7d91
Resolves: #1803802
2f7d91
---
2f7d91
 src/core/service.c | 22 +++++++++++++++-------
2f7d91
 src/core/unit.c    |  6 ++++--
2f7d91
 src/core/unit.h    |  2 +-
2f7d91
 3 files changed, 20 insertions(+), 10 deletions(-)
2f7d91
2f7d91
diff --git a/src/core/service.c b/src/core/service.c
2f7d91
index e538280bad..3c2f69a003 100644
2f7d91
--- a/src/core/service.c
2f7d91
+++ b/src/core/service.c
2f7d91
@@ -258,7 +258,17 @@ static void service_fd_store_unlink(ServiceFDStore *fs) {
2f7d91
         free(fs);
2f7d91
 }
2f7d91
 
2f7d91
-static void service_release_resources(Unit *u) {
2f7d91
+static void service_release_fd_store(Service *s) {
2f7d91
+        assert(s);
2f7d91
+
2f7d91
+        log_unit_debug(UNIT(s)->id, "Releasing all stored fds");
2f7d91
+        while (s->fd_store)
2f7d91
+                service_fd_store_unlink(s->fd_store);
2f7d91
+
2f7d91
+        assert(s->n_fd_store == 0);
2f7d91
+}
2f7d91
+
2f7d91
+static void service_release_resources(Unit *u, bool inactive) {
2f7d91
         Service *s = SERVICE(u);
2f7d91
 
2f7d91
         assert(s);
2f7d91
@@ -266,12 +276,10 @@ static void service_release_resources(Unit *u) {
2f7d91
         if (!s->fd_store)
2f7d91
                 return;
2f7d91
 
2f7d91
-        log_debug("Releasing all resources for %s", u->id);
2f7d91
-
2f7d91
-        while (s->fd_store)
2f7d91
-                service_fd_store_unlink(s->fd_store);
2f7d91
+        log_unit_debug(u->id, "Releasing resources.");
2f7d91
 
2f7d91
-        assert(s->n_fd_store == 0);
2f7d91
+        if (inactive)
2f7d91
+                service_release_fd_store(s);
2f7d91
 }
2f7d91
 
2f7d91
 static void service_done(Unit *u) {
2f7d91
@@ -319,7 +327,7 @@ static void service_done(Unit *u) {
2f7d91
 
2f7d91
         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
2f7d91
 
2f7d91
-        service_release_resources(u);
2f7d91
+        service_release_resources(u, true);
2f7d91
 }
2f7d91
 
2f7d91
 static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *userdata) {
2f7d91
diff --git a/src/core/unit.c b/src/core/unit.c
2f7d91
index 0dc66203a4..22e31a76b3 100644
2f7d91
--- a/src/core/unit.c
2f7d91
+++ b/src/core/unit.c
2f7d91
@@ -285,6 +285,7 @@ int unit_set_description(Unit *u, const char *description) {
2f7d91
 
2f7d91
 bool unit_may_gc(Unit *u) {
2f7d91
         UnitActiveState state;
2f7d91
+        bool inactive;
2f7d91
         assert(u);
2f7d91
 
2f7d91
         /* Checks whether the unit is ready to be unloaded for garbage collection.
2f7d91
@@ -302,16 +303,17 @@ bool unit_may_gc(Unit *u) {
2f7d91
                 return false;
2f7d91
 
2f7d91
         state = unit_active_state(u);
2f7d91
+        inactive = state == UNIT_INACTIVE;
2f7d91
 
2f7d91
         /* If the unit is inactive and failed and no job is queued for
2f7d91
          * it, then release its runtime resources */
2f7d91
         if (UNIT_IS_INACTIVE_OR_FAILED(state) &&
2f7d91
             UNIT_VTABLE(u)->release_resources)
2f7d91
-                UNIT_VTABLE(u)->release_resources(u);
2f7d91
+                UNIT_VTABLE(u)->release_resources(u, inactive);
2f7d91
 
2f7d91
         /* But we keep the unit object around for longer when it is
2f7d91
          * referenced or configured to not be gc'ed */
2f7d91
-        if (state != UNIT_INACTIVE)
2f7d91
+        if (!inactive)
2f7d91
                 return false;
2f7d91
 
2f7d91
         if (UNIT_VTABLE(u)->no_gc)
2f7d91
diff --git a/src/core/unit.h b/src/core/unit.h
2f7d91
index 719fc95260..232be8164f 100644
2f7d91
--- a/src/core/unit.h
2f7d91
+++ b/src/core/unit.h
2f7d91
@@ -360,7 +360,7 @@ struct UnitVTable {
2f7d91
 
2f7d91
         /* When the unit is not running and no job for it queued we
2f7d91
          * shall release its runtime resources */
2f7d91
-        void (*release_resources)(Unit *u);
2f7d91
+        void (*release_resources)(Unit *u, bool inactive);
2f7d91
 
2f7d91
         /* Return true when this unit is suitable for snapshotting */
2f7d91
         bool (*check_snapshot)(Unit *u);