diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/a/elogind/11-prefer-deep-suspend.patch | 8 | ||||
-rw-r--r-- | source/a/elogind/12-default-deep-suspend.patch | 11 | ||||
-rw-r--r-- | source/a/elogind/5d16d94aa9a5e3afe5b51f591497149630763b24.patch | 39 | ||||
-rw-r--r-- | source/a/elogind/ce3616c8864e56bf7efb233242f20197108a9dba.patch | 132 | ||||
-rw-r--r-- | source/a/elogind/doinst.sh | 1 | ||||
-rwxr-xr-x | source/a/elogind/elogind.SlackBuild | 56 |
6 files changed, 232 insertions, 15 deletions
diff --git a/source/a/elogind/11-prefer-deep-suspend.patch b/source/a/elogind/11-prefer-deep-suspend.patch new file mode 100644 index 000000000..c3d3d23b5 --- /dev/null +++ b/source/a/elogind/11-prefer-deep-suspend.patch @@ -0,0 +1,8 @@ +--- ./src/sleep/10-elogind.conf.orig 2024-04-16 02:21:44.000000000 -0500 ++++ ./src/sleep/10-elogind.conf 2024-04-16 13:32:01.046025234 -0500 +@@ -19,4 +19,4 @@ + #HandleNvidiaSleep=no + #HibernateByUsing= + #SuspendByUsing= +-#SuspendMode=s2idle deep ++SuspendMode=deep s2idle diff --git a/source/a/elogind/12-default-deep-suspend.patch b/source/a/elogind/12-default-deep-suspend.patch new file mode 100644 index 000000000..25eb73dc6 --- /dev/null +++ b/source/a/elogind/12-default-deep-suspend.patch @@ -0,0 +1,11 @@ +--- ./src/shared/sleep-config.c.orig 2024-04-16 02:21:44.000000000 -0500 ++++ ./src/shared/sleep-config.c 2024-04-22 13:31:58.033078814 -0500 +@@ -45,7 +45,7 @@ + #if 0 /// elogind supports suspend modes (deep s2idle) so we need defaults, too + /* Not used by SLEEP_SUSPEND */ + #else // 0 +- [SLEEP_SUSPEND] = STRV_MAKE("s2idle", "deep"), ++ [SLEEP_SUSPEND] = STRV_MAKE("deep", "s2idle"), + #endif // 0 + [SLEEP_HIBERNATE] = STRV_MAKE("platform", "shutdown"), + [SLEEP_HYBRID_SLEEP] = STRV_MAKE("suspend"), diff --git a/source/a/elogind/5d16d94aa9a5e3afe5b51f591497149630763b24.patch b/source/a/elogind/5d16d94aa9a5e3afe5b51f591497149630763b24.patch new file mode 100644 index 000000000..fe7940fff --- /dev/null +++ b/source/a/elogind/5d16d94aa9a5e3afe5b51f591497149630763b24.patch @@ -0,0 +1,39 @@ +From 5d16d94aa9a5e3afe5b51f591497149630763b24 Mon Sep 17 00:00:00 2001 +From: Sven Eden <sven@eden-worx.com> +Date: Mon, 22 Apr 2024 08:31:30 +0200 +Subject: [PATCH] SIGCHLD handler: Check sleep_fork_action against NULL + +Signed-off-by: Sven Eden <sven@eden-worx.com> +--- + src/login/elogind.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/login/elogind.c b/src/login/elogind.c +index e616b8088e..b47540352f 100644 +--- a/src/login/elogind.c ++++ b/src/login/elogind.c +@@ -81,6 +81,7 @@ static int elogind_sigchld_handler( + sd_event_source* s, + const struct signalfd_siginfo* si, + void* userdata ) { ++ const HandleActionData* a; + Manager* m = userdata; + int r, status; + +@@ -97,13 +98,14 @@ static int elogind_sigchld_handler( + + /* The sleep forker PID is always "the outer one", so wait for it second. */ + if ( m->sleep_fork_pid > 0 ) { ++ a = m->sleep_fork_action; + waitpid(m->sleep_fork_pid, &status, WNOHANG | WUNTRACED); + log_debug_elogind( "sleep_fork PID %d waitpid() set status %d", m->sleep_fork_pid, status ); + if ( WIFEXITED(status) || WIFSIGNALED(status) ) + m->sleep_fork_pid = 0; + /* Tell people that they now may take a lock again */ +- if ( m->sleep_fork_action->sleep_operation != _SLEEP_OPERATION_INVALID ) { +- (void) send_prepare_for( m, m->sleep_fork_action, false ); ++ if ( a && a->sleep_operation != _SLEEP_OPERATION_INVALID ) { ++ (void) send_prepare_for( m, a, false ); + m->sleep_fork_action = NULL; /* All done */ + } + } diff --git a/source/a/elogind/ce3616c8864e56bf7efb233242f20197108a9dba.patch b/source/a/elogind/ce3616c8864e56bf7efb233242f20197108a9dba.patch new file mode 100644 index 000000000..3fcc03794 --- /dev/null +++ b/source/a/elogind/ce3616c8864e56bf7efb233242f20197108a9dba.patch @@ -0,0 +1,132 @@ +From ce3616c8864e56bf7efb233242f20197108a9dba Mon Sep 17 00:00:00 2001 +From: Sven Eden <sven@eden-worx.com> +Date: Sun, 21 Apr 2024 17:07:25 +0200 +Subject: [PATCH] Send wakeup signal in SIGCHLD handler (#280) + +The forked out sleeper process fails to send the wakeup signal, as it +does not share the dbus connection with elogind. + +Therefore elogind sends the signal itself once the sleeper has +messaged elogind that it is done via the SIGCHLD signal. + +Bug: #280 +Signed-off-by: Sven Eden <sven@eden-worx.com> +--- + src/login/elogind.c | 19 +++++++++++++------ + src/login/logind-dbus.c | 13 +++++-------- + src/login/logind-dbus.h | 4 ++++ + src/login/logind.h | 3 +++ + 4 files changed, 25 insertions(+), 14 deletions(-) + +diff --git a/src/login/elogind.c b/src/login/elogind.c +index 11000170a6..e616b8088e 100644 +--- a/src/login/elogind.c ++++ b/src/login/elogind.c +@@ -25,6 +25,7 @@ + #include "fd-util.h" + #include "fileio.h" + #include "fs-util.h" ++#include "logind-dbus.h" + #include "mount-setup.h" + #include "musl_missing.h" + #include "parse-util.h" +@@ -100,6 +101,11 @@ static int elogind_sigchld_handler( + log_debug_elogind( "sleep_fork PID %d waitpid() set status %d", m->sleep_fork_pid, status ); + if ( WIFEXITED(status) || WIFSIGNALED(status) ) + m->sleep_fork_pid = 0; ++ /* Tell people that they now may take a lock again */ ++ if ( m->sleep_fork_action->sleep_operation != _SLEEP_OPERATION_INVALID ) { ++ (void) send_prepare_for( m, m->sleep_fork_action, false ); ++ m->sleep_fork_action = NULL; /* All done */ ++ } + } + } + +@@ -416,12 +422,13 @@ void elogind_manager_free( Manager* m ) { + int elogind_manager_new( Manager* m ) { + int r = 0; + +- m->cgroups_agent_fd = -1; +- m->pin_cgroupfs_fd = -1; +- m->test_run_flags = 0; +- m->do_interrupt = false; +- m->sleep_fork_pid = 0; +- m->tool_fork_pid = 0; ++ m->cgroups_agent_fd = -1; ++ m->pin_cgroupfs_fd = -1; ++ m->test_run_flags = 0; ++ m->do_interrupt = false; ++ m->sleep_fork_pid = 0; ++ m->tool_fork_pid = 0; ++ m->sleep_fork_action = NULL; + + /* Init poweroff/suspend interruption */ + m->allow_poweroff_interrupts = false; +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 25df8d2cb9..b83dceae9b 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -1730,7 +1730,11 @@ int manager_set_lid_switch_ignore(Manager *m, usec_t until) { + return r; + } + ++#if 0 /// elogind needs to call this from elogind.c + static int send_prepare_for(Manager *m, const HandleActionData *a, bool _active) { ++#else ++int send_prepare_for(Manager *m, const HandleActionData *a, bool _active) { ++#endif // 0 + int k = 0, r, active = _active; + + assert(m); +@@ -1902,6 +1906,7 @@ static int elogind_execute_shutdown_or_sleep( + * from the shutdown/sleep routines. Doing this in the main thread would + * make it impossible to talk to ourselves. + */ ++ m->sleep_fork_action = a; /* Remember this for the SIGCHLD handler */ + forker = strjoina( "e-", handle_action_to_string( a->handle ) ); + t = safe_fork( forker, + FORK_LOG|FORK_REOPEN_LOG|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO, +@@ -1926,14 +1931,6 @@ static int elogind_execute_shutdown_or_sleep( + log_error_errno( r, "%s: shutdown_or_sleep failed: %m", program_invocation_short_name ); + } + +- /* As elogind cannot rely on a systemd manager to call all +- * sleeping processes to wake up, we have to tell them all +- * by ourselves. +- * Note: execute_shutdown_or_sleep() does not send the +- * signal unless an error occurred. */ +- if ( a->sleep_operation != _SLEEP_OPERATION_INVALID ) +- (void) send_prepare_for( m, a, false ); +- + log_debug_elogind("Exiting from %s", program_invocation_short_name); + + _exit( EXIT_SUCCESS ); +diff --git a/src/login/logind-dbus.h b/src/login/logind-dbus.h +index c9d59231d4..aa8bdfeb23 100644 +--- a/src/login/logind-dbus.h ++++ b/src/login/logind-dbus.h +@@ -9,6 +9,10 @@ + #include "logind-user.h" + #include "logind.h" + ++#if 1 /// elogind needs to call this from elogind.c ++int send_prepare_for(Manager *m, const HandleActionData *a, bool _active); ++#endif // 1 ++ + int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret); + int manager_get_user_from_creds(Manager *m, sd_bus_message *message, uid_t uid, sd_bus_error *error, User **ret); + int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Seat **ret); +diff --git a/src/login/logind.h b/src/login/logind.h +index 20c73444ed..6eb40ddb6f 100644 +--- a/src/login/logind.h ++++ b/src/login/logind.h +@@ -84,6 +84,9 @@ struct Manager { + /* elogind might spawn processes to suspend/hibernate, so we need their PIDs to end them properly */ + pid_t sleep_fork_pid; /* for suspend/hibernate fork */ + pid_t tool_fork_pid; /* for external tool fork */ ++ ++ /* To wake up sleeping consumers using the right operation, the manager must know what is going on. */ ++ const HandleActionData *sleep_fork_action; + #endif // 0 + + Seat *seat0; diff --git a/source/a/elogind/doinst.sh b/source/a/elogind/doinst.sh index e529fda15..e39e2aee3 100644 --- a/source/a/elogind/doinst.sh +++ b/source/a/elogind/doinst.sh @@ -29,6 +29,7 @@ preserve_perms() { preserve_perms etc/rc.d/rc.elogind.new config etc/elogind/logind.conf.new config etc/elogind/sleep.conf.new +config etc/elogind/sleep.conf.d/10-elogind.conf.new config etc/pam.d/elogind-user.new # Reload elogind-daemon: diff --git a/source/a/elogind/elogind.SlackBuild b/source/a/elogind/elogind.SlackBuild index ead080f8e..2f5199837 100755 --- a/source/a/elogind/elogind.SlackBuild +++ b/source/a/elogind/elogind.SlackBuild @@ -25,7 +25,7 @@ cd $(dirname $0) ; CWD=$(pwd) PKGNAM=elogind VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)} -BUILD=${BUILD:-3} +BUILD=${BUILD:-2} # Automatically determine the architecture we're building on: if [ -z "$ARCH" ]; then @@ -98,30 +98,55 @@ find . \ # but sed will still happily scribble all over everything. cat $CWD/elogind.nobody.nogroup.99.99.diff | patch -p1 --verbose || exit 1 +# OK, here's the scoop on s2idle. After doing some digging, it looks like both +# Intel and AMD have stopped officially supporting S3 sleep (aka "deep") with +# the latest generation of CPUs (although it "might work"). I've also seen a +# few people say that S3 is "not secure"... which if you're worried that a +# three letter agency might grab your sleeping laptop and extract the contents +# of the RAM while keeping it powered up, well, maybe in that sense it isn't. +# As far as s2idle, I have heard that it has the potential to be as much of a +# low power mode as deep, but that depends on how low the IRQ rate gets. In +# practice I have heard of s2idle draining a battery in half a day. +# +# Anyway, I tried s2deep here again (with the below sleep patches) and it still +# locks up my machine (a fairly recent Thinkpad X1). +# +# S3 works and has the best power savings of all the partially-on modes. +# Feel free to edit /etc/elogind/sleep.conf.d/10-elogind.conf if s2deep works +# for you, but we'll continue to default to deep for now. +# +# Don't prefer s2idle, as it doesn't seem to work: +cat $CWD/11-prefer-deep-suspend.patch | patch -p1 --verbose || exit 1 +cat $CWD/12-default-deep-suspend.patch | patch -p1 --verbose || exit 1 + +# Upstream sleep fixes: +cat $CWD/ce3616c8864e56bf7efb233242f20197108a9dba.patch | patch -p1 --verbose || exit 1 +cat $CWD/5d16d94aa9a5e3afe5b51f591497149630763b24.patch | patch -p1 --verbose || exit 1 + # Configure, build, and install: export CFLAGS="$SLKCFLAGS" export CXXFLAGS="$SLKCFLAGS" mkdir meson-build cd meson-build meson setup \ - --buildtype release \ - --prefix /usr \ - --libdir /usr/lib${LIBDIRSUFFIX} \ - -Drootlibdir="/lib${LIBDIRSUFFIX}" \ - -Drootlibexecdir="/lib${LIBDIRSUFFIX}/elogind" \ + --buildtype=release \ + --prefix=/usr \ + --libdir=/lib${LIBDIRSUFFIX} \ + --libexecdir=/lib${LIBDIRSUFFIX}/elogind \ + -Dpkgconfiglibdir=/usr/lib${LIBDIRSUFFIX}/pkgconfig \ + -Dpamlibdir=/lib${LIBDIRSUFFIX}/security \ -Dudevrulesdir="/lib/udev/rules.d" \ -Ddocdir="/usr/doc/$PKGNAM-$VERSION" \ -Dhtmldir="/usr/doc/$PKGNAM-$VERSION/html" \ -Dmandir="/usr/man" \ - -Dman=true \ - -Dhtml=false \ + -Dman=enabled \ + -Dhtml=disabled \ -Dbashcompletiondir="/usr/share/bash-completion/completions" \ -Dnobody-user=nobody \ -Dnobody-group=nogroup \ - -Dpam=true \ - -Dpamlibdir="/lib${LIBDIRSUFFIX}/security" \ + -Dpam=enabled \ -Dpamconfdir="/etc/pam.d" \ - -Dacl=true \ + -Dacl=enabled \ -Dsmack=false \ -Dutmp=true \ -Ddefault-hierarchy=legacy \ @@ -136,14 +161,15 @@ meson setup \ DESTDIR=$PKG $NINJA install || exit 1 cd .. -# Create symlinks for elogind binaries to /usr/bin/: -mkdir -p $PKG/usr/bin -ln -sf /bin/elogind-inhibit $PKG/usr/bin/elogind-inhibit -ln -sf /bin/loginctl $PKG/usr/bin/loginctl +# Create symlinks for elogind binaries to /bin/: +mkdir -p $PKG/bin +ln -sf /usr/bin/elogind-inhibit $PKG/bin/elogind-inhibit +ln -sf /usr/bin/loginctl $PKG/bin/loginctl # Make sure we do not overwrite the user's customizations: mv -i $PKG/etc/elogind/logind.conf{,.new} mv -i $PKG/etc/elogind/sleep.conf{,.new} +mv -i $PKG/etc/elogind/sleep.conf.d/10-elogind.conf{,.new} mv -i $PKG/etc/pam.d/elogind-user{,.new} # Strip binaries: |