diff options
author | Simon Rettberg | 2017-11-26 01:34:07 +0100 |
---|---|---|
committer | Simon Rettberg | 2017-11-26 01:34:07 +0100 |
commit | 106442253f1f43e12c5cb37d8ff3681815c76cb9 (patch) | |
tree | 83a84f13e1749045e7cf662c8b9195e742351a62 /core/modules/idleaction | |
parent | [hardware-stats] Support reporting suspend/resume (diff) | |
download | mltk-106442253f1f43e12c5cb37d8ff3681815c76cb9.tar.gz mltk-106442253f1f43e12c5cb37d8ff3681815c76cb9.tar.xz mltk-106442253f1f43e12c5cb37d8ff3681815c76cb9.zip |
[idleaction] Support suspend
Diffstat (limited to 'core/modules/idleaction')
8 files changed, 125 insertions, 26 deletions
diff --git a/core/modules/idleaction/data/etc/systemd/system/basic.target.wants/idleaction-set_normal.service b/core/modules/idleaction/data/etc/systemd/system/basic.target.wants/idleaction-set_normal.service new file mode 120000 index 00000000..f6ff1d6b --- /dev/null +++ b/core/modules/idleaction/data/etc/systemd/system/basic.target.wants/idleaction-set_normal.service @@ -0,0 +1 @@ +../idleaction-set_normal.service
\ No newline at end of file diff --git a/core/modules/idleaction/data/etc/systemd/system/idleaction-set_normal.service b/core/modules/idleaction/data/etc/systemd/system/idleaction-set_normal.service new file mode 100644 index 00000000..af4df557 --- /dev/null +++ b/core/modules/idleaction/data/etc/systemd/system/idleaction-set_normal.service @@ -0,0 +1,10 @@ +[Unit] +Description=Setup next rtcwake +DefaultDependencies=no +RefuseManualStart=true + +[Service] +Type=oneshot +ExecStart=/opt/openslx/scripts/systemd-idleaction_init +RemainAfterExit=no + diff --git a/core/modules/idleaction/data/etc/systemd/system/idleaction-set_suspend.service b/core/modules/idleaction/data/etc/systemd/system/idleaction-set_suspend.service new file mode 100644 index 00000000..747d8a4c --- /dev/null +++ b/core/modules/idleaction/data/etc/systemd/system/idleaction-set_suspend.service @@ -0,0 +1,11 @@ +[Unit] +Description=Reset idletime and setup next rtcwake before suspend +DefaultDependencies=no +RefuseManualStart=true +Before=sleep.target + +[Service] +Type=oneshot +ExecStart=/opt/openslx/scripts/systemd-idleaction_init suspend +RemainAfterExit=no + diff --git a/core/modules/idleaction/data/etc/systemd/system/shutdown.target.wants/idleaction-set_normal.service b/core/modules/idleaction/data/etc/systemd/system/shutdown.target.wants/idleaction-set_normal.service new file mode 120000 index 00000000..f6ff1d6b --- /dev/null +++ b/core/modules/idleaction/data/etc/systemd/system/shutdown.target.wants/idleaction-set_normal.service @@ -0,0 +1 @@ +../idleaction-set_normal.service
\ No newline at end of file diff --git a/core/modules/idleaction/data/etc/systemd/system/sleep.target.wants/idleaction-set_suspend.service b/core/modules/idleaction/data/etc/systemd/system/sleep.target.wants/idleaction-set_suspend.service new file mode 120000 index 00000000..51286428 --- /dev/null +++ b/core/modules/idleaction/data/etc/systemd/system/sleep.target.wants/idleaction-set_suspend.service @@ -0,0 +1 @@ +../idleaction-set_suspend.service
\ No newline at end of file diff --git a/core/modules/idleaction/data/opt/openslx/scripts/idleaction-cron_script b/core/modules/idleaction/data/opt/openslx/scripts/idleaction-cron_script index b7617940..929ae68c 100755 --- a/core/modules/idleaction/data/opt/openslx/scripts/idleaction-cron_script +++ b/core/modules/idleaction/data/opt/openslx/scripts/idleaction-cron_script @@ -2,10 +2,11 @@ . /opt/openslx/config || exit 1 +CRONFILE="/etc/cron.d/idleaction-shutdown_schedule" + # If existent, no session is open. Will contain timestamp of last activity. # If not existent, at least one user is logged in -CRONFILE="/etc/cron.d/idleaction-shutdown_schedule" -IDLEHINT="/dev/shm/idlehint" +IDLEHINT="/run/openslx/idlehint" NOW=$(date +%s) # @@ -76,8 +77,8 @@ if [ -n "${SLX_LOGOUT_TIMEOUT}" ] && [ "${SLX_LOGOUT_TIMEOUT}" -gt 0 ]; then rm -f -- "$IDLEHINT" fi else - # No logout timeout is set, take shortcut for shutdown timeout (if set) - if [ -n "$SLX_SHUTDOWN_TIMEOUT" ]; then + # No logout timeout is set, take shortcut for shutdown/suspend timeout (if set) + if [ -n "$SLX_SHUTDOWN_TIMEOUT" ] || [ -n "$SLX_SYSTEM_STANDBY_TIMEOUT" ]; then SESSIONS=$(loginctl | wc -l) if [ "$SESSIONS" = "0" ]; then [ ! -e "$IDLEHINT" ] && echo "$NOW" > "$IDLEHINT" @@ -88,19 +89,23 @@ else fi # -# 2) Check for no-session-shutdown timeout +# 2) Check for no-session shutdown/suspend timeout # -if [ -n "${SLX_SHUTDOWN_TIMEOUT}" ] && [ "${SLX_SHUTDOWN_TIMEOUT}" -gt 0 ] && [ -e "$IDLEHINT" ]; then +if [ -e "$IDLEHINT" ]; then IDLE=$(cat "$IDLEHINT") [ "$IDLE" -gt "$NOW" ] && IDLE="$NOW" IDLE=$(( $NOW - $IDLE )) - if [ "$IDLE" -gt "$SLX_SHUTDOWN_TIMEOUT" ]; then - poweroff + if [ -n "${SLX_SHUTDOWN_TIMEOUT}" ] && [ "${SLX_SHUTDOWN_TIMEOUT}" -gt 0 ] && [ "$IDLE" -gt "$SLX_SHUTDOWN_TIMEOUT" ]; then + poweroff & + exit 0 + elif [ -n "${SLX_SYSTEM_STANDBY_TIMEOUT}" ] && [ "${SLX_SYSTEM_STANDBY_TIMEOUT}" -gt 0 ] && [ "$IDLE" -gt "$SLX_SYSTEM_STANDBY_TIMEOUT" ]; then + systemctl suspend & + exit 0 fi fi # -# 3) Check for hard scheduled shutdown +# 3) Check for hard scheduled shutdown/reboot # # A cron file is created dynamically here so there's everything # in one module and you don't need to repack config.tgz @@ -111,28 +116,33 @@ invalid_time () return 0 } -if [ -n "$SLX_SHUTDOWN_SCHEDULE" -o -n "$SLX_REBOOT_SCHEDULE" ] && [ ! -e "$CRONFILE" ]; then - echo "# OpenSLX: Trigger poweroff at certain time of day" > "$CRONFILE" - echo "SHELL=/bin/ash" >> "$CRONFILE" - echo "PATH=/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin" >> "$CRONFILE" - echo "" >> "$CRONFILE" - for time in $SLX_SHUTDOWN_SCHEDULE; do - HOUR=${time%%:*} - MINUTE=${time##*:} - [ -z "$HOUR$MINUTE" ] && invalid_time && continue - [ "$HOUR" -lt 0 -o "$HOUR" -gt 23 ] && invalid_time && continue - [ "$MINUTE" -lt 0 -o "$MINUTE" -gt 59 ] && invalid_time && continue - echo "$MINUTE $HOUR * * * root /opt/openslx/scripts/idleaction-scheduled_action poweroff" >> "$CRONFILE" - done - # do it again for SLX_REBOOT_SCHEDULE - for time in $SLX_REBOOT_SCHEDULE; do +write_crontab () +{ + local ACTION time HOUR MINUTE + [ $# -lt 1 ] && return + ACTION=$1 + shift + for time in $*; do HOUR=${time%%:*} MINUTE=${time##*:} - [ -z "$HOUR$MINUTE" ] && invalid_time && continue + [ -z "$HOUR" -o -z "$MINUTE" ] && invalid_time && continue [ "$HOUR" -lt 0 -o "$HOUR" -gt 23 ] && invalid_time && continue [ "$MINUTE" -lt 0 -o "$MINUTE" -gt 59 ] && invalid_time && continue - echo "$MINUTE $HOUR * * * root /opt/openslx/scripts/idleaction-scheduled_action reboot" >> "$CRONFILE" + echo "$MINUTE $HOUR * * * root /opt/openslx/scripts/idleaction-scheduled_action $ACTION" >> "$CRONFILE" done +} + +if [ -n "$SLX_SHUTDOWN_SCHEDULE" -o -n "$SLX_REBOOT_SCHEDULE" ] && [ ! -e "$CRONFILE" ]; then + echo "# OpenSLX: Trigger poweroff/reboot at certain time of day" > "$CRONFILE" + echo "SHELL=/bin/ash" >> "$CRONFILE" + echo "PATH=/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin" >> "$CRONFILE" + echo "" >> "$CRONFILE" + write_crontab "poweroff" "$SLX_SHUTDOWN_SCHEDULE" + write_crontab "reboot" "$SLX_REBOOT_SCHEDULE" + # Might want to re-set rtcwake timestamp periodically + if [ -n "$SLX_WAKEUP_SCHEDULE" ]; then + echo "0 * * * * root /opt/openslx/scripts/systemd-idleaction_init" >> "$CRONFILE" + fi touch "/etc/cron.d" # Aufs bug where it won't update dir mtime when creating the file within fi diff --git a/core/modules/idleaction/data/opt/openslx/scripts/systemd-idleaction_init b/core/modules/idleaction/data/opt/openslx/scripts/systemd-idleaction_init new file mode 100755 index 00000000..983dfcec --- /dev/null +++ b/core/modules/idleaction/data/opt/openslx/scripts/systemd-idleaction_init @@ -0,0 +1,64 @@ +#!/bin/ash + +if [ "$1" = "test" ]; then + shift + TEST=1 + SCHEDULE="$@" +else + SCHEDULE= + TEST= + . /opt/openslx/config +fi + +# Figure out the next rtcwake +SCHEDULE="$SCHEDULE $SLX_WAKEUP_SCHEDULE" +if [ "x$1" = "xsuspend" ]; then + # If we're about to suspend, consider reboot and shutdown too - we + # need to wake up to execute these + SCHEDULE="$SCHEDULE $SLX_SHUTDOWN_SCHEDULE $SLX_REBOOT_SCHEDULE" + # Delete this so the idle timeout will be reset + # Otherwise a user might wake the PC up right before + # cron fires the idle action check, which could + # shut the machine down right away because the timestamp + # from the file looks quite old + rm -f -- /run/openslx/idlehint +fi # suspend == true + +SCHEDULE=$( echo ${SCHEDULE} ) # poor man's trim + +NEXT= +if [ -n "$SCHEDULE" ]; then + # Time-math in ash - yay + TODAY=$(date +%Y-%m-%d) + # Use tomorrow instead of adding 86400 seconds so it (hopefully) works when DST changes + TOMORROW=$(date --date="+1 day" +%Y-%m-%d) + NOW=$(date --date="+1 minute" +%s) # don't wake up again immediately + for t in $SCHEDULE; do + HOUR=${t%%:*} + MINUTE=${t##*:} + [ -z "$HOUR" -o -z "$MINUTE" ] && continue + [ "$HOUR" -lt 0 -o "$HOUR" -gt 23 ] && continue + [ "$MINUTE" -lt 0 -o "$MINUTE" -gt 59 ] && continue + TS=$(date --date "$TODAY $t" +%s) + [ "$TS" -le "$NOW" ] && TS=$(date --date "$TOMORROW $t" +%s) + if [ -z "$NEXT" ] || [ "$NEXT" -gt "$TS" ]; then + NEXT="$TS" + fi + done +fi + +if [ -n "$TEST" ]; then + echo -n "Next wakeup: " + date -d "@$NEXT" + exit 0 +fi + +if [ -n "$NEXT" ]; then + # Always assume RTC is UTC so rtcwake will not assume the RTC does DST changes + rtcwake -u -m no -t "$NEXT" +else + rtcwake -m disable +fi + +exit 0 + diff --git a/core/modules/idleaction/module.conf b/core/modules/idleaction/module.conf index 5f37afad..8e74ccce 100644 --- a/core/modules/idleaction/module.conf +++ b/core/modules/idleaction/module.conf @@ -1,5 +1,6 @@ #!/bin/bash REQUIRED_BINARIES=" xprintidle + rtcwake " |