chiark / gitweb /
systemd-sleep: add support for freeze and standby
[elogind.git] / src / login / logind-dbus.c
index 4ae8362211122b094ac3056c9c2bf789cf8f9d26..4a84b860f10479fb053e3bdd6b0ac71350bea17c 100644 (file)
@@ -31,6 +31,7 @@
 #include "path-util.h"
 #include "polkit.h"
 #include "special.h"
+#include "sleep-config.h"
 #include "systemd/sd-id128.h"
 #include "systemd/sd-messages.h"
 #include "fileio-label.h"
@@ -66,7 +67,7 @@
         "  <method name=\"CreateSession\">\n"                           \
         "   <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n"          \
         "   <arg name=\"leader\" type=\"u\" direction=\"in\"/>\n"       \
-        "   <arg name=\"sevice\" type=\"s\" direction=\"in\"/>\n"       \
+        "   <arg name=\"service\" type=\"s\" direction=\"in\"/>\n"      \
         "   <arg name=\"type\" type=\"s\" direction=\"in\"/>\n"         \
         "   <arg name=\"class\" type=\"s\" direction=\"in\"/>\n"        \
         "   <arg name=\"seat\" type=\"s\" direction=\"in\"/>\n"         \
@@ -353,21 +354,28 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
                 return -EINVAL;
 
         dbus_message_iter_get_basic(&iter, &type);
-        t = session_type_from_string(type);
+        if (isempty(type))
+                t = _SESSION_TYPE_INVALID;
+        else {
+                t = session_type_from_string(type);
+                if (t < 0)
+                        return -EINVAL;
+        }
 
