|
|
be0c12 |
From 19d91eef7f15b654cd96ad5350385e535fab9e2a Mon Sep 17 00:00:00 2001
|
|
|
be0c12 |
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
|
be0c12 |
Date: Tue, 16 Oct 2018 13:28:39 +0200
|
|
|
be0c12 |
Subject: [PATCH] core: define "exit" and "exit-force" actions for user units
|
|
|
be0c12 |
and only accept that
|
|
|
be0c12 |
|
|
|
be0c12 |
We would accept e.g. FailureAction=reboot-force in user units and then do an
|
|
|
be0c12 |
exit in the user manager. Let's be stricter, and define "exit"/"exit-force" as
|
|
|
be0c12 |
the only supported actions in user units.
|
|
|
be0c12 |
|
|
|
be0c12 |
v2:
|
|
|
be0c12 |
- rename 'exit' to 'exit-force' and add new 'exit'
|
|
|
be0c12 |
- add test for the parsing function
|
|
|
be0c12 |
|
|
|
be0c12 |
(cherry picked from commit 54fcb6192c618726d11404b24b1a1e9ec3169ee1)
|
|
|
be0c12 |
|
|
|
be0c12 |
Related: #1860899
|
|
|
be0c12 |
---
|
|
|
be0c12 |
TODO | 4 +++
|
|
|
be0c12 |
man/systemd.unit.xml | 26 +++++++++-------
|
|
|
be0c12 |
src/core/dbus-unit.c | 37 ++++++++++++++++++++++-
|
|
|
be0c12 |
src/core/emergency-action.c | 47 ++++++++++++++++++++++-------
|
|
|
be0c12 |
src/core/emergency-action.h | 5 ++++
|
|
|
be0c12 |
src/core/load-fragment.c | 42 +++++++++++++++++++++++++-
|
|
|
be0c12 |
src/test/meson.build | 5 ++++
|
|
|
be0c12 |
src/test/test-emergency-action.c | 51 ++++++++++++++++++++++++++++++++
|
|
|
be0c12 |
8 files changed, 195 insertions(+), 22 deletions(-)
|
|
|
be0c12 |
create mode 100644 src/test/test-emergency-action.c
|
|
|
be0c12 |
|
|
|
be0c12 |
diff --git a/TODO b/TODO
|
|
|
be0c12 |
index 3100e067d6..0705b6b08e 100644
|
|
|
be0c12 |
--- a/TODO
|
|
|
be0c12 |
+++ b/TODO
|
|
|
be0c12 |
@@ -4,6 +4,10 @@ Bugfixes:
|
|
|
be0c12 |
|
|
|
be0c12 |
* copy.c: set the right chattrs before copying files and others after
|
|
|
be0c12 |
|
|
|
be0c12 |
+* Many manager configuration settings that are only applicable to user
|
|
|
be0c12 |
+ manager or system manager can be always set. It would be better to reject
|
|
|
be0c12 |
+ them when parsing config.
|
|
|
be0c12 |
+
|
|
|
be0c12 |
External:
|
|
|
be0c12 |
|
|
|
be0c12 |
* Fedora: add an rpmlint check that verifies that all unit files in the RPM are listed in %systemd_post macros.
|
|
|
be0c12 |
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
|
|
|
be0c12 |
index 802db453a4..5772a6684e 100644
|
|
|
be0c12 |
--- a/man/systemd.unit.xml
|
|
|
be0c12 |
+++ b/man/systemd.unit.xml
|
|
|
be0c12 |
@@ -877,18 +877,24 @@
|
|
|
be0c12 |
<term><varname>FailureAction=</varname></term>
|
|
|
be0c12 |
<term><varname>SuccessAction=</varname></term>
|
|
|
be0c12 |
|
|
|
be0c12 |
- <listitem><para>Configure the action to take when the unit stops and enters a failed state or inactive
|
|
|
be0c12 |
- state. Takes one of <option>none</option>, <option>reboot</option>, <option>reboot-force</option>,
|
|
|
be0c12 |
- <option>reboot-immediate</option>, <option>poweroff</option>, <option>poweroff-force</option> or
|
|
|
be0c12 |
- <option>poweroff-immediate</option>. If <option>none</option> is set, no action will be triggered.
|
|
|
be0c12 |
- <option>reboot</option> causes a reboot following the normal shutdown procedure (i.e. equivalent to
|
|
|
be0c12 |
- <command>systemctl reboot</command>). <option>reboot-force</option> causes a forced reboot which will
|
|
|
be0c12 |
- terminate all processes forcibly but should cause no dirty file systems on reboot (i.e. equivalent to
|
|
|
be0c12 |
- <command>systemctl reboot -f</command>) and <option>reboot-immediate</option> causes immediate execution of the
|
|
|
be0c12 |
+ <listitem><para>Configure the action to take when the unit stops and enters a failed state or inactive state.
|
|
|
be0c12 |
+ Takes one of <option>none</option>, <option>reboot</option>, <option>reboot-force</option>,
|
|
|
be0c12 |
+ <option>reboot-immediate</option>, <option>poweroff</option>, <option>poweroff-force</option>,
|
|
|
be0c12 |
+ <option>poweroff-immediate</option>, <option>exit</option>, and <option>exit-force</option>. In system mode,
|
|
|
be0c12 |
+ all options except <option>exit</option> and <option>exit-force</option> are allowed. In user mode, only
|
|
|
be0c12 |
+ <option>none</option>, <option>exit</option>, and <option>exit-force</option> are allowed. Both options default
|
|
|
be0c12 |
+ to <option>none</option>.</para>
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ <para>If <option>none</option> is set, no action will be triggered. <option>reboot</option> causes a reboot
|
|
|
be0c12 |
+ following the normal shutdown procedure (i.e. equivalent to <command>systemctl reboot</command>).
|
|
|
be0c12 |
+ <option>reboot-force</option> causes a forced reboot which will terminate all processes forcibly but should
|
|
|
be0c12 |
+ cause no dirty file systems on reboot (i.e. equivalent to <command>systemctl reboot -f</command>) and
|
|
|
be0c12 |
+ <option>reboot-immediate</option> causes immediate execution of the
|
|
|
be0c12 |
<citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call, which
|
|
|
be0c12 |
might result in data loss. Similarly, <option>poweroff</option>, <option>poweroff-force</option>,
|
|
|
be0c12 |
- <option>poweroff-immediate</option> have the effect of powering down the system with similar semantics. Both
|
|
|
be0c12 |
- options default to <option>none</option>.</para></listitem>
|
|
|
be0c12 |
+ <option>poweroff-immediate</option> have the effect of powering down the system with similar
|
|
|
be0c12 |
+ semantics. <option>exit</option> causes the user manager to exit following the normal shutdown procedure, and
|
|
|
be0c12 |
+ <option>exit-force</option> causes it terminate without shutting down services.</para></listitem>
|
|
|
be0c12 |
</varlistentry>
|
|
|
be0c12 |
|
|
|
be0c12 |
<varlistentry>
|
|
|
be0c12 |
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
|
|
|
be0c12 |
index 549a166abc..e7ea9db3ac 100644
|
|
|
be0c12 |
--- a/src/core/dbus-unit.c
|
|
|
be0c12 |
+++ b/src/core/dbus-unit.c
|
|
|
be0c12 |
@@ -1564,8 +1564,43 @@ static int bus_unit_set_live_property(
|
|
|
be0c12 |
return 0;
|
|
|
be0c12 |
}
|
|
|
be0c12 |
|
|
|
be0c12 |
+static int bus_set_transient_emergency_action(
|
|
|
be0c12 |
+ Unit *u,
|
|
|
be0c12 |
+ const char *name,
|
|
|
be0c12 |
+ EmergencyAction *p,
|
|
|
be0c12 |
+ sd_bus_message *message,
|
|
|
be0c12 |
+ UnitWriteFlags flags,
|
|
|
be0c12 |
+ sd_bus_error *error) {
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ const char *s;
|
|
|
be0c12 |
+ EmergencyAction v;
|
|
|
be0c12 |
+ int r;
|
|
|
be0c12 |
+ bool system;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ assert(p);
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ r = sd_bus_message_read(message, "s", &s);
|
|
|
be0c12 |
+ if (r < 0)
|
|
|
be0c12 |
+ return r;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ system = MANAGER_IS_SYSTEM(u->manager);
|
|
|
be0c12 |
+ r = parse_emergency_action(s, system, &v);
|
|
|
be0c12 |
+ if (v < 0)
|
|
|
be0c12 |
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
|
|
be0c12 |
+ v == -EOPNOTSUPP ? "EmergencyAction setting invalid for manager type: %s"
|
|
|
be0c12 |
+ : "Invalid %s setting: %s",
|
|
|
be0c12 |
+ name, s);
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
|
|
be0c12 |
+ *p = v;
|
|
|
be0c12 |
+ unit_write_settingf(u, flags, name,
|
|
|
be0c12 |
+ "%s=%s", name, s);
|
|
|
be0c12 |
+ }
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ return 1;
|
|
|
be0c12 |
+}
|
|
|
be0c12 |
+
|
|
|
be0c12 |
static BUS_DEFINE_SET_TRANSIENT_PARSE(collect_mode, CollectMode, collect_mode_from_string);
|
|
|
be0c12 |
-static BUS_DEFINE_SET_TRANSIENT_PARSE(emergency_action, EmergencyAction, emergency_action_from_string);
|
|
|
be0c12 |
static BUS_DEFINE_SET_TRANSIENT_PARSE(job_mode, JobMode, job_mode_from_string);
|
|
|
be0c12 |
|
|
|
be0c12 |
static int bus_set_transient_conditions(
|
|
|
be0c12 |
diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c
|
|
|
be0c12 |
index 766a3b4d2b..00f5996317 100644
|
|
|
be0c12 |
--- a/src/core/emergency-action.c
|
|
|
be0c12 |
+++ b/src/core/emergency-action.c
|
|
|
be0c12 |
@@ -39,15 +39,6 @@ int emergency_action(
|
|
|
be0c12 |
return -ECANCELED;
|
|
|
be0c12 |
}
|
|
|
be0c12 |
|
|
|
be0c12 |
- if (!MANAGER_IS_SYSTEM(m)) {
|
|
|
be0c12 |
- /* Downgrade all options to simply exiting if we run
|
|
|
be0c12 |
- * in user mode */
|
|
|
be0c12 |
-
|
|
|
be0c12 |
- log_warning("Exiting: %s", reason);
|
|
|
be0c12 |
- m->exit_code = MANAGER_EXIT;
|
|
|
be0c12 |
- return -ECANCELED;
|
|
|
be0c12 |
- }
|
|
|
be0c12 |
-
|
|
|
be0c12 |
switch (action) {
|
|
|
be0c12 |
|
|
|
be0c12 |
case EMERGENCY_ACTION_REBOOT:
|
|
|
be0c12 |
@@ -80,11 +71,26 @@ int emergency_action(
|
|
|
be0c12 |
(void) reboot(RB_AUTOBOOT);
|
|
|
be0c12 |
break;
|
|
|
be0c12 |
|
|
|
be0c12 |
+ case EMERGENCY_ACTION_EXIT:
|
|
|
be0c12 |
+ assert(MANAGER_IS_USER(m));
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ log_and_status(m, "Exiting", reason);
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL);
|
|
|
be0c12 |
+ break;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
case EMERGENCY_ACTION_POWEROFF:
|
|
|
be0c12 |
log_and_status(m, "Powering off", reason);
|
|
|
be0c12 |
(void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL);
|
|
|
be0c12 |
break;
|
|
|
be0c12 |
|
|
|
be0c12 |
+ case EMERGENCY_ACTION_EXIT_FORCE:
|
|
|
be0c12 |
+ assert(MANAGER_IS_USER(m));
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ log_and_status(m, "Exiting immediately", reason);
|
|
|
be0c12 |
+ m->exit_code = MANAGER_EXIT;
|
|
|
be0c12 |
+ break;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
case EMERGENCY_ACTION_POWEROFF_FORCE:
|
|
|
be0c12 |
log_and_status(m, "Forcibly powering off", reason);
|
|
|
be0c12 |
m->exit_code = MANAGER_POWEROFF;
|
|
|
be0c12 |
@@ -113,6 +119,27 @@ static const char* const emergency_action_table[_EMERGENCY_ACTION_MAX] = {
|
|
|
be0c12 |
[EMERGENCY_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate",
|
|
|
be0c12 |
[EMERGENCY_ACTION_POWEROFF] = "poweroff",
|
|
|
be0c12 |
[EMERGENCY_ACTION_POWEROFF_FORCE] = "poweroff-force",
|
|
|
be0c12 |
- [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate"
|
|
|
be0c12 |
+ [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate",
|
|
|
be0c12 |
+ [EMERGENCY_ACTION_EXIT] = "exit",
|
|
|
be0c12 |
+ [EMERGENCY_ACTION_EXIT_FORCE] = "exit-force",
|
|
|
be0c12 |
};
|
|
|
be0c12 |
DEFINE_STRING_TABLE_LOOKUP(emergency_action, EmergencyAction);
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+int parse_emergency_action(
|
|
|
be0c12 |
+ const char *value,
|
|
|
be0c12 |
+ bool system,
|
|
|
be0c12 |
+ EmergencyAction *ret) {
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ EmergencyAction x;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ x = emergency_action_from_string(value);
|
|
|
be0c12 |
+ if (x < 0)
|
|
|
be0c12 |
+ return -EINVAL;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ if ((system && x >= _EMERGENCY_ACTION_FIRST_USER_ACTION) ||
|
|
|
be0c12 |
+ (!system && x != EMERGENCY_ACTION_NONE && x < _EMERGENCY_ACTION_FIRST_USER_ACTION))
|
|
|
be0c12 |
+ return -EOPNOTSUPP;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ *ret = x;
|
|
|
be0c12 |
+ return 0;
|
|
|
be0c12 |
+}
|
|
|
be0c12 |
diff --git a/src/core/emergency-action.h b/src/core/emergency-action.h
|
|
|
be0c12 |
index 61791f176f..646ccc4e6b 100644
|
|
|
be0c12 |
--- a/src/core/emergency-action.h
|
|
|
be0c12 |
+++ b/src/core/emergency-action.h
|
|
|
be0c12 |
@@ -13,6 +13,9 @@ typedef enum EmergencyAction {
|
|
|
be0c12 |
EMERGENCY_ACTION_POWEROFF,
|
|
|
be0c12 |
EMERGENCY_ACTION_POWEROFF_FORCE,
|
|
|
be0c12 |
EMERGENCY_ACTION_POWEROFF_IMMEDIATE,
|
|
|
be0c12 |
+ EMERGENCY_ACTION_EXIT,
|
|
|
be0c12 |
+ _EMERGENCY_ACTION_FIRST_USER_ACTION = EMERGENCY_ACTION_EXIT,
|
|
|
be0c12 |
+ EMERGENCY_ACTION_EXIT_FORCE,
|
|
|
be0c12 |
_EMERGENCY_ACTION_MAX,
|
|
|
be0c12 |
_EMERGENCY_ACTION_INVALID = -1
|
|
|
be0c12 |
} EmergencyAction;
|
|
|
be0c12 |
@@ -24,3 +27,5 @@ int emergency_action(Manager *m, EmergencyAction action, const char *reboot_arg,
|
|
|
be0c12 |
|
|
|
be0c12 |
const char* emergency_action_to_string(EmergencyAction i) _const_;
|
|
|
be0c12 |
EmergencyAction emergency_action_from_string(const char *s) _pure_;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+int parse_emergency_action(const char *value, bool system, EmergencyAction *ret);
|
|
|
be0c12 |
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
|
|
|
be0c12 |
index e0d7b8f7f8..c102ffb9f0 100644
|
|
|
be0c12 |
--- a/src/core/load-fragment.c
|
|
|
be0c12 |
+++ b/src/core/load-fragment.c
|
|
|
be0c12 |
@@ -77,7 +77,6 @@ DEFINE_CONFIG_PARSE(config_parse_socket_protocol, supported_socket_protocol_from
|
|
|
be0c12 |
DEFINE_CONFIG_PARSE(config_parse_exec_secure_bits, secure_bits_from_string, "Failed to parse secure bits");
|
|
|
be0c12 |
DEFINE_CONFIG_PARSE_ENUM(config_parse_collect_mode, collect_mode, CollectMode, "Failed to parse garbage collection mode");
|
|
|
be0c12 |
DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy, "Failed to parse device policy");
|
|
|
be0c12 |
-DEFINE_CONFIG_PARSE_ENUM(config_parse_emergency_action, emergency_action, EmergencyAction, "Failed to parse failure action specifier");
|
|
|
be0c12 |
DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode, "Failed to parse keyring mode");
|
|
|
be0c12 |
DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode");
|
|
|
be0c12 |
DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to parse job mode");
|
|
|
be0c12 |
@@ -4253,6 +4252,47 @@ int config_parse_job_running_timeout_sec(
|
|
|
be0c12 |
return 0;
|
|
|
be0c12 |
}
|
|
|
be0c12 |
|
|
|
be0c12 |
+int config_parse_emergency_action(
|
|
|
be0c12 |
+ const char* unit,
|
|
|
be0c12 |
+ const char *filename,
|
|
|
be0c12 |
+ unsigned line,
|
|
|
be0c12 |
+ const char *section,
|
|
|
be0c12 |
+ unsigned section_line,
|
|
|
be0c12 |
+ const char *lvalue,
|
|
|
be0c12 |
+ int ltype,
|
|
|
be0c12 |
+ const char *rvalue,
|
|
|
be0c12 |
+ void *data,
|
|
|
be0c12 |
+ void *userdata) {
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ Manager *m = NULL;
|
|
|
be0c12 |
+ EmergencyAction *x = data;
|
|
|
be0c12 |
+ int r;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ assert(filename);
|
|
|
be0c12 |
+ assert(lvalue);
|
|
|
be0c12 |
+ assert(rvalue);
|
|
|
be0c12 |
+ assert(data);
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ if (unit)
|
|
|
be0c12 |
+ m = ((Unit*) userdata)->manager;
|
|
|
be0c12 |
+ else
|
|
|
be0c12 |
+ m = data;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ r = parse_emergency_action(rvalue, MANAGER_IS_SYSTEM(m), x);
|
|
|
be0c12 |
+ if (r < 0) {
|
|
|
be0c12 |
+ if (r == -EOPNOTSUPP)
|
|
|
be0c12 |
+ log_syntax(unit, LOG_ERR, filename, line, r,
|
|
|
be0c12 |
+ "%s= specified as %s mode action, ignoring: %s",
|
|
|
be0c12 |
+ lvalue, MANAGER_IS_SYSTEM(m) ? "user" : "system", rvalue);
|
|
|
be0c12 |
+ else
|
|
|
be0c12 |
+ log_syntax(unit, LOG_ERR, filename, line, r,
|
|
|
be0c12 |
+ "Failed to parse %s=, ignoring: %s", lvalue, rvalue);
|
|
|
be0c12 |
+ return 0;
|
|
|
be0c12 |
+ }
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ return 0;
|
|
|
be0c12 |
+}
|
|
|
be0c12 |
+
|
|
|
be0c12 |
#define FOLLOW_MAX 8
|
|
|
be0c12 |
|
|
|
be0c12 |
static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
|
|
|
be0c12 |
diff --git a/src/test/meson.build b/src/test/meson.build
|
|
|
be0c12 |
index 7b310d4ec7..40cf56d73d 100644
|
|
|
be0c12 |
--- a/src/test/meson.build
|
|
|
be0c12 |
+++ b/src/test/meson.build
|
|
|
be0c12 |
@@ -65,6 +65,11 @@ tests += [
|
|
|
be0c12 |
libshared],
|
|
|
be0c12 |
[]],
|
|
|
be0c12 |
|
|
|
be0c12 |
+ [['src/test/test-emergency-action.c'],
|
|
|
be0c12 |
+ [libcore,
|
|
|
be0c12 |
+ libshared],
|
|
|
be0c12 |
+ []],
|
|
|
be0c12 |
+
|
|
|
be0c12 |
[['src/test/test-job-type.c'],
|
|
|
be0c12 |
[libcore,
|
|
|
be0c12 |
libshared],
|
|
|
be0c12 |
diff --git a/src/test/test-emergency-action.c b/src/test/test-emergency-action.c
|
|
|
be0c12 |
new file mode 100644
|
|
|
be0c12 |
index 0000000000..493b23227e
|
|
|
be0c12 |
--- /dev/null
|
|
|
be0c12 |
+++ b/src/test/test-emergency-action.c
|
|
|
be0c12 |
@@ -0,0 +1,51 @@
|
|
|
be0c12 |
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+#include "emergency-action.h"
|
|
|
be0c12 |
+#include "tests.h"
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+static void test_parse_emergency_action(void) {
|
|
|
be0c12 |
+ EmergencyAction x;
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ log_info("/* %s */", __func__);
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("none", false, &x) == 0);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_NONE);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("reboot", false, &x) == -EOPNOTSUPP);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("reboot-force", false, &x) == -EOPNOTSUPP);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("reboot-immediate", false, &x) == -EOPNOTSUPP);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("poweroff", false, &x) == -EOPNOTSUPP);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("poweroff-force", false, &x) == -EOPNOTSUPP);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("poweroff-immediate", false, &x) == -EOPNOTSUPP);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_NONE);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("exit", false, &x) == 0);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_EXIT);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("exit-force", false, &x) == 0);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_EXIT_FORCE);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("exit-forcee", false, &x) == -EINVAL);
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("none", true, &x) == 0);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_NONE);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("reboot", true, &x) == 0);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_REBOOT);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("reboot-force", true, &x) == 0);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_REBOOT_FORCE);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("reboot-immediate", true, &x) == 0);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_REBOOT_IMMEDIATE);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("poweroff", true, &x) == 0);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_POWEROFF);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("poweroff-force", true, &x) == 0);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_POWEROFF_FORCE);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("poweroff-immediate", true, &x) == 0);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("exit", true, &x) == -EOPNOTSUPP);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("exit-force", true, &x) == -EOPNOTSUPP);
|
|
|
be0c12 |
+ assert_se(parse_emergency_action("exit-forcee", true, &x) == -EINVAL);
|
|
|
be0c12 |
+ assert_se(x == EMERGENCY_ACTION_POWEROFF_IMMEDIATE);
|
|
|
be0c12 |
+}
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+int main(int argc, char **argv) {
|
|
|
be0c12 |
+ test_setup_logging(LOG_INFO);
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ test_parse_emergency_action();
|
|
|
be0c12 |
+
|
|
|
be0c12 |
+ return EXIT_SUCCESS;
|
|
|
be0c12 |
+}
|