free(s->status_text);
s->status_text = NULL;
- exec_context_done(&s->exec_context);
+ exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager));
exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX);
s->control_command = NULL;
s->main_command = NULL;
if (endswith(name, ".sh"))
/* Drop .sh suffix */
strcpy(stpcpy(r, name) - 3, ".service");
- if (startswith(name, "rc."))
- /* Drop rc. prefix */
- strcpy(stpcpy(r, name + 3), ".service");
else
/* Normal init script name */
strcpy(stpcpy(r, name), ".service");
continue;
if (unit_name_to_type(m) == UNIT_SERVICE)
- r = unit_add_name(u, m);
+ r = unit_merge_by_name(u, m);
else
/* NB: SysV targets
* which are provided
assert(s);
assert(name);
- /* For SysV services we strip the rc.* and *.sh
- * prefixes/suffixes. */
- if (startswith(name, "rc.") ||
- endswith(name, ".sh.service"))
+ /* For SysV services we strip the *.sh suffixes. */
+ if (endswith(name, ".sh.service"))
return -ENOENT;
STRV_FOREACH(p, UNIT(s)->manager->lookup_paths.sysvinit_path) {
}
free(path);
- if (r >= 0 && UNIT(s)->load_state == UNIT_STUB) {
- /* Try rc.* init scripts */
-
- path = strjoin(*p, "/rc.", name, NULL);
- if (!path)
- return -ENOMEM;
-
- /* Drop .service suffix */
- path[strlen(path)-8] = 0;
- r = service_load_sysv_path(s, path);
- free(path);
- }
-
if (r < 0)
return r;
SPECIAL_SOCKETS_TARGET, NULL, true);
if (r < 0)
return r;
+
+ r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES,
+ SPECIAL_TIMERS_TARGET, NULL, true);
+ if (r < 0)
+ return r;
+
+ r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES,
+ SPECIAL_PATHS_TARGET, NULL, true);
+ if (r < 0)
+ return r;
}
/* Second, activate normal shutdown */
s->forbid_restart = false;
+ /* we want fresh tmpdirs in case service is started again immediately */
+ exec_context_tmp_dirs_done(&s->exec_context);
+
return;
fail:
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);
+
return 0;
}
dual_timestamp_deserialize(value, &s->main_exec_status.exit_timestamp);
else if (streq(key, "watchdog-timestamp"))
dual_timestamp_deserialize(value, &s->watchdog_timestamp);
- else
+ 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
log_debug_unit(u->id, "Unknown serialization key '%s'", key);
return 0;
static int service_kill(Unit *u, KillWho who, int signo, DBusError *error) {
Service *s = SERVICE(u);
- int r = 0;
- Set *pid_set = NULL;
-
- assert(s);
-
- if (s->main_pid <= 0 && who == KILL_MAIN) {
- dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
- return -ESRCH;
- }
-
- if (s->control_pid <= 0 && who == KILL_CONTROL) {
- dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
- return -ESRCH;
- }
-
- if (who == KILL_CONTROL || who == KILL_ALL)
- if (s->control_pid > 0)
- if (kill(s->control_pid, signo) < 0)
- r = -errno;
-
- if (who == KILL_MAIN || who == KILL_ALL)
- if (s->main_pid > 0)
- if (kill(s->main_pid, signo) < 0)
- r = -errno;
-
- if (who == KILL_ALL) {
- int q;
-
- pid_set = set_new(trivial_hash_func, trivial_compare_func);
- if (!pid_set)
- return -ENOMEM;
-
- /* Exclude the control/main pid from being killed via the cgroup */
- if (s->control_pid > 0) {
- q = set_put(pid_set, LONG_TO_PTR(s->control_pid));
- if (q < 0) {
- r = q;
- goto finish;
- }
- }
-
- if (s->main_pid > 0) {
- q = set_put(pid_set, LONG_TO_PTR(s->main_pid));
- if (q < 0) {
- r = q;
- goto finish;
- }
- }
-
- q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, false, pid_set, NULL);
- if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
- r = q;
- }
-
-finish:
- if (pid_set)
- set_free(pid_set);
-
- return r;
+ return unit_kill_common(u, who, signo, s->main_pid, s->control_pid, error);
}
static const char* const service_state_table[_SERVICE_STATE_MAX] = {