/* FIXME: Maybe we should compare the name here lexicographically? */
- if (!(r = unit_add_dependency(UNIT(s), d, UNIT(t))) < 0)
+ if (!(r = unit_add_dependency(UNIT(s), d, UNIT(t), true)) < 0)
return r;
}
if (unit_name_to_type(m) == UNIT_SERVICE)
r = unit_add_name(u, m);
else {
- if ((r = unit_add_dependency_by_name_inverse(u, UNIT_REQUIRES, m, NULL)) >= 0)
- r = unit_add_dependency_by_name(u, UNIT_BEFORE, m, NULL);
+ if ((r = unit_add_dependency_by_name_inverse(u, UNIT_REQUIRES, m, NULL, true)) >= 0)
+ r = unit_add_dependency_by_name(u, UNIT_BEFORE, m, NULL, true);
}
free(m);
if (r == 0)
continue;
- r = unit_add_dependency_by_name(u, UNIT_AFTER, m, NULL);
+ r = unit_add_dependency_by_name(u, UNIT_AFTER, m, NULL, true);
free(m);
if (r < 0)
* needed for early boot) and don't create any links
* to it. */
- if ((r = unit_add_dependency_by_name(u, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL)) < 0 ||
- (r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_BASIC_TARGET, NULL)) < 0)
+ if ((r = unit_add_dependency_by_name(u, UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true)) < 0 ||
+ (r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_BASIC_TARGET, NULL, true)) < 0)
goto finish;
}
if (!s->exec_command[c])
continue;
- fprintf(f, "%s→ %s:\n",
+ fprintf(f, "%s-> %s:\n",
prefix, service_exec_command_to_string(c));
exec_command_dump_list(s->exec_command[c], f, prefix2);
service_close_socket_fd(s);
if (old_state != state)
- log_debug("%s changed %s → %s", UNIT(s)->meta.id, service_state_to_string(old_state), service_state_to_string(state));
+ log_debug("%s changed %s -> %s", UNIT(s)->meta.id, service_state_to_string(old_state), service_state_to_string(state));
unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]);
}
s->deserialized_state == SERVICE_STOP_POST ||
s->deserialized_state == SERVICE_FINAL_SIGTERM ||
s->deserialized_state == SERVICE_FINAL_SIGKILL ||
- s->deserialized_state == SERVICE_AUTO_RESTART)
- if ((r = unit_watch_timer(UNIT(s),
- s->deserialized_state == SERVICE_AUTO_RESTART ?
- s->restart_usec :
- s->timeout_usec,
- &s->timer_watch)) < 0)
- return r;
+ s->deserialized_state == SERVICE_AUTO_RESTART) {
+
+ if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_usec > 0) {
+ usec_t k;
+
+ k = s->deserialized_state == SERVICE_AUTO_RESTART ? s->restart_usec : s->timeout_usec;
+
+ if ((r = unit_watch_timer(UNIT(s), k, &s->timer_watch)) < 0)
+ return r;
+ }
+ }
if ((s->deserialized_state == SERVICE_START &&
(s->type == SERVICE_FORKING ||
goto fail;
}
- if (timeout) {
+ if (timeout && s->timeout_usec) {
if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
goto fail;
} else
s->failure = true;
if (allow_restart &&
+ s->allow_restart &&
(s->restart == SERVICE_RESTART_ALWAYS ||
(s->restart == SERVICE_RESTART_ON_SUCCESS && !s->failure))) {
}
if (sent) {
- if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
- goto fail;
+ if (s->timeout_usec > 0)
+ if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0)
+ goto fail;
service_set_state(s, state);
} else if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL)
s->failure = false;
s->main_pid_known = false;
+ s->allow_restart = true;
service_enter_start_pre(s);
return 0;
assert(s->state == SERVICE_RUNNING || s->state == SERVICE_EXITED);
+ /* This is a user request, so don't do restarts on this
+ * shutdown. */
+ s->allow_restart = false;
+
service_enter_stop(s, true);
return 0;
}
* commands attached here, we will start from the first one
* again */
if (s->control_command_id >= 0)
- unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(s->control_command_id));
+ unit_serialize_item(u, f, "control-command", service_exec_command_to_string(s->control_command_id));
if (s->socket_fd >= 0) {
int copy;
return service_state_to_string(SERVICE(u)->state);
}
+static bool service_check_gc(Unit *u) {
+ Service *s = SERVICE(u);
+
+ assert(s);
+
+ return !!s->sysv_path;
+}
+
+static bool service_check_snapshot(Unit *u) {
+ Service *s = SERVICE(u);
+
+ assert(s);
+
+ return !s->got_socket_fd;
+}
+
static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
Service *s = SERVICE(u);
bool success;
}
while ((de = readdir(d))) {
- Unit *runlevel, *service;
+ Unit *service;
if (ignore_file(de->d_name))
continue;
if ((r = manager_load_unit(m, name, NULL, &service)) < 0)
goto finish;
- if ((r = manager_load_unit(m, rcnd_table[i+1], NULL, &runlevel)) < 0)
- goto finish;
-
if (de->d_name[0] == 'S') {
- if ((r = unit_add_dependency(runlevel, UNIT_WANTS, service)) < 0)
+ Unit *runlevel_target;
+
+ if ((r = manager_load_unit(m, rcnd_table[i+1], NULL, &runlevel_target)) < 0)
+ goto finish;
+
+ if ((r = unit_add_dependency(runlevel_target, UNIT_WANTS, service, true)) < 0)
goto finish;
- if ((r = unit_add_dependency(runlevel, UNIT_AFTER, service)) < 0)
+ if ((r = unit_add_dependency(service, UNIT_BEFORE, runlevel_target, true)) < 0)
goto finish;
} else if (de->d_name[0] == 'K' &&
(streq(rcnd_table[i+1], SPECIAL_RUNLEVEL0_TARGET) ||
streq(rcnd_table[i+1], SPECIAL_RUNLEVEL6_TARGET))) {
+ Unit *shutdown_target;
+
/* We honour K links only for
* halt/reboot. For the normal
* runlevels we assume the
* stop jobs will be
* implicitly added by the
- * core logic. */
+ * core logic. Also, we don't
+ * really distuingish here
+ * between the runlevels 0 and
+ * 6 and just add them to the
+ * special shutdown target. */
+
+ if ((r = manager_load_unit(m, SPECIAL_SHUTDOWN_TARGET, NULL, &shutdown_target)) < 0)
+ goto finish;
- if ((r = unit_add_dependency(runlevel, UNIT_CONFLICTS, service)) < 0)
+ if ((r = unit_add_dependency(service, UNIT_CONFLICTS, shutdown_target, true)) < 0)
goto finish;
- if ((r = unit_add_dependency(runlevel, UNIT_BEFORE, service)) < 0)
+ if ((r = unit_add_dependency(service, UNIT_BEFORE, shutdown_target, true)) < 0)
goto finish;
}
}
return -EAGAIN;
s->socket_fd = fd;
+ s->got_socket_fd = true;
return 0;
}
.active_state = service_active_state,
.sub_state_to_string = service_sub_state_to_string,
+ .check_gc = service_check_gc,
+ .check_snapshot = service_check_snapshot,
+
.sigchld_event = service_sigchld_event,
.timer_event = service_timer_event,