-        if (t < 0 ||
-            !dbus_message_iter_next(&iter) ||
+        if (!dbus_message_iter_next(&iter) ||
             dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
                 return -EINVAL;
 
         dbus_message_iter_get_basic(&iter, &class);
         if (isempty(class))
-                c = SESSION_USER;
-        else
+                c = _SESSION_CLASS_INVALID;
+        else {
                 c = session_class_from_string(class);
+                if (c < 0)
+                        return -EINVAL;
+        }
 
-        if (c < 0 ||
-            !dbus_message_iter_next(&iter) ||
+        if (!dbus_message_iter_next(&iter) ||
             dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
                 return -EINVAL;
 
@@ -441,6 +449,22 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
             dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
                 return -EINVAL;
 
+        if (t == _SESSION_TYPE_INVALID) {
+                if (!isempty(display))
+                        t = SESSION_X11;
+                else if (!isempty(tty))
+                        t = SESSION_TTY;
+                else
+                        t = SESSION_UNSPECIFIED;
+        }
+
+        if (c == _SESSION_CLASS_INVALID) {
+                if (!isempty(display) || !isempty(tty))
+                        c = SESSION_USER;
+                else
+                        c = SESSION_BACKGROUND;
+        }
+
         dbus_message_iter_get_basic(&iter, &remote);
 
         if (!dbus_message_iter_next(&iter) ||
@@ -464,8 +488,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
         if (r < 0)
                 return -EINVAL;
 
-        if (strv_contains(controllers, "systemd") ||
-            !dbus_message_iter_next(&iter) ||
+        if (!dbus_message_iter_next(&iter) ||
             dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
             dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) {
                 r = -EINVAL;
@@ -476,8 +499,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
         if (r < 0)
                 goto fail;
 
-        if (strv_contains(reset_controllers, "systemd") ||
-            !dbus_message_iter_next(&iter) ||
+        if (!dbus_message_iter_next(&iter) ||
             dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) {
                 r = -EINVAL;
                 goto fail;
@@ -485,7 +507,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
 
         dbus_message_iter_get_basic(&iter, &kill_processes);
 
-        r = cg_pid_get_cgroup(leader, NULL, &cgroup);
+        r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, leader, &cgroup);
         if (r < 0)
                 goto fail;
 
@@ -588,11 +610,11 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
         session->type = t;
         session->class = c;
         session->remote = remote;
-        session->controllers = controllers;
-        session->reset_controllers = reset_controllers;
         session->kill_processes = kill_processes;
         session->vtnr = vtnr;
 
+        session->controllers = cg_shorten_controllers(controllers);
+        session->reset_controllers = cg_shorten_controllers(reset_controllers);
         controllers = reset_controllers = NULL;
 
         if (!isempty(tty)) {
@@ -886,7 +908,7 @@ static int trigger_device(Manager *m, struct udev_device *d) {
                         goto finish;
                 }
 
-                write_one_line_file(t, "change");
+                write_string_file(t, "change");
                 free(t);
         }
 
@@ -901,7 +923,7 @@ finish:
 
 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
         struct udev_device *d;
-        char _cleanup_free_ *rule = NULL, *file = NULL;
+        _cleanup_free_ char *rule = NULL, *file = NULL;
         const char *id_for_seat;
         int r;
 
@@ -936,7 +958,7 @@ static int attach_device(Manager *m, const char *seat, const char *sysfs) {
 
         mkdir_p_label("/etc/udev/rules.d", 0755);
         label_init("/etc");
-        r = write_one_line_file_atomic_label(file, rule);
+        r = write_string_file_atomic_label(file, rule);
         if (r < 0)
                 goto finish;
 
@@ -950,7 +972,7 @@ finish:
 }
 
 static int flush_devices(Manager *m) {
-        DIR _cleanup_closedir_ *d;
+        _cleanup_closedir_ DIR *d;
 
         assert(m);
 
@@ -993,7 +1015,6 @@ static int have_multiple_sessions(
          * count, and non-login sessions do not count either. */
         HASHMAP_FOREACH(session, m->sessions, i)
                 if (session->class == SESSION_USER &&
-                    (session->type == SESSION_TTY || session->type == SESSION_X11) &&
                     session->user->uid != uid)
                         return true;
 
@@ -1111,13 +1132,12 @@ static int bus_manager_can_shutdown_or_sleep(
                 const char *action,
                 const char *action_multiple_sessions,
                 const char *action_ignore_inhibit,
-                const char *sleep_type,
-                const char *sleep_disk_type,
+                const char *sleep_verb,
                 DBusError *error,
                 DBusMessage **_reply) {
 
         bool multiple_sessions, challenge, blocked, b;
-        const char *result;
+        const char *result = NULL;
         _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
         int r;
         unsigned long ul;
@@ -1133,22 +1153,10 @@ static int bus_manager_can_shutdown_or_sleep(
         assert(error);
         assert(_reply);
 
-        if (sleep_type) {
-                r = can_sleep(sleep_type);
+        if (sleep_verb) {
+                r = can_sleep(sleep_verb);
                 if (r < 0)
                         return r;
-
-                if (r == 0) {
-                        result = "na";
-                        goto finish;
-                }
-        }
-
-        if (sleep_disk_type) {
-                r = can_sleep_disk(sleep_disk_type);
-                if (r < 0)
-                        return r;
-
                 if (r == 0) {
                         result = "na";
                         goto finish;
@@ -1293,8 +1301,7 @@ static int bus_manager_do_shutdown_or_sleep(
                 const char *action,
                 const char *action_multiple_sessions,
                 const char *action_ignore_inhibit,
-                const char *sleep_type,
-                const char *sleep_disk_type,
+                const char *sleep_verb,
                 DBusError *error,
                 DBusMessage **_reply) {
 
@@ -1327,17 +1334,8 @@ static int bus_manager_do_shutdown_or_sleep(
                             DBUS_TYPE_INVALID))
                 return -EINVAL;
 
-        if (sleep_type) {
-                r = can_sleep(sleep_type);
-                if (r < 0)
-                        return r;
-
-                if (r == 0)
-                        return -ENOTSUP;
-        }
-
-        if (sleep_disk_type) {
-                r = can_sleep_disk(sleep_disk_type);
+        if (sleep_verb) {
+                r = can_sleep(sleep_verb);
                 if (r < 0)
                         return r;
 
@@ -2140,7 +2138,7 @@ static DBusHandlerResult manager_message_handler(
                                 "org.freedesktop.login1.power-off",
                                 "org.freedesktop.login1.power-off-multiple-sessions",
                                 "org.freedesktop.login1.power-off-ignore-inhibit",
-                                NULL, NULL,
+                                NULL,
                                 &error, &reply);
                 if (r < 0)
                         return bus_send_error_reply(connection, message, &error, r);
@@ -2152,7 +2150,7 @@ static DBusHandlerResult manager_message_handler(
                                 "org.freedesktop.login1.reboot",
                                 "org.freedesktop.login1.reboot-multiple-sessions",
                                 "org.freedesktop.login1.reboot-ignore-inhibit",
-                                NULL, NULL,
+                                NULL,
                                 &error, &reply);
                 if (r < 0)
                         return bus_send_error_reply(connection, message, &error, r);
@@ -2165,7 +2163,7 @@ static DBusHandlerResult manager_message_handler(
                                 "org.freedesktop.login1.suspend",
                                 "org.freedesktop.login1.suspend-multiple-sessions",
                                 "org.freedesktop.login1.suspend-ignore-inhibit",
-                                "mem", NULL,
+                                "suspend",
                                 &error, &reply);
                 if (r < 0)
                         return bus_send_error_reply(connection, message, &error, r);
@@ -2177,7 +2175,7 @@ static DBusHandlerResult manager_message_handler(
                                 "org.freedesktop.login1.hibernate",
                                 "org.freedesktop.login1.hibernate-multiple-sessions",
                                 "org.freedesktop.login1.hibernate-ignore-inhibit",
-                                "disk", NULL,
+                                "hibernate",
                                 &error, &reply);
                 if (r < 0)
                         return bus_send_error_reply(connection, message, &error, r);
@@ -2190,7 +2188,7 @@ static DBusHandlerResult manager_message_handler(
                                 "org.freedesktop.login1.hibernate",
                                 "org.freedesktop.login1.hibernate-multiple-sessions",
                                 "org.freedesktop.login1.hibernate-ignore-inhibit",
-                                "disk", "suspend",
+                                "hybrid-sleep",
                                 &error, &reply);
                 if (r < 0)
                         return bus_send_error_reply(connection, message, &error, r);
@@ -2203,7 +2201,7 @@ static DBusHandlerResult manager_message_handler(
                                 "org.freedesktop.login1.power-off",
                                 "org.freedesktop.login1.power-off-multiple-sessions",
                                 "org.freedesktop.login1.power-off-ignore-inhibit",
-                                NULL, NULL,
+                                NULL,
                                 &error, &reply);
                 if (r < 0)
                         return bus_send_error_reply(connection, message, &error, r);
@@ -2214,7 +2212,7 @@ static DBusHandlerResult manager_message_handler(
                                 "org.freedesktop.login1.reboot",
                                 "org.freedesktop.login1.reboot-multiple-sessions",
                                 "org.freedesktop.login1.reboot-ignore-inhibit",
-                                NULL, NULL,
+                                NULL,
                                 &error, &reply);
                 if (r < 0)
                         return bus_send_error_reply(connection, message, &error, r);
@@ -2226,7 +2224,7 @@ static DBusHandlerResult manager_message_handler(
                                 "org.freedesktop.login1.suspend",
                                 "org.freedesktop.login1.suspend-multiple-sessions",
                                 "org.freedesktop.login1.suspend-ignore-inhibit",
-                                "mem", NULL,
+                                "suspend",
                                 &error, &reply);
                 if (r < 0)
                         return bus_send_error_reply(connection, message, &error, r);
@@ -2238,7 +2236,7 @@ static DBusHandlerResult manager_message_handler(
                                 "org.freedesktop.login1.hibernate",
                                 "org.freedesktop.login1.hibernate-multiple-sessions",
                                 "org.freedesktop.login1.hibernate-ignore-inhibit",
-                                "disk", NULL,
+                                "hibernate",
                                 &error, &reply);
                 if (r < 0)
                         return bus_send_error_reply(connection, message, &error, r);
@@ -2250,7 +2248,7 @@ static DBusHandlerResult manager_message_handler(
                                 "org.freedesktop.login1.hibernate",
                                 "org.freedesktop.login1.hibernate-multiple-sessions",
                                 "org.freedesktop.login1.hibernate-ignore-inhibit",
-                                "disk", "suspend",
+                                "hybrid-sleep",
                                 &error, &reply);
                 if (r < 0)
                         return bus_send_error_reply(connection, message, &error, r);
@@ -2380,7 +2378,6 @@ DBusHandlerResult bus_message_filter(
                         log_error("Failed to parse JobRemoved message: %s", bus_error_message(&error));
 
                 else if (m->action_job && streq(m->action_job, path)) {
-
                         log_info("Operation finished.");
 
                         /* Tell people that they now may take a lock again */
@@ -2421,7 +2418,7 @@ int manager_dispatch_delayed(Manager *manager) {
 
         assert(manager);
 
-        if (!manager->action_unit || manager->action_job)
+        if (manager->action_what == 0 || manager->action_job)
                 return 0;
 
         /* Continue delay? */
@@ -2437,7 +2434,7 @@ int manager_dispatch_delayed(Manager *manager) {
         dbus_error_init(&error);
         r = execute_shutdown_or_sleep(manager, manager->action_what, manager->action_unit, &error);
         if (r < 0) {
-                log_warning("Failed to send delayed message: %s", bus_error_message_or_strerror(&error, -r));
+                log_warning("Failed to send delayed message: %s", bus_error(&error, r));
                 dbus_error_free(&error);
 
                 manager->action_unit = NULL;