core: add IgnoreOnSoftReboot= unit option
As it says on the tin, configures the unit to survive a soft reboot. Currently all the following options have to be set by hand: Conflicts=reboot.target kexec.target poweroff.target halt.target Before=reboot.target kexec.target poweroff.target halt.target After=sysinit.target basic.target DefaultDependencies=no IgnoreOnIsolate=yes This is not very user friendly. If new default dependencies are added, or new shutdown/reboot types, they also have to be added manually. The new option is much simpler, easy to find, and does the right thing by default.
This commit is contained in:
committed by
Zbigniew Jędrzejewski-Szmek
parent
03d298e1e5
commit
b80fc61e89
@@ -921,6 +921,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
|
||||
SD_BUS_PROPERTY("RefuseManualStop", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_stop), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("AllowIsolate", "b", bus_property_get_bool, offsetof(Unit, allow_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultDependencies", "b", bus_property_get_bool, offsetof(Unit, default_dependencies), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("IgnoreOnSoftReboot", "b", bus_property_get_bool, offsetof(Unit, ignore_on_soft_reboot), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("OnSuccesJobMode", "s", property_get_job_mode, offsetof(Unit, on_success_job_mode), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* deprecated */
|
||||
SD_BUS_PROPERTY("OnSuccessJobMode", "s", property_get_job_mode, offsetof(Unit, on_success_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("OnFailureJobMode", "s", property_get_job_mode, offsetof(Unit, on_failure_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
@@ -2175,6 +2176,9 @@ static int bus_unit_set_transient_property(
|
||||
if (streq(name, "DefaultDependencies"))
|
||||
return bus_set_transient_bool(u, name, &u->default_dependencies, message, flags, error);
|
||||
|
||||
if (streq(name, "IgnoreOnSoftReboot"))
|
||||
return bus_set_transient_bool(u, name, &u->ignore_on_soft_reboot, message, flags, error);
|
||||
|
||||
if (streq(name, "OnSuccessJobMode"))
|
||||
return bus_set_transient_job_mode(u, name, &u->on_success_job_mode, message, flags, error);
|
||||
|
||||
|
||||
@@ -312,6 +312,7 @@ Unit.RefuseManualStart, config_parse_bool,
|
||||
Unit.RefuseManualStop, config_parse_bool, 0, offsetof(Unit, refuse_manual_stop)
|
||||
Unit.AllowIsolate, config_parse_bool, 0, offsetof(Unit, allow_isolate)
|
||||
Unit.DefaultDependencies, config_parse_bool, 0, offsetof(Unit, default_dependencies)
|
||||
Unit.IgnoreOnSoftReboot, config_parse_bool, 0, offsetof(Unit, ignore_on_soft_reboot)
|
||||
Unit.OnSuccessJobMode, config_parse_job_mode, 0, offsetof(Unit, on_success_job_mode)
|
||||
Unit.OnFailureJobMode, config_parse_job_mode, 0, offsetof(Unit, on_failure_job_mode)
|
||||
{# The following is a legacy alias name for compatibility #}
|
||||
|
||||
+14
-2
@@ -342,12 +342,24 @@ static int path_add_default_dependencies(Path *p) {
|
||||
return r;
|
||||
|
||||
if (MANAGER_IS_SYSTEM(UNIT(p)->manager)) {
|
||||
r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
r = unit_add_two_dependencies_by_name(UNIT(p),
|
||||
UNIT_AFTER,
|
||||
UNIT(p)->ignore_on_soft_reboot ? -EINVAL : UNIT_REQUIRES,
|
||||
SPECIAL_SYSINIT_TARGET,
|
||||
true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return unit_add_two_dependencies_by_name(UNIT(p), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
if (!UNIT(p)->ignore_on_soft_reboot)
|
||||
return unit_add_two_dependencies_by_name(
|
||||
UNIT(p),
|
||||
UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
SPECIAL_SHUTDOWN_TARGET, true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
|
||||
return unit_add_dependencies_on_real_shutdown_targets(UNIT(p));
|
||||
}
|
||||
|
||||
static int path_add_trigger_dependencies(Path *p) {
|
||||
|
||||
+9
-10
@@ -131,23 +131,22 @@ static void scope_set_state(Scope *s, ScopeState state) {
|
||||
}
|
||||
|
||||
static int scope_add_default_dependencies(Scope *s) {
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (!UNIT(s)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
/* Make sure scopes are unloaded on shutdown */
|
||||
r = unit_add_two_dependencies_by_name(
|
||||
UNIT(s),
|
||||
UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
SPECIAL_SHUTDOWN_TARGET, true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!UNIT(s)->ignore_on_soft_reboot)
|
||||
return unit_add_two_dependencies_by_name(
|
||||
UNIT(s),
|
||||
UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
SPECIAL_SHUTDOWN_TARGET, true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
|
||||
return 0;
|
||||
/* Unless we are meant to survive soft reboot, in which case we need to conflict with
|
||||
* non-soft-reboot targets. */
|
||||
return unit_add_dependencies_on_real_shutdown_targets(UNIT(s));
|
||||
}
|
||||
|
||||
static int scope_verify(Scope *s) {
|
||||
|
||||
+20
-5
@@ -722,11 +722,16 @@ static int service_add_default_dependencies(Service *s) {
|
||||
* majority of services. */
|
||||
|
||||
if (MANAGER_IS_SYSTEM(UNIT(s)->manager)) {
|
||||
/* First, pull in the really early boot stuff, and
|
||||
* require it, so that we fail if we can't acquire
|
||||
* it. */
|
||||
/* First, pull in the really early boot stuff, and require it, so that we fail if we can't
|
||||
* acquire it. But only add ordering if this is meant to survive a soft reboot, otherwise
|
||||
* it will be pulled down. */
|
||||
|
||||
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
r = unit_add_two_dependencies_by_name(UNIT(s),
|
||||
UNIT_AFTER,
|
||||
UNIT(s)->ignore_on_soft_reboot ? -EINVAL : UNIT_REQUIRES,
|
||||
SPECIAL_SYSINIT_TARGET,
|
||||
true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
@@ -747,7 +752,17 @@ static int service_add_default_dependencies(Service *s) {
|
||||
return r;
|
||||
|
||||
/* Third, add us in for normal shutdown. */
|
||||
return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
if (!UNIT(s)->ignore_on_soft_reboot)
|
||||
return unit_add_two_dependencies_by_name(UNIT(s),
|
||||
UNIT_BEFORE,
|
||||
UNIT_CONFLICTS,
|
||||
SPECIAL_SHUTDOWN_TARGET,
|
||||
true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
|
||||
/* Unless we are meant to survive soft reboot, in which case we need to conflict with
|
||||
* non-soft-reboot targets. */
|
||||
return unit_add_dependencies_on_real_shutdown_targets(UNIT(s));
|
||||
}
|
||||
|
||||
static void service_fix_stdio(Service *s) {
|
||||
|
||||
+9
-9
@@ -64,22 +64,22 @@ static int slice_add_parent_slice(Slice *s) {
|
||||
}
|
||||
|
||||
static int slice_add_default_dependencies(Slice *s) {
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
if (!UNIT(s)->default_dependencies)
|
||||
return 0;
|
||||
|
||||
/* Make sure slices are unloaded on shutdown */
|
||||
r = unit_add_two_dependencies_by_name(
|
||||
UNIT(s),
|
||||
UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!UNIT(s)->ignore_on_soft_reboot)
|
||||
return unit_add_two_dependencies_by_name(
|
||||
UNIT(s),
|
||||
UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
SPECIAL_SHUTDOWN_TARGET, true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
|
||||
return 0;
|
||||
/* Unless we are meant to survive soft reboot, in which case we need to conflict with
|
||||
* non-soft-reboot targets. */
|
||||
return unit_add_dependencies_on_real_shutdown_targets(UNIT(s));
|
||||
}
|
||||
|
||||
static int slice_verify(Slice *s) {
|
||||
|
||||
+14
-2
@@ -278,12 +278,24 @@ static int socket_add_default_dependencies(Socket *s) {
|
||||
return r;
|
||||
|
||||
if (MANAGER_IS_SYSTEM(UNIT(s)->manager)) {
|
||||
r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
r = unit_add_two_dependencies_by_name(UNIT(s),
|
||||
UNIT_AFTER,
|
||||
UNIT(s)->ignore_on_soft_reboot ? -EINVAL : UNIT_REQUIRES,
|
||||
SPECIAL_SYSINIT_TARGET,
|
||||
true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
if (!UNIT(s)->ignore_on_soft_reboot)
|
||||
return unit_add_two_dependencies_by_name(
|
||||
UNIT(s),
|
||||
UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
SPECIAL_SHUTDOWN_TARGET, true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
|
||||
return unit_add_dependencies_on_real_shutdown_targets(UNIT(s));
|
||||
}
|
||||
|
||||
_pure_ static bool socket_has_exec(Socket *s) {
|
||||
|
||||
+10
-1
@@ -66,7 +66,16 @@ static int target_add_default_dependencies(Target *t) {
|
||||
return 0;
|
||||
|
||||
/* Make sure targets are unloaded on shutdown */
|
||||
return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
if (!UNIT(t)->ignore_on_soft_reboot)
|
||||
return unit_add_two_dependencies_by_name(
|
||||
UNIT(t),
|
||||
UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
SPECIAL_SHUTDOWN_TARGET, true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
|
||||
/* Unless we are meant to survive soft reboot, in which case we need to conflict with
|
||||
* non-soft-reboot targets. */
|
||||
return unit_add_dependencies_on_real_shutdown_targets(UNIT(t));
|
||||
}
|
||||
|
||||
static int target_load(Unit *u) {
|
||||
|
||||
+14
-2
@@ -94,7 +94,12 @@ static int timer_add_default_dependencies(Timer *t) {
|
||||
return r;
|
||||
|
||||
if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) {
|
||||
r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
r = unit_add_two_dependencies_by_name(UNIT(t),
|
||||
UNIT_AFTER,
|
||||
UNIT(t)->ignore_on_soft_reboot ? -EINVAL : UNIT_REQUIRES,
|
||||
SPECIAL_SYSINIT_TARGET,
|
||||
true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -112,7 +117,14 @@ static int timer_add_default_dependencies(Timer *t) {
|
||||
}
|
||||
}
|
||||
|
||||
return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, true, UNIT_DEPENDENCY_DEFAULT);
|
||||
if (!UNIT(t)->ignore_on_soft_reboot)
|
||||
return unit_add_two_dependencies_by_name(
|
||||
UNIT(t),
|
||||
UNIT_BEFORE, UNIT_CONFLICTS,
|
||||
SPECIAL_SHUTDOWN_TARGET, true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
|
||||
return unit_add_dependencies_on_real_shutdown_targets(UNIT(t));
|
||||
}
|
||||
|
||||
static int timer_add_trigger_dependencies(Timer *t) {
|
||||
|
||||
@@ -628,7 +628,7 @@ static int transaction_apply(
|
||||
HASHMAP_FOREACH(j, m->jobs) {
|
||||
assert(j->installed);
|
||||
|
||||
if (j->unit->ignore_on_isolate)
|
||||
if (j->unit->ignore_on_isolate || j->unit->ignore_on_soft_reboot)
|
||||
continue;
|
||||
|
||||
if (hashmap_contains(tr->jobs, j->unit))
|
||||
@@ -1159,6 +1159,9 @@ static bool shall_stop_on_isolate(Transaction *tr, Unit *u) {
|
||||
if (u->ignore_on_isolate)
|
||||
return false;
|
||||
|
||||
if (u->ignore_on_soft_reboot)
|
||||
return false;
|
||||
|
||||
/* Is there already something listed for this? */
|
||||
if (hashmap_contains(tr->jobs, u))
|
||||
return false;
|
||||
|
||||
@@ -830,6 +830,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
"%s\tRefuseManualStart: %s\n"
|
||||
"%s\tRefuseManualStop: %s\n"
|
||||
"%s\tDefaultDependencies: %s\n"
|
||||
"%s\tIgnoreOnSoftReboot: %s\n"
|
||||
"%s\tOnSuccessJobMode: %s\n"
|
||||
"%s\tOnFailureJobMode: %s\n"
|
||||
"%s\tIgnoreOnIsolate: %s\n",
|
||||
@@ -837,6 +838,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
prefix, yes_no(u->refuse_manual_start),
|
||||
prefix, yes_no(u->refuse_manual_stop),
|
||||
prefix, yes_no(u->default_dependencies),
|
||||
prefix, yes_no(u->ignore_on_soft_reboot),
|
||||
prefix, job_mode_to_string(u->on_success_job_mode),
|
||||
prefix, job_mode_to_string(u->on_failure_job_mode),
|
||||
prefix, yes_no(u->ignore_on_isolate));
|
||||
|
||||
+36
-9
@@ -3291,19 +3291,46 @@ int unit_add_dependency(
|
||||
}
|
||||
|
||||
int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference, UnitDependencyMask mask) {
|
||||
int r, s;
|
||||
int r = 0, s = 0;
|
||||
|
||||
assert(u);
|
||||
assert(d >= 0 || e >= 0);
|
||||
|
||||
if (d >= 0) {
|
||||
r = unit_add_dependency(u, d, other, add_reference, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (e >= 0) {
|
||||
s = unit_add_dependency(u, e, other, add_reference, mask);
|
||||
if (s < 0)
|
||||
return s;
|
||||
}
|
||||
|
||||
return r > 0 || s > 0;
|
||||
}
|
||||
|
||||
int unit_add_dependencies_on_real_shutdown_targets(Unit *u) {
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
|
||||
r = unit_add_dependency(u, d, other, add_reference, mask);
|
||||
if (r < 0)
|
||||
return r;
|
||||
STRV_FOREACH(target, STRV_MAKE(SPECIAL_REBOOT_TARGET,
|
||||
SPECIAL_KEXEC_TARGET,
|
||||
SPECIAL_HALT_TARGET,
|
||||
SPECIAL_POWEROFF_TARGET)) {
|
||||
r = unit_add_two_dependencies_by_name(u,
|
||||
UNIT_BEFORE,
|
||||
UNIT_CONFLICTS,
|
||||
*target,
|
||||
/* add_reference= */ true,
|
||||
UNIT_DEPENDENCY_DEFAULT);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
s = unit_add_dependency(u, e, other, add_reference, mask);
|
||||
if (s < 0)
|
||||
return s;
|
||||
|
||||
return r > 0 || s > 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int resolve_template(Unit *u, const char *name, char **buf, const char **ret) {
|
||||
|
||||
@@ -450,6 +450,9 @@ typedef struct Unit {
|
||||
/* Create default dependencies */
|
||||
bool default_dependencies;
|
||||
|
||||
/* Configure so that the unit survives a soft reboot without stopping/starting. */
|
||||
bool ignore_on_soft_reboot;
|
||||
|
||||
/* Refuse manual starting, allow starting only indirectly via dependency. */
|
||||
bool refuse_manual_start;
|
||||
|
||||
@@ -852,6 +855,8 @@ int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, boo
|
||||
int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, bool add_reference, UnitDependencyMask mask);
|
||||
|
||||
int unit_add_exec_dependencies(Unit *u, ExecContext *c);
|
||||
/* Helper for IgnoreOnSoftReboot units that need to survive soft-reboot.target but not others */
|
||||
int unit_add_dependencies_on_real_shutdown_targets(Unit *u);
|
||||
|
||||
int unit_choose_id(Unit *u, const char *name);
|
||||
int unit_set_description(Unit *u, const char *description);
|
||||
|
||||
Reference in New Issue
Block a user