chiark / gitweb /
bus: add .busname unit type to implement kdbus-style bus activation
[elogind.git] / src / core / service.c
index d9e525e48545c4a7b35f6a15cc65d10e194b5c1b..530a305b4bd00dbc6efd5b7a60683c45b30c442d 100644 (file)
@@ -304,7 +304,8 @@ static void service_done(Unit *u) {
         s->status_text = NULL;
 
         cgroup_context_done(&s->cgroup_context);
-        exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager));
+        exec_context_done(&s->exec_context);
+        s->exec_runtime = exec_runtime_unref(s->exec_runtime);
         exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX);
         s->control_command = NULL;
         s->main_command = NULL;
@@ -346,11 +347,6 @@ static int service_arm_timer(Service *s, usec_t usec) {
 
         assert(s);
 
-        if (usec <= 0) {
-                s->timer_event_source = sd_event_source_unref(s->timer_event_source);
-                return 0;
-        }
-
         if (s->timer_event_source) {
                 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + usec);
                 if (r < 0)
@@ -1597,21 +1593,30 @@ static int service_coldplug(Unit *u) {
                     s->deserialized_state == SERVICE_STOP_SIGKILL ||
                     s->deserialized_state == SERVICE_STOP_POST ||
                     s->deserialized_state == SERVICE_FINAL_SIGTERM ||
-                    s->deserialized_state == SERVICE_FINAL_SIGKILL ||
-                    s->deserialized_state == SERVICE_AUTO_RESTART) {
+                    s->deserialized_state == SERVICE_FINAL_SIGKILL) {
+
+                        usec_t k;
 
-                        if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_start_usec > 0) {
+                        k = s->deserialized_state == SERVICE_START_PRE || s->deserialized_state == SERVICE_START ||
+                                s->deserialized_state == SERVICE_START_POST || s->deserialized_state == SERVICE_RELOAD ?
+                                s->timeout_start_usec : s->timeout_stop_usec;
 
-                                r = service_arm_timer(s,
-                                                      s->deserialized_state == SERVICE_AUTO_RESTART ? s->restart_usec :
-                                                      s->deserialized_state == SERVICE_START_PRE || s->deserialized_state == SERVICE_START ||
-                                                      s->deserialized_state == SERVICE_START_POST || s->deserialized_state == SERVICE_RELOAD ? s->timeout_start_usec :
-                                                      s->timeout_stop_usec);
+                        /* For the start/stop timeouts 0 means off */
+                        if (k > 0) {
+                                r = service_arm_timer(s, k);
                                 if (r < 0)
                                         return r;
                         }
                 }
 
+                if (s->deserialized_state == SERVICE_AUTO_RESTART) {
+
+                        /* The restart timeouts 0 means immediately */
+                        r = service_arm_timer(s, s->restart_usec);
+                        if (r < 0)
+                                return r;
+                }
+
                 if ((s->deserialized_state == SERVICE_START &&
                      (s->type == SERVICE_FORKING ||
                       s->type == SERVICE_DBUS ||
@@ -1651,6 +1656,7 @@ static int service_coldplug(Unit *u) {
 
                 service_set_state(s, s->deserialized_state);
         }
+
         return 0;
 }
 
@@ -1746,6 +1752,10 @@ static int service_spawn(
 
         unit_realize_cgroup(UNIT(s));
 
+        r = unit_setup_exec_runtime(UNIT(s));
+        if (r < 0)
+                goto fail;
+
         if (pass_fds ||
             s->exec_context.std_input == EXEC_INPUT_SOCKET ||
             s->exec_context.std_output == EXEC_OUTPUT_SOCKET ||
@@ -1763,9 +1773,12 @@ static int service_spawn(
                 }
         }
 
-        r = service_arm_timer(s, timeout ? s->timeout_start_usec : 0);
-        if (r < 0)
-                goto fail;
+        if (timeout && s->timeout_start_usec > 0) {
+                r = service_arm_timer(s, s->timeout_start_usec);
+                if (r < 0)
+                        goto fail;
+        } else
+                s->timer_event_source = sd_event_source_unref(s->timer_event_source);
 
         r = unit_full_printf_strv(UNIT(s), c->argv, &argv);
         if (r < 0)
@@ -1826,6 +1839,7 @@ static int service_spawn(
                        path,
                        UNIT(s)->id,
                        s->type == SERVICE_IDLE ? UNIT(s)->manager->idle_pipe : NULL,
+                       s->exec_runtime,
                        &pid);
         if (r < 0)
                 goto fail;
@@ -1924,7 +1938,8 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
         s->forbid_restart = false;
 
         /* we want fresh tmpdirs in case service is started again immediately */
-        exec_context_tmp_dirs_done(&s->exec_context);
+        exec_runtime_destroy(s->exec_runtime);
+        s->exec_runtime = exec_runtime_unref(s->exec_runtime);
 
         /* Try to delete the pid file. At this point it will be
          * out-of-date, and some software might be confused by it, so
@@ -2634,12 +2649,6 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
                 dual_timestamp_serialize(f, "watchdog-timestamp",
                                          &s->watchdog_timestamp);
 
-        if (s->exec_context.tmp_dir)
-                unit_serialize_item(u, f, "tmp-dir", s->exec_context.tmp_dir);
-
-        if (s->exec_context.var_tmp_dir)
-                unit_serialize_item(u, f, "var-tmp-dir", s->exec_context.var_tmp_dir);
-
         if (s->forbid_restart)
                 unit_serialize_item(u, f, "forbid-restart", yes_no(s->forbid_restart));
 
@@ -2763,23 +2772,7 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
                 dual_timestamp_deserialize(value, &s->main_exec_status.exit_timestamp);
         else if (streq(key, "watchdog-timestamp"))
                 dual_timestamp_deserialize(value, &s->watchdog_timestamp);
-        else if (streq(key, "tmp-dir")) {
-                char *t;
-
-                t = strdup(value);
-                if (!t)
-                        return log_oom();
-
-                s->exec_context.tmp_dir = t;
-        } else if (streq(key, "var-tmp-dir")) {
-                char *t;
-
-                t = strdup(value);
-                if (!t)
-                        return log_oom();
-
-                s->exec_context.var_tmp_dir = t;
-        } else if (streq(key, "forbid-restart")) {
+        else if (streq(key, "forbid-restart")) {
                 int b;
 
                 b = parse_boolean(value);
@@ -2834,7 +2827,7 @@ _pure_ static bool service_check_snapshot(Unit *u) {
 
         assert(s);
 
-        return !s->got_socket_fd;
+        return (s->socket_fd < 0);
 }
 
 static int service_retry_pid_file(Service *s) {
@@ -2908,7 +2901,12 @@ static int service_demand_pid_file(Service *s) {
 }
 
 static int service_dispatch_io(sd_event_source *source, int fd, uint32_t events, void *userdata) {
-        Service *s = SERVICE(userdata);
+        PathSpec *p = userdata;
+        Service *s;
+
+        assert(p);
+
+        s = SERVICE(p->unit);
 
         assert(s);
         assert(fd >= 0);
@@ -2918,7 +2916,7 @@ static int service_dispatch_io(sd_event_source *source, int fd, uint32_t events,
 
         log_debug_unit(UNIT(s)->id, "inotify event for %s", UNIT(s)->id);
 
-        if (path_spec_fd_event(s->pid_file_pathspec, events) < 0)
+        if (path_spec_fd_event(p, events) < 0)
                 goto fail;
 
         if (service_retry_pid_file(s) == 0)
@@ -3494,7 +3492,7 @@ static int service_enumerate(Manager *m) {
                         d = opendir(path);
                         if (!d) {
                                 if (errno != ENOENT)
-                                        log_warning("opendir(%s) failed: %s", path, strerror(errno));
+                                        log_warning("opendir(%s) failed: %m", path);
 
                                 continue;
                         }
@@ -3527,7 +3525,7 @@ static int service_enumerate(Manager *m) {
                                 if (access(fpath, X_OK) < 0) {
 
                                         if (errno != ENOENT)
-                                                log_warning("access() failed on %s: %s", fpath, strerror(errno));
+                                                log_warning("access() failed on %s: %m", fpath);
 
                                         continue;
                                 }
@@ -3675,11 +3673,14 @@ static void service_bus_name_owner_change(
                     s->state == SERVICE_RUNNING ||
                     s->state == SERVICE_RELOAD)) {
 
+                _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
                 pid_t pid;
 
                 /* Try to acquire PID from bus service */
 
-                r = sd_bus_get_owner_pid(u->manager->api_bus, name, &pid);
+                r = sd_bus_get_owner(u->manager->api_bus, name, SD_BUS_CREDS_PID, &creds);
+                if (r >= 0)
+                        r = sd_bus_creds_get_pid(creds, &pid);
                 if (r >= 0) {
                         log_debug_unit(u->id, "%s's D-Bus name %s is now owned by process %u", u->id, name, (unsigned) pid);
 
@@ -3708,7 +3709,6 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock) {
                 return -EAGAIN;
 
         s->socket_fd = fd;
-        s->got_socket_fd = true;
 
         unit_ref_set(&s->accept_socket, UNIT(sock));
 
@@ -3822,6 +3822,7 @@ const UnitVTable service_vtable = {
         .exec_context_offset = offsetof(Service, exec_context),
         .cgroup_context_offset = offsetof(Service, cgroup_context),
         .kill_context_offset = offsetof(Service, kill_context),
+        .exec_runtime_offset = offsetof(Service, exec_runtime),
 
         .sections =
                 "Unit\0"