]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: add support for Sleep() logind call 29853/head
authorMike Yuan <me@yhndnzj.com>
Fri, 3 Nov 2023 13:25:42 +0000 (21:25 +0800)
committerMike Yuan <me@yhndnzj.com>
Tue, 5 Dec 2023 14:18:32 +0000 (22:18 +0800)
man/systemctl.xml
src/systemctl/systemctl-logind.c
src/systemctl/systemctl-start-special.c
src/systemctl/systemctl-start-unit.c
src/systemctl/systemctl.c
src/systemctl/systemctl.h

index 1d791b44fd32d8bb1d4cc2e8f0a784beec7fc70f..6029434ae6b7e56b2ae32d2643852c6abc1473fe 100644 (file)
@@ -1755,6 +1755,24 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><command>sleep</command></term>
+
+          <listitem>
+            <para>Put the system to sleep, through <command>suspend</command>, <command>hibernate</command>,
+            <command>hybrid-sleep</command>, or <command>suspend-then-hibernate</command>. The sleep operation
+            to use is automatically selected by <citerefentry>
+            <refentrytitle>systemd-logind.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+            By default, <command>suspend-then-hibernate</command> is used, and falls back to <command>suspend</command>
+            and then <command>hibernate</command> if not supported. Refer to <varname>SleepOperation=</varname>
+            setting in <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+            for more details. This command is asynchronous, and will return after the sleep operation is
+            successfully enqueued. It will not wait for the sleep/resume cycle to complete.</para>
+
+            <xi:include href="version-info.xml" xpointer="v256"/>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><command>suspend</command></term>
 
index 268e528856a382d4fb541c8083c33cc20cb08a13..2e35413b5fd2ccacbb6f3affa196a1700bcf2f27 100644 (file)
@@ -51,6 +51,7 @@ int logind_reboot(enum action a) {
                 [ACTION_HIBERNATE]              = "Hibernate",
                 [ACTION_HYBRID_SLEEP]           = "HybridSleep",
                 [ACTION_SUSPEND_THEN_HIBERNATE] = "SuspendThenHibernate",
+                [ACTION_SLEEP]                  = "Sleep",
         };
 
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -71,7 +72,7 @@ int logind_reboot(enum action a) {
         polkit_agent_open_maybe();
         (void) logind_set_wall_message(bus);
 
-        const char *method_with_flags = strjoina(actions[a], "WithFlags");
+        const char *method_with_flags = a == ACTION_SLEEP ? actions[a] : strjoina(actions[a], "WithFlags");
 
         log_debug("%s org.freedesktop.login1.Manager %s dbus call.",
                   arg_dry_run ? "Would execute" : "Executing", method_with_flags);
@@ -103,7 +104,7 @@ int logind_reboot(enum action a) {
         }
         if (r >= 0)
                 return 0;
-        if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD))
+        if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD) || a == ACTION_SLEEP)
                 return log_error_errno(r, "Call to %s failed: %s", actions[a], bus_error_message(&error, r));
 
         /* Fall back to original methods in case there is an older version of systemd-logind */
index d93bffb75914d65633c699d2d81b6918d9ac21db..2cf746c5a6057d7b5e424b9fa67e3013c1b0f453 100644 (file)
@@ -229,6 +229,9 @@ int verb_start_special(int argc, char *argv[], void *userdata) {
                         arg_no_block = true;
                         break;
 
+                case ACTION_SLEEP:
+                        return logind_reboot(a);
+
                 case ACTION_EXIT:
                         /* Since exit is so close in behaviour to power-off/reboot, let's also make
                          * it asynchronous, in order to not confuse the user needlessly with unexpected
index 6927e9774792870c63b7ab16321b8780ccdc692e..ae7e25eedb626003d11b5780b9a3770887d37d65 100644 (file)
@@ -236,6 +236,7 @@ const struct action_metadata action_table[_ACTION_MAX] = {
         [ACTION_HIBERNATE]              = { SPECIAL_HIBERNATE_TARGET,              "hibernate",              "replace-irreversibly" },
         [ACTION_HYBRID_SLEEP]           = { SPECIAL_HYBRID_SLEEP_TARGET,           "hybrid-sleep",           "replace-irreversibly" },
         [ACTION_SUSPEND_THEN_HIBERNATE] = { SPECIAL_SUSPEND_THEN_HIBERNATE_TARGET, "suspend-then-hibernate", "replace-irreversibly" },
+        [ACTION_SLEEP]                  = { NULL, /* handled only by logind */     "sleep",                  NULL                   },
 };
 
 enum action verb_to_action(const char *verb) {
@@ -294,6 +295,8 @@ int verb_start(int argc, char *argv[], void *userdata) {
 
                 action = verb_to_action(argv[0]);
 
+                assert(action != ACTION_SLEEP);
+
                 if (action != _ACTION_INVALID) {
                         /* A command in style "systemctl reboot", "systemctl poweroff", … */
                         method = "StartUnit";
index dd6f6c9873e25e611ab703928c7ea7c79fb48c96..0fa672eb905314cac10229f772481e789f921ac5 100644 (file)
@@ -249,6 +249,8 @@ static int systemctl_help(void) {
                "  soft-reboot                         Shut down and reboot userspace\n"
                "  exit [EXIT_CODE]                    Request user instance or container exit\n"
                "  switch-root [ROOT [INIT]]           Change to a different root file system\n"
+               "  sleep                               Put the system to sleep (through one of\n"
+               "                                      the operations below)\n"
                "  suspend                             Suspend the system\n"
                "  hibernate                           Hibernate the system\n"
                "  hybrid-sleep                        Hibernate and suspend the system\n"
@@ -1179,6 +1181,7 @@ static int systemctl_main(int argc, char *argv[]) {
                 { "reboot",                VERB_ANY, 1,        VERB_ONLINE_ONLY, verb_start_system_special    },
                 { "kexec",                 VERB_ANY, 1,        VERB_ONLINE_ONLY, verb_start_system_special    },
                 { "soft-reboot",           VERB_ANY, 1,        VERB_ONLINE_ONLY, verb_start_system_special    },
+                { "sleep",                 VERB_ANY, 1,        VERB_ONLINE_ONLY, verb_start_system_special    },
                 { "suspend",               VERB_ANY, 1,        VERB_ONLINE_ONLY, verb_start_system_special    },
                 { "hibernate",             VERB_ANY, 1,        VERB_ONLINE_ONLY, verb_start_system_special    },
                 { "hybrid-sleep",          VERB_ANY, 1,        VERB_ONLINE_ONLY, verb_start_system_special    },
@@ -1323,6 +1326,7 @@ static int run(int argc, char *argv[]) {
                 break;
 
         case ACTION_EXIT:
+        case ACTION_SLEEP:
         case ACTION_SUSPEND:
         case ACTION_HIBERNATE:
         case ACTION_HYBRID_SLEEP:
index e8ba8f76a07e9b8bc8edeaf0bf464d187c496504..a42fc36a2e481297cee9bd40902a2e7c188f5caa 100644 (file)
@@ -18,6 +18,7 @@ enum action {
         ACTION_KEXEC,
         ACTION_SOFT_REBOOT,
         ACTION_EXIT,
+        ACTION_SLEEP,
         ACTION_SUSPEND,
         ACTION_HIBERNATE,
         ACTION_HYBRID_SLEEP,