mirror of
https://gitlab.freedesktop.org/upower/upower.git
synced 2026-05-09 03:38:05 +02:00
Use systemd for suspend and hibernate
When running under systemd, call into systemd for suspend and hibernate instead of pm-utils. To capture resume events, install a small script that gets executed by systemd after resume and sends a dbus signal back to upower. To make this work, the upower backends gain a new signal, ::resuming, that they can optionally emit to signal that a resume happened. Backends opt in to this by returning TRUE from up_backend_emits_resuming(). In this case, upower doesn't assume the sleep command to block until resume, but instead waits for the ::resuming signal from the backend. The only backend that uses this mechanism is the linux backend when built with systemd support. Signed-off-by: Richard Hughes <richard@hughsie.com>
This commit is contained in:
parent
7bad068a2d
commit
44189f8129
10 changed files with 194 additions and 32 deletions
57
configure.ac
57
configure.ac
|
|
@ -176,6 +176,55 @@ fi
|
|||
|
||||
PKG_CHECK_MODULES(GIO, [gio-2.0 >= 2.16.1])
|
||||
|
||||
dnl ====================================================================
|
||||
dnl Check for systemd
|
||||
dnl ====================================================================
|
||||
AC_ARG_ENABLE([systemd],
|
||||
AS_HELP_STRING([--enable-systemd], [Use systemd]),
|
||||
[enable_systemd=$enableval],
|
||||
[enable_systemd=auto])
|
||||
|
||||
PKG_CHECK_MODULES(SYSTEMD,
|
||||
[libsystemd-daemon],
|
||||
[have_systemd=yes], [have_systemd=no])
|
||||
|
||||
AC_MSG_CHECKING([whether to use systemd])
|
||||
|
||||
if test x$enable_systemd = xauto ; then
|
||||
if test x$have_systemd = xno ; then
|
||||
enable_systemd=no
|
||||
else
|
||||
enable_systemd=yes
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($enable_systemd)
|
||||
|
||||
if test x$enable_systemd = xyes; then
|
||||
if test x$have_systemd = xno; then
|
||||
AC_MSG_ERROR([Systemd support explicitly required, but systemd not found])
|
||||
fi
|
||||
AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is used for session tracking])
|
||||
fi
|
||||
|
||||
AC_SUBST(SYSTEMD_CFLAGS)
|
||||
AC_SUBST(SYSTEMD_LIBS)
|
||||
|
||||
AM_CONDITIONAL(HAVE_SYSTEMD, [test "$with_systemd" = "yes"], [Using systemd])
|
||||
|
||||
AC_ARG_WITH([systemdutildir],
|
||||
AS_HELP_STRING([--with-systemdutildir=DIR], [Directory for systemd utilities]),
|
||||
[],
|
||||
[with_systemdutildir=$($PKG_CONFIG --variable=systemdutildir systemd)])
|
||||
AC_SUBST([systemdutildir], [$with_systemdutildir])
|
||||
AM_CONDITIONAL(HAVE_SYSTEMDUTILDIR, [test -n "$with_systemdutildir"])
|
||||
|
||||
AC_ARG_WITH([systemdsystemunitdir],
|
||||
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
|
||||
[],
|
||||
[with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
|
||||
AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
|
||||
AM_CONDITIONAL(HAVE_SYSTEMDSYSTEMUNITDIR, [test -n "$with_systemdsystemunitdir"])
|
||||
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl - Compile time default choice of backend
|
||||
dnl ---------------------------------------------------------------------------
|
||||
|
|
@ -210,14 +259,6 @@ fi
|
|||
|
||||
AM_CONDITIONAL(HAVE_IDEVICE, [test x$have_idevice = xyes])
|
||||
|
||||
# systemd
|
||||
AC_ARG_WITH([systemdsystemunitdir],
|
||||
AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
|
||||
[],
|
||||
[with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
|
||||
AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
|
||||
AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir"])
|
||||
|
||||
# export to Makefile.am
|
||||
AM_CONDITIONAL(BACKEND_TYPE_DUMMY, [test x$with_backend = xdummy])
|
||||
AM_CONDITIONAL(BACKEND_TYPE_LINUX, [test x$with_backend = xlinux])
|
||||
|
|
|
|||
|
|
@ -122,7 +122,13 @@ upowerd_LDADD += \
|
|||
linux/libupshared.la \
|
||||
$(USB_LIBS) \
|
||||
$(GUDEV_LIBS) \
|
||||
$(IDEVICE_LIBS)
|
||||
$(IDEVICE_LIBS) \
|
||||
$(SYSTEMD_LIBS)
|
||||
|
||||
if HAVE_SYSTEMDUTILDIR
|
||||
systemsleepdir = $(systemdutildir)/system-sleep
|
||||
systemsleep_SCRIPTS = notify-upower.sh
|
||||
endif
|
||||
|
||||
if UP_BUILD_TESTS
|
||||
DBUS_LAUNCH=$(shell which dbus-launch)
|
||||
|
|
@ -196,7 +202,7 @@ dbusconf_DATA = $(dbusconf_in_files:.conf.in=.conf)
|
|||
$(dbusconf_DATA): $(dbusconf_in_files) Makefile
|
||||
cp $< $@
|
||||
|
||||
if HAVE_SYSTEMD
|
||||
if HAVE_SYSTEMDSYSTEMUNITDIR
|
||||
systemdservicedir = $(systemdsystemunitdir)
|
||||
systemdservice_in_files = upower.service.in
|
||||
systemdservice_DATA = $(systemdservice_in_files:.service.in=.service)
|
||||
|
|
@ -223,6 +229,8 @@ EXTRA_DIST = \
|
|||
org.freedesktop.UPower.KbdBacklight.xml \
|
||||
org.freedesktop.UPower.Wakeups.xml \
|
||||
up-marshal.list \
|
||||
$(systemsleep_SCRIPTS) \
|
||||
$(systemdservice_in_files) \
|
||||
$(dbusservice_in_files) \
|
||||
$(dbusconf_in_files)
|
||||
|
||||
|
|
|
|||
|
|
@ -297,3 +297,9 @@ up_backend_get_powersave_command (UpBackend *backend, gboolean powersave)
|
|||
{
|
||||
return "/bin/true";
|
||||
}
|
||||
|
||||
gboolean
|
||||
up_backend_emits_resuming (UpBackend *backend)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -326,6 +326,12 @@ up_backend_get_hibernate_command (UpBackend *backend)
|
|||
return UP_BACKEND_HIBERNATE_COMMAND;
|
||||
}
|
||||
|
||||
gboolean
|
||||
up_backend_emits_resuming (UpBackend *backend)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* up_backend_kernel_can_suspend:
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ INCLUDES = \
|
|||
$(GUDEV_CFLAGS) \
|
||||
$(POLKIT_CFLAGS) \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(IDEVICE_CFLAGS)
|
||||
$(IDEVICE_CFLAGS) \
|
||||
$(SYSTEMD_CFLAGS)
|
||||
|
||||
if BACKEND_TYPE_LINUX
|
||||
noinst_LTLIBRARIES = libupshared.la
|
||||
|
|
|
|||
|
|
@ -45,6 +45,17 @@
|
|||
#include "up-device-idevice.h"
|
||||
#endif /* HAVE_IDEVICE */
|
||||
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
|
||||
#define SD_HIBERNATE_COMMAND "gdbus call --system --dest org.freedesktop.login1 --object-path /org/freedesktop/login1 --method org.freedesktop.login1.Manager.Hibernate 'true'"
|
||||
#define SD_SUSPEND_COMMAND "gdbus call --system --dest org.freedesktop.login1 --object-path /org/freedesktop/login1 --method org.freedesktop.login1.Manager.Suspend 'true'"
|
||||
|
||||
#endif
|
||||
|
||||
static void up_backend_class_init (UpBackendClass *klass);
|
||||
static void up_backend_init (UpBackend *backend);
|
||||
static void up_backend_finalize (GObject *object);
|
||||
|
|
@ -59,11 +70,13 @@ struct UpBackendPrivate
|
|||
UpDeviceList *managed_devices;
|
||||
UpDock *dock;
|
||||
UpConfig *config;
|
||||
DBusConnection *connection;
|
||||
};
|
||||
|
||||
enum {
|
||||
SIGNAL_DEVICE_ADDED,
|
||||
SIGNAL_DEVICE_REMOVED,
|
||||
SIGNAL_RESUMING,
|
||||
SIGNAL_LAST
|
||||
};
|
||||
|
||||
|
|
@ -564,6 +577,11 @@ out:
|
|||
const gchar *
|
||||
up_backend_get_suspend_command (UpBackend *backend)
|
||||
{
|
||||
#ifdef HAVE_SYSTEMD
|
||||
if (sd_booted ())
|
||||
return SD_SUSPEND_COMMAND;
|
||||
else
|
||||
#endif
|
||||
return UP_BACKEND_SUSPEND_COMMAND;
|
||||
}
|
||||
|
||||
|
|
@ -573,9 +591,24 @@ up_backend_get_suspend_command (UpBackend *backend)
|
|||
const gchar *
|
||||
up_backend_get_hibernate_command (UpBackend *backend)
|
||||
{
|
||||
#ifdef HAVE_SYSTEMD
|
||||
if (sd_booted ())
|
||||
return SD_HIBERNATE_COMMAND;
|
||||
else
|
||||
#endif
|
||||
return UP_BACKEND_HIBERNATE_COMMAND;
|
||||
}
|
||||
|
||||
gboolean
|
||||
up_backend_emits_resuming (UpBackend *backend)
|
||||
{
|
||||
#ifdef HAVE_SYSTEMD
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* up_backend_get_powersave_command:
|
||||
**/
|
||||
|
|
@ -609,10 +642,32 @@ up_backend_class_init (UpBackendClass *klass)
|
|||
G_STRUCT_OFFSET (UpBackendClass, device_removed),
|
||||
NULL, NULL, up_marshal_VOID__POINTER_POINTER,
|
||||
G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER);
|
||||
signals [SIGNAL_RESUMING] =
|
||||
g_signal_new ("resuming",
|
||||
G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (UpBackendClass, resuming),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (UpBackendPrivate));
|
||||
}
|
||||
|
||||
static DBusHandlerResult
|
||||
message_filter (DBusConnection *connection,
|
||||
DBusMessage *message,
|
||||
void *user_data)
|
||||
{
|
||||
UpBackend *backend = user_data;
|
||||
|
||||
if (dbus_message_is_signal (message, "org.freedesktop.UPower", "Resuming")) {
|
||||
g_debug ("received Resuming signal");
|
||||
g_signal_emit (backend, signals[SIGNAL_RESUMING], 0);
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* up_backend_init:
|
||||
**/
|
||||
|
|
@ -624,6 +679,15 @@ up_backend_init (UpBackend *backend)
|
|||
backend->priv->daemon = NULL;
|
||||
backend->priv->device_list = NULL;
|
||||
backend->priv->managed_devices = up_device_list_new ();
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
if (sd_booted ()) {
|
||||
DBusGConnection *bus;
|
||||
bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
|
||||
backend->priv->connection = dbus_g_connection_get_connection (bus);
|
||||
dbus_connection_add_filter (backend->priv->connection, message_filter, backend, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -648,6 +712,9 @@ up_backend_finalize (GObject *object)
|
|||
|
||||
g_object_unref (backend->priv->managed_devices);
|
||||
|
||||
if (backend->priv->connection)
|
||||
dbus_connection_remove_filter (backend->priv->connection, message_filter, backend);
|
||||
|
||||
G_OBJECT_CLASS (up_backend_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
|
|
|||
6
src/notify-upower.sh
Executable file
6
src/notify-upower.sh
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
[ "$1" = "post" ] && exec /usr/bin/dbus-send \
|
||||
--system --type=signal \
|
||||
--dest=org.freedesktop.UPower \
|
||||
/org/freedesktop/UPower \
|
||||
org.freedesktop.UPower.Resuming
|
||||
|
|
@ -205,6 +205,12 @@ up_backend_get_hibernate_command (UpBackend *backend)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
up_backend_emits_resuming (UpBackend *backend)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* up_backend_kernel_can_suspend:
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ typedef struct
|
|||
void (* device_removed) (UpBackend *backend,
|
||||
GObject *native,
|
||||
UpDevice *device);
|
||||
void (* resuming) (UpBackend *backend);
|
||||
} UpBackendClass;
|
||||
|
||||
GType up_backend_get_type (void);
|
||||
|
|
@ -75,6 +76,7 @@ const gchar *up_backend_get_suspend_command (UpBackend *backend);
|
|||
const gchar *up_backend_get_hibernate_command (UpBackend *backend);
|
||||
const gchar *up_backend_get_powersave_command (UpBackend *backend,
|
||||
gboolean powersave);
|
||||
gboolean up_backend_emits_resuming (UpBackend *backend);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -380,8 +380,40 @@ typedef struct {
|
|||
UpDaemon *daemon;
|
||||
DBusGMethodInvocation *context;
|
||||
gchar *command;
|
||||
gulong handler;
|
||||
} UpDaemonDeferredSleep;
|
||||
|
||||
static void
|
||||
emit_resuming (UpDaemonDeferredSleep *sleep)
|
||||
{
|
||||
UpDaemon *daemon = sleep->daemon;
|
||||
UpDaemonPrivate *priv = daemon->priv;
|
||||
|
||||
/* emit signal for session components */
|
||||
g_debug ("emitting resuming");
|
||||
g_signal_emit (daemon, signals[SIGNAL_RESUMING], 0);
|
||||
g_signal_emit (daemon, signals[SIGNAL_NOTIFY_RESUME], 0,
|
||||
priv->sleep_kind);
|
||||
|
||||
/* reset the about-to-sleep logic */
|
||||
g_timer_reset (priv->about_to_sleep_timer);
|
||||
g_timer_stop (priv->about_to_sleep_timer);
|
||||
|
||||
/* actually return from the DBus call now */
|
||||
dbus_g_method_return (sleep->context, NULL);
|
||||
|
||||
/* clear timer */
|
||||
priv->about_to_sleep_id = 0;
|
||||
priv->sent_sleeping_signal = FALSE;
|
||||
|
||||
/* delete temp object */
|
||||
if (sleep->handler)
|
||||
g_signal_handler_disconnect (priv->backend, sleep->handler);
|
||||
g_object_unref (sleep->daemon);
|
||||
g_free (sleep->command);
|
||||
g_free (sleep);
|
||||
}
|
||||
|
||||
/**
|
||||
* up_daemon_deferred_sleep_cb:
|
||||
**/
|
||||
|
|
@ -396,7 +428,13 @@ up_daemon_deferred_sleep_cb (UpDaemonDeferredSleep *sleep)
|
|||
UpDaemon *daemon = sleep->daemon;
|
||||
UpDaemonPrivate *priv = daemon->priv;
|
||||
|
||||
if (up_backend_emits_resuming (priv->backend)) {
|
||||
sleep->handler = g_signal_connect_swapped (priv->backend, "resuming",
|
||||
G_CALLBACK (emit_resuming), sleep);
|
||||
}
|
||||
|
||||
/* run the command */
|
||||
g_debug ("Running %s", sleep->command);
|
||||
ret = g_spawn_command_line_sync (sleep->command, &stdout, &stderr, NULL, &error_local);
|
||||
if (!ret) {
|
||||
error = g_error_new (UP_DAEMON_ERROR,
|
||||
|
|
@ -408,32 +446,13 @@ up_daemon_deferred_sleep_cb (UpDaemonDeferredSleep *sleep)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* emit signal for session components */
|
||||
g_debug ("emitting resuming");
|
||||
g_signal_emit (daemon, signals[SIGNAL_RESUMING], 0);
|
||||
g_signal_emit (daemon, signals[SIGNAL_NOTIFY_RESUME], 0,
|
||||
priv->sleep_kind);
|
||||
|
||||
/* reset the about-to-sleep logic */
|
||||
g_timer_reset (priv->about_to_sleep_timer);
|
||||
g_timer_stop (priv->about_to_sleep_timer);
|
||||
|
||||
/* actually return from the DBus call now */
|
||||
dbus_g_method_return (sleep->context, NULL);
|
||||
if (!up_backend_emits_resuming (priv->backend))
|
||||
emit_resuming (sleep);
|
||||
|
||||
out:
|
||||
/* clear timer */
|
||||
priv->about_to_sleep_id = 0;
|
||||
priv->sent_sleeping_signal = FALSE;
|
||||
|
||||
g_free (stdout);
|
||||
g_free (stderr);
|
||||
|
||||
/* delete temp object */
|
||||
g_object_unref (sleep->daemon);
|
||||
g_free (sleep->command);
|
||||
g_free (sleep);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue