mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-02-23 21:57:46 +03:00
core: introduce SuccessAction= as unit file property
SuccessAction= is similar to FailureAction= but declares what to do on success of a unit, rather than on failure. This is useful for running commands in qemu/nspawn images, that shall power down on completion. We frequently see "ExecStopPost=/usr/bin/systemctl poweroff" or so in unit files like this. Offer a simple, more declarative alternative for this. While we are at it, hook up failure action with unit_dump() and transient units too.
This commit is contained in:
parent
53c35a766f
commit
e7dfbb4e74
@ -879,10 +879,12 @@
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>FailureAction=</varname></term>
|
||||
<listitem><para>Configure the action to take when the unit enters the failed state. Takes the same values as
|
||||
the setting <varname>StartLimitAction=</varname> setting and executes the same actions (see
|
||||
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>). Defaults to
|
||||
<option>none</option>. </para></listitem>
|
||||
<term><varname>SuccessAction=</varname></term>
|
||||
<listitem><para>Configure the action to take when the unit stops and enters a failed state or inactive
|
||||
state. Takes the same values as the setting <varname>StartLimitAction=</varname> setting and executes the same
|
||||
actions (see
|
||||
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>). Both options
|
||||
default to <option>none</option>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -799,6 +799,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
|
||||
SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action, offsetof(Unit, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SuccessAction", "s", property_get_emergency_action, offsetof(Unit, success_action), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("InvocationID", "ay", bus_property_get_id128, offsetof(Unit, invocation_id), 0),
|
||||
SD_BUS_PROPERTY("CollectMode", "s", property_get_collect_mode, offsetof(Unit, collect_mode), 0),
|
||||
@ -1471,6 +1472,30 @@ static int bus_unit_set_transient_property(
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "FailureAction", "SuccessAction")) {
|
||||
EmergencyAction action;
|
||||
const char *s;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
action = emergency_action_from_string(s);
|
||||
if (action < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid emergency action: %s", s);
|
||||
|
||||
if (mode != UNIT_CHECK) {
|
||||
|
||||
if (streq(name, "FailureAction"))
|
||||
u->failure_action = action;
|
||||
else
|
||||
u->success_action = action;
|
||||
|
||||
unit_write_drop_in_format(u, mode, name, "%s=%s", name, emergency_action_to_string(action));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "AddRef")) {
|
||||
|
||||
int b;
|
||||
|
@ -224,6 +224,7 @@ Unit.StartLimitInterval, config_parse_sec, 0,
|
||||
Unit.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
|
||||
Unit.StartLimitAction, config_parse_emergency_action, 0, offsetof(Unit, start_limit_action)
|
||||
Unit.FailureAction, config_parse_emergency_action, 0, offsetof(Unit, failure_action)
|
||||
Unit.SuccessAction, config_parse_emergency_action, 0, offsetof(Unit, success_action)
|
||||
Unit.RebootArgument, config_parse_unit_string_printf, 0, offsetof(Unit, reboot_arg)
|
||||
Unit.ConditionPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, offsetof(Unit, conditions)
|
||||
Unit.ConditionPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, offsetof(Unit, conditions)
|
||||
|
@ -1181,6 +1181,11 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
STRV_FOREACH(j, u->dropin_paths)
|
||||
fprintf(f, "%s\tDropIn Path: %s\n", prefix, *j);
|
||||
|
||||
if (u->failure_action != EMERGENCY_ACTION_NONE)
|
||||
fprintf(f, "%s\tFailure Action: %s\n", prefix, emergency_action_to_string(u->failure_action));
|
||||
if (u->success_action != EMERGENCY_ACTION_NONE)
|
||||
fprintf(f, "%s\tSuccess Action: %s\n", prefix, emergency_action_to_string(u->success_action));
|
||||
|
||||
if (u->job_timeout != USEC_INFINITY)
|
||||
fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
|
||||
|
||||
@ -2506,6 +2511,8 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
|
||||
|
||||
if (os != UNIT_FAILED && ns == UNIT_FAILED)
|
||||
(void) emergency_action(u->manager, u->failure_action, u->reboot_arg, "unit failed");
|
||||
else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && ns == UNIT_INACTIVE)
|
||||
(void) emergency_action(u->manager, u->success_action, u->reboot_arg, "unit succeeded");
|
||||
}
|
||||
|
||||
unit_add_to_dbus_queue(u);
|
||||
|
@ -250,6 +250,7 @@ struct Unit {
|
||||
EmergencyAction start_limit_action;
|
||||
|
||||
EmergencyAction failure_action;
|
||||
EmergencyAction success_action;
|
||||
char *reboot_arg;
|
||||
|
||||
/* Make sure we never enter endless loops with the check unneeded logic, or the BindsTo= logic */
|
||||
|
@ -408,7 +408,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
|
||||
"RootDirectory", "SyslogIdentifier", "ProtectSystem",
|
||||
"ProtectHome", "SELinuxContext", "Restart", "RootImage",
|
||||
"NotifyAccess", "RuntimeDirectoryPreserve", "Personality",
|
||||
"KeyringMode", "CollectMode"))
|
||||
"KeyringMode", "CollectMode", "FailureAction", "SuccessAction"))
|
||||
r = sd_bus_message_append(m, "v", "s", eq);
|
||||
|
||||
else if (streq(field, "StandardInputData")) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user