}
static void service_set_state(Service *s, ServiceState state) {
+ Unit *u = UNIT(ASSERT_PTR(s));
ServiceState old_state;
const UnitActiveState *table;
- assert(s);
-
if (s->state != state)
- bus_unit_send_pending_change_signal(UNIT(s), false);
+ bus_unit_send_pending_change_signal(u, false);
table = s->type == SERVICE_IDLE ? state_translation_table_idle : state_translation_table;
SERVICE_DEAD, SERVICE_FAILED,
SERVICE_DEAD_BEFORE_AUTO_RESTART, SERVICE_FAILED_BEFORE_AUTO_RESTART, SERVICE_AUTO_RESTART, SERVICE_AUTO_RESTART_QUEUED,
SERVICE_DEAD_RESOURCES_PINNED)) {
- unit_unwatch_all_pids(UNIT(s));
- unit_dequeue_rewatch_pids(UNIT(s));
+ unit_unwatch_all_pids(u);
+ unit_dequeue_rewatch_pids(u);
}
if (state != SERVICE_START)
if (!IN_SET(state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD, SERVICE_RELOAD_SIGNAL, SERVICE_RELOAD_NOTIFY))
service_stop_watchdog(s);
- /* For the inactive states unit_notify() will trim the cgroup,
- * but for exit we have to do that ourselves... */
- if (state == SERVICE_EXITED && !MANAGER_IS_RELOADING(UNIT(s)->manager))
- unit_prune_cgroup(UNIT(s));
+ if (state == SERVICE_EXITED && !MANAGER_IS_RELOADING(u->manager)) {
+ /* For the inactive states unit_notify() will trim the cgroup. But for exit we have to
+ * do that ourselves... */
+ unit_prune_cgroup(u);
+
+ /* If none of ExecReload= and ExecStop*= is used, we can safely destroy runtime data
+ * as soon as the service enters SERVICE_EXITED. This saves us from keeping the credential mount
+ * for the whole duration of the oneshot service while no processes are actually running,
+ * among other things. */
+
+ bool start_only = true;
+ for (ServiceExecCommand c = SERVICE_EXEC_RELOAD; c < _SERVICE_EXEC_COMMAND_MAX; c++)
+ if (s->exec_command[c]) {
+ start_only = false;
+ break;
+ }
+
+ if (start_only)
+ unit_destroy_runtime_data(u, &s->exec_context);
+ }
if (old_state != state)
- log_unit_debug(UNIT(s), "Changed %s -> %s", service_state_to_string(old_state), service_state_to_string(state));
+ log_unit_debug(u, "Changed %s -> %s", service_state_to_string(old_state), service_state_to_string(state));
- unit_notify(UNIT(s), table[old_state], table[state], s->reload_result == SERVICE_SUCCESS);
+ unit_notify(u, table[old_state], table[state], s->reload_result == SERVICE_SUCCESS);
}
static usec_t service_coldplug_timeout(Service *s) {