1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-25 01:34:28 +03:00

Merge pull request #14505 from poettering/refuse-on-failure

refuse OnFailure= deps on units that have no failure state
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-01-14 14:19:04 +01:00 committed by GitHub
commit 7c286cd6a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 58 additions and 10 deletions

View File

@ -79,7 +79,7 @@
</row>
<row>
<entry><constant>sl</constant></entry>
<entry>serial line IP (slip)</entry>
<entry>Serial line IP (slip)</entry>
</row>
<row>
<entry><constant>wl</constant></entry>

View File

@ -45,6 +45,15 @@
url="https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces</ulink> for an introduction on how to make
use of scope units from programs.</para>
<para>Note that unlike service units scope units have no "main" process, all processes in the scope are
equivalent. The lifecycle of the scope unit is thus not bound to the lifetime of one specific process but
to the existance of any processes in the scope. This also means that the exit status of these processes
do not cause the scope unit to enter a failure state. Scope units may still enter a failure state, for
example due to resource exhaustion or stop timeouts being reached, but not due to programs inside of them
terminating uncleanly. Since processes managed as scope units generally remain children of the original
process that forked them off it's also the job of that process to collect their exit statuses and act on
them as needed.</para>
</refsect1>
<refsect1>

View File

@ -1106,6 +1106,10 @@ const UnitVTable automount_vtable = {
"Automount\0"
"Install\0",
.can_transient = true,
.can_fail = true,
.can_trigger = true,
.init = automount_init,
.load = automount_load,
.done = automount_done,
@ -1132,8 +1136,6 @@ const UnitVTable automount_vtable = {
.bus_vtable = bus_automount_vtable,
.bus_set_property = bus_automount_set_property,
.can_transient = true,
.shutdown = automount_shutdown,
.supported = automount_supported,

View File

@ -1064,6 +1064,7 @@ const UnitVTable device_vtable = {
"Device\0"
"Install\0",
.refuse_after = true,
.gc_jobs = true,
.init = device_init,

View File

@ -2065,6 +2065,9 @@ const UnitVTable mount_vtable = {
"Install\0",
.private_section = "Mount",
.can_transient = true,
.can_fail = true,
.init = mount_init,
.load = mount_load,
.done = mount_done,
@ -2103,8 +2106,6 @@ const UnitVTable mount_vtable = {
.get_timeout = mount_get_timeout,
.can_transient = true,
.enumerate_perpetual = mount_enumerate_perpetual,
.enumerate = mount_enumerate,
.shutdown = mount_shutdown,

View File

@ -806,6 +806,8 @@ const UnitVTable path_vtable = {
.private_section = "Path",
.can_transient = true,
.can_fail = true,
.can_trigger = true,
.init = path_init,
.done = path_done,

View File

@ -619,6 +619,7 @@ const UnitVTable scope_vtable = {
.can_transient = true,
.can_delegate = true,
.can_fail = true,
.once_only = true,
.init = scope_init,

View File

@ -4391,6 +4391,7 @@ const UnitVTable service_vtable = {
.can_transient = true,
.can_delegate = true,
.can_fail = true,
.init = service_init,
.done = service_done,

View File

@ -3423,6 +3423,8 @@ const UnitVTable socket_vtable = {
.private_section = "Socket",
.can_transient = true,
.can_trigger = true,
.can_fail = true,
.init = socket_init,
.done = socket_done,

View File

@ -1590,6 +1590,8 @@ const UnitVTable swap_vtable = {
"Install\0",
.private_section = "Swap",
.can_fail = true,
.init = swap_init,
.load = swap_load,
.done = swap_done,

View File

@ -895,6 +895,10 @@ const UnitVTable timer_vtable = {
"Install\0",
.private_section = "Timer",
.can_transient = true,
.can_fail = true,
.can_trigger = true,
.init = timer_init,
.done = timer_done,
.load = timer_load,
@ -923,6 +927,4 @@ const UnitVTable timer_vtable = {
.bus_vtable = bus_timer_vtable,
.bus_set_property = bus_timer_set_property,
.can_transient = true,
};

View File

@ -2937,12 +2937,28 @@ int unit_add_dependency(
return 0;
}
if ((d == UNIT_BEFORE && other->type == UNIT_DEVICE) ||
(d == UNIT_AFTER && u->type == UNIT_DEVICE)) {
log_unit_warning(u, "Dependency Before=%s ignored (.device units cannot be delayed)", other->id);
if (d == UNIT_AFTER && UNIT_VTABLE(u)->refuse_after) {
log_unit_warning(u, "Requested dependency After=%s ignored (%s units cannot be delayed).", other->id, unit_type_to_string(u->type));
return 0;
}
if (d == UNIT_BEFORE && UNIT_VTABLE(other)->refuse_after) {
log_unit_warning(u, "Requested dependency Before=%s ignored (%s units cannot be delayed).", other->id, unit_type_to_string(other->type));
return 0;
}
if (d == UNIT_ON_FAILURE && !UNIT_VTABLE(u)->can_fail) {
log_unit_warning(u, "Requested dependency OnFailure=%s ignored (%s units cannot fail).", other->id, unit_type_to_string(u->type));
return 0;
}
if (d == UNIT_TRIGGERS && !UNIT_VTABLE(u)->can_trigger)
return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL),
"Requested dependency Triggers=%s refused (%s units cannot trigger other units).", other->id, unit_type_to_string(u->type));
if (d == UNIT_TRIGGERED_BY && !UNIT_VTABLE(other)->can_trigger)
return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL),
"Requested dependency TriggeredBy=%s refused (%s units cannot trigger other units).", other->id, unit_type_to_string(other->type));
r = unit_add_dependency_hashmap(u->dependencies + d, other, mask, 0);
if (r < 0)
return r;

View File

@ -600,6 +600,15 @@ typedef struct UnitVTable {
/* True if cgroup delegation is permissible */
bool can_delegate:1;
/* True if the unit type triggers other units, i.e. can have a UNIT_TRIGGERS dependency */
bool can_trigger:1;
/* True if the unit type knows a failure state, and thus can be source of an OnFailure= dependency */
bool can_fail:1;
/* True if After= dependencies should be refused */
bool refuse_after:1;
/* True if units of this type shall be startable only once and then never again */
bool once_only:1;