]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/service.c
core: unified cgroup hierarchy support
[thirdparty/systemd.git] / src / core / service.c
index 71252e29e2e59c163b2733dcc288204f7d1fb945..292fe50de81e8bbe610d4ebb07a5bcbca05a867f 100644 (file)
@@ -401,7 +401,6 @@ static int service_add_fd_store_set(Service *s, FDSet *fds) {
                 r = service_add_fd_store(s, fd);
                 if (r < 0)
                         return log_unit_error_errno(UNIT(s), r, "Couldn't add fd to fd store: %m");
-
                 if (r > 0) {
                         log_unit_debug(UNIT(s), "Added fd to fd store.");
                         fd = -1;
@@ -557,7 +556,7 @@ static int service_add_extras(Service *s) {
         if (r < 0)
                 return r;
 
-        r = unit_add_default_slice(UNIT(s), &s->cgroup_context);
+        r = unit_set_default_slice(UNIT(s));
         if (r < 0)
                 return r;
 
@@ -568,18 +567,18 @@ static int service_add_extras(Service *s) {
                 s->notify_access = NOTIFY_MAIN;
 
         if (s->bus_name) {
-#ifdef ENABLE_KDBUS
                 const char *n;
 
                 n = strjoina(s->bus_name, ".busname");
                 r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, n, NULL, true);
                 if (r < 0)
                         return r;
-#endif
 
                 r = unit_watch_bus_name(UNIT(s), s->bus_name);
+                if (r == -EEXIST)
+                        return log_unit_error_errno(UNIT(s), r, "Two services allocated for the same bus name %s, refusing operation.", s->bus_name);
                 if (r < 0)
-                        return r;
+                        return log_unit_error_errno(UNIT(s), r, "Cannot watch bus name %s: %m", s->bus_name);
         }
 
         if (UNIT(s)->default_dependencies) {
@@ -768,7 +767,7 @@ static int service_load_pid_file(Service *s, bool may_warn) {
 }
 
 static int service_search_main_pid(Service *s) {
-        pid_t pid;
+        pid_t pid = 0;
         int r;
 
         assert(s);
@@ -783,9 +782,9 @@ static int service_search_main_pid(Service *s) {
 
         assert(s->main_pid <= 0);
 
-        pid = unit_search_main_pid(UNIT(s));
-        if (pid <= 0)
-                return -ENOENT;
+        r = unit_search_main_pid(UNIT(s), &pid);
+        if (r < 0)
+                return r;
 
         log_unit_debug(UNIT(s), "Main PID guessed: "PID_FMT, pid);
         r = service_set_main_pid(s, pid);
@@ -861,7 +860,7 @@ static void service_set_state(Service *s, ServiceState state) {
         /* For the inactive states unit_notify() will trim the cgroup,
          * but for exit we have to do that ourselves... */
         if (state == SERVICE_EXITED && UNIT(s)->manager->n_reloading <= 0)
-                unit_destroy_cgroup_if_empty(UNIT(s));
+                unit_prune_cgroup(UNIT(s));
 
         /* For remain_after_exit services, let's see if we can "release" the
          * hold on the console, since unit_notify() only does that in case of
@@ -1180,7 +1179,6 @@ static int service_spawn(
         } else
                 path = UNIT(s)->cgroup_path;
 
-#ifdef ENABLE_KDBUS
         if (s->exec_context.bus_endpoint) {
                 r = bus_kernel_create_endpoint(UNIT(s)->manager->running_as == MANAGER_SYSTEM ? "system" : "user",
                                                UNIT(s)->id, &bus_endpoint_path);
@@ -1192,7 +1190,6 @@ static int service_spawn(
                  * as the service is running. */
                 exec_params.bus_endpoint_fd = s->bus_endpoint_fd = r;
         }
-#endif
 
         exec_params.argv = argv;
         exec_params.fds = fds;
@@ -1239,7 +1236,7 @@ static int main_pid_good(Service *s) {
         /* Returns 0 if the pid is dead, 1 if it is good, -1 if we
          * don't know */
 
-        /* If we know the pid file, then lets just check if it is
+        /* If we know the pid file, then let's just check if it is
          * still valid */
         if (s->main_pid_known) {
 
@@ -1272,7 +1269,7 @@ static int cgroup_good(Service *s) {
         if (!UNIT(s)->cgroup_path)
                 return 0;
 
-        r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, UNIT(s)->cgroup_path, true);
+        r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, UNIT(s)->cgroup_path);
         if (r < 0)
                 return r;
 
@@ -1523,18 +1520,33 @@ fail:
         service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
 }
 
+static bool service_good(Service *s) {
+        int main_pid_ok;
+        assert(s);
+
+        if (s->type == SERVICE_DBUS && !s->bus_name_good)
+                return false;
+
+        main_pid_ok = main_pid_good(s);
+        if (main_pid_ok > 0) /* It's alive */
+                return true;
+        if (main_pid_ok == 0) /* It's dead */
+                return false;
+
+        /* OK, we don't know anything about the main PID, maybe
+         * because there is none. Let's check the control group
+         * instead. */
+
+        return cgroup_good(s) != 0;
+}
+
 static void service_enter_running(Service *s, ServiceResult f) {
-        int main_pid_ok, cgroup_ok;
         assert(s);
 
         if (f != SERVICE_SUCCESS)
                 s->result = f;
 
-        main_pid_ok = main_pid_good(s);
-        cgroup_ok = cgroup_good(s);
-
-        if ((main_pid_ok > 0 || (main_pid_ok < 0 && cgroup_ok != 0)) &&
-            (s->bus_name_good || s->type != SERVICE_DBUS)) {
+        if (service_good(s)) {
 
                 /* If there are any queued up sd_notify()
                  * notifications, process them now */
@@ -1978,7 +1990,7 @@ static int service_reload(Unit *u) {
         assert(s->state == SERVICE_RUNNING || s->state == SERVICE_EXITED);
 
         service_enter_reload(s);
-        return 0;
+        return 1;
 }
 
 _pure_ static bool service_can_reload(Unit *u) {
@@ -2632,7 +2644,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                                 break;
                                         }
                                 } else
-                                        service_search_main_pid(s);
+                                        (void) service_search_main_pid(s);
 
                                 service_enter_start_post(s);
                                 break;
@@ -2654,7 +2666,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                                 break;
                                         }
                                 } else
-                                        service_search_main_pid(s);
+                                        (void) service_search_main_pid(s);
 
                                 service_enter_running(s, SERVICE_SUCCESS);
                                 break;
@@ -2662,7 +2674,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                         case SERVICE_RELOAD:
                                 if (f == SERVICE_SUCCESS) {
                                         service_load_pid_file(s, true);
-                                        service_search_main_pid(s);
+                                        (void) service_search_main_pid(s);
                                 }
 
                                 s->reload_result = f;
@@ -3217,7 +3229,6 @@ const UnitVTable service_vtable = {
 
         .bus_name_owner_change = service_bus_name_owner_change,
 
-        .bus_interface = "org.freedesktop.systemd1.Service",
         .bus_vtable = bus_service_vtable,
         .bus_set_property = bus_service_set_property,
         .bus_commit_properties = bus_service_commit_properties,
@@ -3233,13 +3244,10 @@ const UnitVTable service_vtable = {
                 .finished_start_job = {
                         [JOB_DONE]       = "Started %s.",
                         [JOB_FAILED]     = "Failed to start %s.",
-                        [JOB_DEPENDENCY] = "Dependency failed for %s.",
-                        [JOB_TIMEOUT]    = "Timed out starting %s.",
                 },
                 .finished_stop_job = {
                         [JOB_DONE]       = "Stopped %s.",
                         [JOB_FAILED]     = "Stopped (with error) %s.",
-                        [JOB_TIMEOUT]    = "Timed out stopping %s.",
                 },
         },
 };