fs->service->n_fd_store--;
}
- if (fs->event_source) {
- sd_event_source_set_enabled(fs->event_source, SD_EVENT_OFF);
- sd_event_source_unref(fs->event_source);
- }
+ sd_event_source_disable_unref(fs->event_source);
free(fs->fdname);
safe_close(fs->fd);
log_unit_warning(UNIT(s), "Service has USBFunctionStrings= setting, but no USBFunctionDescriptors=. Ignoring.");
if (s->runtime_max_usec != USEC_INFINITY && s->type == SERVICE_ONESHOT)
- log_unit_warning(UNIT(s), "MaxRuntimeSec= has no effect in combination with Type=oneshot. Ignoring.");
+ log_unit_warning(UNIT(s), "RuntimeMaxSec= has no effect in combination with Type=oneshot. Ignoring.");
return 0;
}
/* If no OOM policy was explicitly set, then default to the configure default OOM policy. Except when
* delegation is on, in that case it we assume the payload knows better what to do and can process
- * things in a more focussed way. */
+ * things in a more focused way. */
if (s->oom_policy < 0)
s->oom_policy = s->cgroup_context.delegate ? OOM_CONTINUE : UNIT(s)->manager->default_oom_policy;
fprintf(f,
"%sRestartSec: %s\n"
"%sTimeoutStartSec: %s\n"
- "%sTimeoutStopSec: %s\n"
- "%sTimeoutAbortSec: %s\n"
- "%sRuntimeMaxSec: %s\n"
- "%sWatchdogSec: %s\n",
+ "%sTimeoutStopSec: %s\n",
prefix, format_timespan(buf_restart, sizeof(buf_restart), s->restart_usec, USEC_PER_SEC),
prefix, format_timespan(buf_start, sizeof(buf_start), s->timeout_start_usec, USEC_PER_SEC),
- prefix, format_timespan(buf_stop, sizeof(buf_stop), s->timeout_stop_usec, USEC_PER_SEC),
- prefix, s->timeout_abort_set
- ? format_timespan(buf_abort, sizeof(buf_abort), s->timeout_abort_usec, USEC_PER_SEC)
- : "",
+ prefix, format_timespan(buf_stop, sizeof(buf_stop), s->timeout_stop_usec, USEC_PER_SEC));
+
+ if (s->timeout_abort_set)
+ fprintf(f,
+ "%sTimeoutAbortSec: %s\n",
+ prefix, format_timespan(buf_abort, sizeof(buf_abort), s->timeout_abort_usec, USEC_PER_SEC));
+
+ fprintf(f,
+ "%sRuntimeMaxSec: %s\n"
+ "%sWatchdogSec: %s\n",
prefix, format_timespan(buf_runtime, sizeof(buf_runtime), s->runtime_max_usec, USEC_PER_SEC),
prefix, format_timespan(buf_watchdog, sizeof(buf_watchdog), s->watchdog_usec, USEC_PER_SEC));
* user can still introspect the counter. Do so on the next start. */
s->flush_n_restarts = true;
- /* The new state is in effect, let's decrease the fd store ref counter again. Let's also readd us to the GC
+ /* The new state is in effect, let's decrease the fd store ref counter again. Let's also re-add us to the GC
* queue, so that the fd store is possibly gc'ed again */
s->n_keep_fd_store--;
unit_add_to_gc_queue(UNIT(s));
* aren't as rigoriously written to protect aganst against multiple use. */
if (unit_warn_leftover_processes(UNIT(s)) &&
IN_SET(s->kill_context.kill_mode, KILL_MIXED, KILL_CONTROL_GROUP) &&
- !s->kill_context.send_sigkill) {
- return log_unit_error_errno(UNIT(s), SYNTHETIC_ERRNO(EBUSY), "Will not start SendSIGKILL=no service of type KillMode=control-group or mixed while processes exist");
- }
+ !s->kill_context.send_sigkill)
+ return log_unit_error_errno(UNIT(s), SYNTHETIC_ERRNO(EBUSY),
+ "Will not start SendSIGKILL=no service of type KillMode=control-group or mixed while processes exist");
+
return 0;
}
/* We force a fake state transition here. Otherwise, the unit would go directly from
* SERVICE_DEAD to SERVICE_DEAD without SERVICE_ACTIVATING or SERVICE_ACTIVE
- * inbetween. This way we can later trigger actions that depend on the state
+ * in between. This way we can later trigger actions that depend on the state
* transition, including SuccessAction=. */
service_set_state(s, SERVICE_START);
return true;
}
+static void service_force_watchdog(Service *s) {
+ if (!UNIT(s)->manager->service_watchdogs)
+ return;
+
+ log_unit_error(UNIT(s), "Watchdog request (last status: %s)!",
+ s->status_text ? s->status_text : "<unset>");
+
+ service_enter_signal(s, SERVICE_STOP_WATCHDOG, SERVICE_FAILURE_WATCHDOG);
+}
+
static void service_notify_message(
Unit *u,
const struct ucred *ucred,
r = service_is_suitable_main_pid(s, new_main_pid, LOG_WARNING);
if (r == 0) {
- /* The new main PID is a bit suspicous, which is OK if the sender is privileged. */
+ /* The new main PID is a bit suspicious, which is OK if the sender is privileged. */
if (ucred->uid == 0) {
log_unit_debug(u, "New main PID "PID_FMT" does not belong to service, but we'll accept it as the request to change it came from a privileged process.", new_main_pid);
}
/* Interpret WATCHDOG= */
- if (strv_find(tags, "WATCHDOG=1"))
- service_reset_watchdog(s);
+ e = strv_find_startswith(tags, "WATCHDOG=");
+ if (e) {
+ if (streq(e, "1"))
+ service_reset_watchdog(s);
+ else if (streq(e, "trigger"))
+ service_force_watchdog(s);
+ else
+ log_unit_warning(u, "Passed WATCHDOG= field is invalid, ignoring.");
+ }
e = strv_find_startswith(tags, "WATCHDOG_USEC=");
if (e) {
DEFINE_STRING_TABLE_LOOKUP(service_exec_command, ServiceExecCommand);
+static const char* const service_exec_ex_command_table[_SERVICE_EXEC_COMMAND_MAX] = {
+ [SERVICE_EXEC_START_PRE] = "ExecStartPreEx",
+ [SERVICE_EXEC_START] = "ExecStartEx",
+ [SERVICE_EXEC_START_POST] = "ExecStartPostEx",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(service_exec_ex_command, ServiceExecCommand);
+
static const char* const notify_state_table[_NOTIFY_STATE_MAX] = {
[NOTIFY_UNKNOWN] = "unknown",
[NOTIFY_READY] = "ready",