]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
units: allow and use SuccessAction=exit-force in system systemd-exit.service
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 16 Oct 2018 14:34:45 +0000 (16:34 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 17 Oct 2018 17:32:07 +0000 (19:32 +0200)
C.f. 287419c119ef961db487a281162ab037eba70c61: 'systemctl exit 42' can be
used to set an exit value and pulls in exit.target, which pulls in systemd-exit.service,
which calls org.fdo.Manager.Exit, which calls method_exit(), which sets the objective
to MANAGER_EXIT. Allow the same to happen through SuccessAction=exit.

v2: update for 'exit' and 'exit-force'

man/systemd.unit.xml
src/core/emergency-action.c
src/test/test-emergency-action.c
units/meson.build
units/systemd-exit.service [moved from units/systemd-exit.service.in with 88% similarity]

index 9f65394b06d4e805e330442a6780b63da4197d19..467b905f14e8ceb11966151de408208957258c8d 100644 (file)
         Takes one of <option>none</option>, <option>reboot</option>, <option>reboot-force</option>,
         <option>reboot-immediate</option>, <option>poweroff</option>, <option>poweroff-force</option>,
         <option>poweroff-immediate</option>, <option>exit</option>, and <option>exit-force</option>. In system mode,
-        all options except <option>exit</option> and <option>exit-force</option> are allowed. In user mode, only
-        <option>none</option>, <option>exit</option>, and <option>exit-force</option> are allowed. Both options default
-        to <option>none</option>.</para>
+        all options are allowed. In user mode, only <option>none</option>, <option>exit</option>, and
+        <option>exit-force</option> are allowed. Both options default to <option>none</option>.</para>
 
         <para>If <option>none</option> is set, no action will be triggered. <option>reboot</option> causes a reboot
         following the normal shutdown procedure (i.e. equivalent to <command>systemctl reboot</command>).
         <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call, which
         might result in data loss. Similarly, <option>poweroff</option>, <option>poweroff-force</option>,
         <option>poweroff-immediate</option> have the effect of powering down the system with similar
-        semantics. <option>exit</option> causes the user manager to exit following the normal shutdown procedure, and
+        semantics. <option>exit</option> causes the manager to exit following the normal shutdown procedure, and
         <option>exit-force</option> causes it terminate without shutting down services.</para></listitem>
       </varlistentry>
 
index 3f0c11a3f27c2086626113f9fcc8a5f5a9101b96..e12ff81601c49b059cc2fafcbcd5a385f4e0e491 100644 (file)
@@ -10,6 +10,7 @@
 #include "special.h"
 #include "string-table.h"
 #include "terminal-util.h"
+#include "virt.h"
 
 static void log_and_status(Manager *m, const char *message, const char *reason) {
         log_warning("%s: %s", message, reason);
@@ -71,12 +72,14 @@ int emergency_action(
                 break;
 
         case EMERGENCY_ACTION_EXIT:
-                assert(MANAGER_IS_USER(m));
-
-                log_and_status(m, "Exiting", reason);
+                if (MANAGER_IS_USER(m) || detect_container() > 0) {
+                        log_and_status(m, "Exiting", reason);
+                        (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL);
+                        break;
+                }
 
-                (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL);
-                break;
+                log_notice("Doing \"poweroff\" action instead of an \"exit\" emergency action.");
+                _fallthrough_;
 
         case EMERGENCY_ACTION_POWEROFF:
                 log_and_status(m, "Powering off", reason);
@@ -84,11 +87,14 @@ int emergency_action(
                 break;
 
         case EMERGENCY_ACTION_EXIT_FORCE:
-                assert(MANAGER_IS_USER(m));
+                if (MANAGER_IS_USER(m) || detect_container() > 0) {
+                        log_and_status(m, "Exiting immediately", reason);
+                        m->objective = MANAGER_EXIT;
+                        break;
+                }
 
-                log_and_status(m, "Exiting immediately", reason);
-                m->objective = MANAGER_EXIT;
-                break;
+                log_notice("Doing \"poweroff-force\" action instead of an \"exit-force\" emergency action.");
+                _fallthrough_;
 
         case EMERGENCY_ACTION_POWEROFF_FORCE:
                 log_and_status(m, "Forcibly powering off", reason);
@@ -135,8 +141,7 @@ int parse_emergency_action(
         if (x < 0)
                 return -EINVAL;
 
-        if ((system && x >= _EMERGENCY_ACTION_FIRST_USER_ACTION) ||
-            (!system && x != EMERGENCY_ACTION_NONE && x < _EMERGENCY_ACTION_FIRST_USER_ACTION))
+        if (!system && x != EMERGENCY_ACTION_NONE && x < _EMERGENCY_ACTION_FIRST_USER_ACTION)
                 return -EOPNOTSUPP;
 
         *ret = x;
index 493b23227e7572c825f800e818cdbe6f91aac664..8ce28ed9f53a46be8fa6223968dcbe40a0c6d247 100644 (file)
@@ -36,10 +36,10 @@ static void test_parse_emergency_action(void) {
         assert_se(parse_emergency_action("poweroff-force", true, &x) == 0);
         assert_se(x == EMERGENCY_ACTION_POWEROFF_FORCE);
         assert_se(parse_emergency_action("poweroff-immediate", true, &x) == 0);
-        assert_se(parse_emergency_action("exit", true, &x) == -EOPNOTSUPP);
-        assert_se(parse_emergency_action("exit-force", true, &x) == -EOPNOTSUPP);
+        assert_se(parse_emergency_action("exit", true, &x) == 0);
+        assert_se(parse_emergency_action("exit-force", true, &x) == 0);
         assert_se(parse_emergency_action("exit-forcee", true, &x) == -EINVAL);
-        assert_se(x == EMERGENCY_ACTION_POWEROFF_IMMEDIATE);
+        assert_se(x == EMERGENCY_ACTION_EXIT_FORCE);
 }
 
 int main(int argc, char **argv) {
index 9d372c78a843eb892489336ae6e71683c63f4429..3cc86b3e92e6f494fbf382b2364d40bff31e07c8 100644 (file)
@@ -85,6 +85,7 @@ units = [
          'multi-user.target.wants/'],
         ['systemd-coredump.socket',             'ENABLE_COREDUMP',
          'sockets.target.wants/'],
+        ['systemd-exit.service',                 ''],
         ['systemd-initctl.socket',              '',
          'sockets.target.wants/'],
         ['systemd-journal-gatewayd.socket',     'ENABLE_REMOTE HAVE_MICROHTTPD'],
@@ -135,7 +136,6 @@ in_units = [
         ['systemd-binfmt.service',               'ENABLE_BINFMT',
          'sysinit.target.wants/'],
         ['systemd-coredump@.service',            'ENABLE_COREDUMP'],
-        ['systemd-exit.service',                 ''],
         ['systemd-firstboot.service',            'ENABLE_FIRSTBOOT',
          'sysinit.target.wants/'],
         ['systemd-fsck-root.service',            ''],
similarity index 88%
rename from units/systemd-exit.service.in
rename to units/systemd-exit.service
index 2fb6ebd76792478454999f3b3b3bacb7fab30910..6029b13a0526e569ceb19966276a4021fac8a005 100644 (file)
@@ -13,7 +13,4 @@ Documentation=man:systemd.special(7)
 DefaultDependencies=no
 Requires=shutdown.target
 After=shutdown.target
-
-[Service]
-Type=oneshot
-ExecStart=@SYSTEMCTL@ --force exit
+SuccessAction=exit