Як автоматично перейти з "Призупинити" у сплячому режимі?


53

Чи можна змусити Ubuntu перейти у сплячий стан із "Suspend", він же "Призупинити седацію"?

Що я шукаю, це таке:
коли я закриваю кришку, ноутбук ставиться в режим Suspend. Потім, після заздалегідь визначеного часу (навіть якщо акумулятор розряджається), якщо я все ще не користуюся ним, він повинен перевести його в режим глибокого сну для економії енергії акумулятора.

Наприклад, мій ноутбук налаштований переходити в Suspend, коли я закриваю кришку. Якщо тоді я не використовую його цілий день, акумулятор розряджається, тому що навіть у режимі призупинення обладнання все ще споживає невелику кількість енергії, і акумулятор з часом розряджається. Я хочу, щоб я міг сказати Ubuntu, що навіть якщо він призупинений, він все одно повинен перейти в сплячий режим через кілька годин бездіяльності.

Windows може це зробити. Ubuntu можна запрограмувати перейти в режим очікування або сплячого режиму за таймером, але не обидва.


У своєму дослідженні я знайшов ту саму нитку Linux Mint, але "Призупинити седацію" не є офіційним терміном Microsoft для цієї функції, наскільки я можу сказати, був винайдений користувачем форуму Linux Mint, який згадував про неї.
ayan4m1

Чи є краща назва цієї функції?
Сергій Стадник

Наскільки я можу сказати, загальновизнаного імені для функції немає. "Гібридна зупинка" використовується деякими, "призупинення седації" використовується тим самим користувачем форуму Linux Mint, і я чув "сплячий і призупинений", що використовується для позначення цього процесу раніше. Microsoft офіційно називає це "гібридним сном", принаймні для Windows 7.
ayan4m1

2
@ ayan4m1 Я розумію, що це старе питання, але я думаю, що це важливо уточнити. Гірбідний сон не є тим самим, як "Сон, а потім сплячий через визначений час". Гібридний сон просто перебуває в сплячому режимі, коли втрачається живлення через розряджання акумулятора. Поведінка, описана в ОП, не вимагає включення гібридного сну.
Павло

Відповіді:


20

В Ubuntu 18.04 набагато простіше. У systemd доступний новий режим призупинення та переходу в сплячку . Щоб почати використовувати цю функцію, вам потрібно створити файл /etc/systemd/sleep.conf із наступним вмістом:

[Sleep]
HibernateDelaySec=3600

Потім ви можете перевірити його командою:

sudo systemctl suspend-then-hibernate

ви можете редагувати, HibernateDelaySecщоб зменшити затримку в сплячку.


Якщо все працює добре, ви можете змінити дію закриття кришки, для цього вам потрібно відредагувати файл /etc/systemd/logind.conf

Вам потрібно знайти варіант HandleLidSwitch=, коментувати його та змінити на HandleLidSwitch=suspend-then-hibernate. Тоді вам потрібно перезапустити систему systemd-logind (попередження! Ви будете перезапущено сеанс користувача) наступною командою:

sudo systemctl restart systemd-logind.service

Це все! Тепер ви можете використовувати цю приємну функцію.


Це було місце на. Використовуючи його на Pop! _OS 18.10 (він же Ubuntu 18.10).
eduncan911

Блискуче дякую! Чи впливає сон.конф на режим сплячки певним чином чи впливає лише на призупинення, а потім на сплячку?
користувач2428107

@ user2428107 Ви можете прочитати про варіанти в ручному systutorials.com/docs/linux/man/5-systemd-sleep
PRIHLOP

35

Рішення цього просте. По-перше, після призупинення та відновлення програма pm-suspend виконує ряд сценаріїв у /etc/pm/sleep.dта /usr/lib/pm-utils/sleep.d. Тому моє рішення полягає в тому, щоб додати сценарій, який виконує наступні дії:

  1. Після призупинення запишіть поточний час та зареєструйте подію пробудження за допомогою rtcwake.
  2. Після відновлення перевіряйте поточний час у відповідності до записаного часу зверху. Якщо минуло достатньо часу, ми, ймовірно, прокинулися через події таймера rtc. Інакше ми прокинулися рано через подію користувача (наприклад, відкриття екрана ноутбука).
  3. Якщо ми прокинулися через таймер rtc, то негайно видаємо команду "pm-hibernate", щоб перейти у сплячку.

Ось сценарій, який робить це. Назвіть це ім’я 0000rtchibernateта помістіть його в /etc/pm/sleep.dкаталог (важливий 0000, щоб сценарій виконувався спочатку призупиненням та останнім під час резюме).

#!/bin/bash
# Script name: /etc/pm/sleep.d/0000rtchibernate
# Purpose: Auto hibernates after a period of sleep
# Edit the "autohibernate" variable below to set the number of seconds to sleep.
curtime=$(date +%s)
autohibernate=7200
echo "$curtime $1" >>/tmp/autohibernate.log
if [ "$1" = "suspend" ]
then
    # Suspending.  Record current time, and set a wake up timer.
    echo "$curtime" >/var/run/pm-utils/locks/rtchibernate.lock
    rtcwake -m no -s $autohibernate
fi

if [ "$1" = "resume" ]
then
    # Coming out of sleep
    sustime=$(cat /var/run/pm-utils/locks/rtchibernate.lock)
    rm /var/run/pm-utils/locks/rtchibernate.lock
    # Did we wake up due to the rtc timer above?
    if [ $(($curtime - $sustime)) -ge $autohibernate ]
    then
        # Then hibernate
        rm /var/run/pm-utils/locks/pm-suspend.lock
        /usr/sbin/pm-hibernate
    else
        # Otherwise cancel the rtc timer and wake up normally.
        rtcwake -m no -s 1
    fi
fi

Сподіваємось, цей код з’являється на цій дошці повідомлень (це моя перша публікація тут).

Відредагуйте значення тайм-аута autohibernate=7200вгорі, за скільки секунд вам потрібно спати, перш ніж перейти у сплячку. Поточне значення вище 2 години. Зауважте, що ваш ноутбук буде прокидатися в цей час на кілька секунд, поки він виконує сплячу функцію.

Тож якщо ви плануєте надягати ноутбук у футляр, не призупиняйте, а замість цього впадайте у сплячку. Інакше ваш ноутбук може перегрітися в esp. якщо він знаходиться в обтягуючому корпусі ковзання (хоча він буде включений лише від декількох секунд до хвилини).

Я використовував цей метод останні пару днів, до цього часу він був успішним (і врятував мене від мертвої батареї сьогодні вдень). Насолоджуйтесь.

Для інших дистрибутивів Linux , які використовують systemdі більш нові версії Ubuntu це повинно працювати , якщо ви помістіть скрипт в /usr/lib/systemd/system-sleepзамість /etc/pm/sleep.d. Також замініть /usr/sbin/pm-hibernateкоманду на systemctl hibernate.


Тут він працював, але лише після того, як я зміцнив файл, щоб додати X для всіх. Я величезна новачка, і мені знадобилося 2 дні, щоб розібратися. Дуже хороший сценарій, і я сподіваюся, що це допоможе тому, хто може мати проблеми. Дякую.

2
Це зробило б корисний пакет Ubuntu / Debian!
Петро Пудлак

Просто цікаво: чи все-таки це дійсно для Ubuntu 13.04? Мені потрібне саме це рішення, але я не хочу возитися з ноутбуком дружини, якщо виявиться, що ламаються речі на нових версіях.
Torben Gundtofte-Bruun

Дякуємо за сценарій. Добре працює для мене на Ubuntu 14.04! Одним з поліпшень було б, якби ноутбук прокинувся до сплячого режиму, він міг би перевірити, чи не підключено він до мережі змінного струму. Якщо так, я хотів би, щоб це знову призупинилося, а не впадало в сплячку. Відновлення після сплячки займає більше часу, і мені дуже не потрібно, щоб він
перезимував,

Дуже дякую!!!! Цей сценарій - це магія, про яку я мріяв !!
yanpas

12

Пояснити, як це працює (це схоже на Windows) простими словами: машина не прокидається з режиму очікування, коли акумулятор розряджається, щоб мати змогу зберегти стан машини на розділ swap, він негайно зберігає все на розділі swap. в режимі очікування, і коли акумулятор розрядиться, він відновиться після цього, завантаживши стан із розділу swap (як це було б у випадку, якщо ви перезимували).

AFAIK linux повинен / повинен використовувати гібридний режим очікування / сплячий режим замість "звичайного" режиму очікування, якщо він знає, що він працює для вашого обладнання. Можливо також, що це зараз вимкнено через занадто багато помилок чи чогось іншого ...;)

Якщо вам подобається експериментувати, можливо, ви можете зрозуміти, чи зможете ви отримати хороші результати з pm-suspend-гібридом .

Якщо наступне говорить, що вам пощастило, то теоретично у вашій системі підтримується гібридне призупинення:

pm-is-supported --suspend-hybrid && echo "you're lucky"

1
Один апостроф у вашій команді оболонки може ввести в оману і заплутати ... будь ласка, уникайте цього.
ayan4m1

1
Так, це відбувається, коли ви редагуєте командний рядок, вбудований в інший текст, не думаючи про це як командний рядок ... Спасибі та виправлені.
січня

Немає жодних проблем, так, я зрозумів про різні заголовки для двох процесів.
ayan4m1

6

Можливо, вас зацікавить s2both . Він надається пакетом uswsuspв Ubuntu 10.10. Він призупиняється на диску, але замість відключення система замість цього ставить його в S3, який є режимом живлення, який зазвичай асоціюється з опцією "Призупинити" в Ubuntu. pm-suspend-гібрид - ще один інструмент, який має намір зробити те саме.

Щоб зробити цю автоматизовану закриту кришку, перегляньте наступне керівництво, яке дозволяє запустити довільний сценарій, коли подія кришки виявлена:

http://ubuntuforums.org/showthread.php?t=1076486

Якщо у вас є ThinkPad, на сторінці вказується tpctlаргумент --pm-sedation-hibernate-from-suspend-timer, який, начебто, забезпечує функцію, яку ви шукаєте. Я б застеріг вас від спроб цього на апаратному забезпеченні, яке не належить ThinkPad.

Для довідки я переглянув сторінку сторінки для hibernate.conf ; начебто не було жодних відповідних варіантів, але, можливо, варто було б прочитати ще раз.


5

Ubuntu 16.04 - від зупинки / сну в сплячку після заздалегідь визначеного часу

Схоже, що в Ubuntu 16.04 справи дещо відрізняються, тому кроки, які я вжив, щоб він працював:

  1. Переконайтесь, що сплячий режим працює так, як очікувалося під час бігу

    systemctl hibernate
    
  2. Скопіюйте оригінальний suspend.targetфайл:

    sudo cp /lib/systemd/system/suspend.target /etc/systemd/system/suspend.target
    

    Потім відредагуйте файл /etc/systemd/system/suspend.targetі додайте рядок:

    Requires=delayed-hibernation.service
    

    до [Unit]розділу цього файлу.

  3. Створіть файл /etc/systemd/system/delayed-hibernation.serviceіз таким вмістом:

[Одиниця]
Опис = тригер затримки сплячки
Перед = suspend.target
Конфлікти = hibernate.target hybrid-suspend.target
StopWhenUnneeded = вірно

[Сервіс]
Тип = onehot
RemainAfterExit = так
ExecStart = / usr / local / bin / delayed-hibernation.sh до призупинення
ExecStop = / usr / local / bin / delay-hibernation.sh призупинити публікацію

[Встановити]
WantedBy = sleep.target
  1. Створіть файл конфігурації /etc/delayed-hibernation.confдля сценарію з наступним вмістом:
# Конфігураційний файл для сценарію 'delayed-hibernation.sh'

# Вкажіть час у секундах, який потрібно провести у сплячому режимі, перш ніж комп'ютер сплять
TIMEOUT = 1200 # дюймів секунд, дає 20 хвилин
  1. Створіть сценарій, який насправді робить важку роботу.

    Створіть файл /usr/local/bin/delayed-hibernation.shіз вмістом:

#! / бін / баш
# Назва сценарію: delaed-hibernation.sh
# Призначення: Автоматично зимує після періоду сну
# Відредагуйте змінну `TIMEOUT` у файлі` $ hibernation_conf`, щоб встановити кількість секунд для сну.

hibernation_lock = '/ var / run / delay-hibernation.lock'
hibernation_fail = '/ var / run / delaed-hibernation.fail'
hibernation_conf = '/ тощо / delaed-hibernation.conf'

# Перевірка конфігураційного файла
якщо [! -f $ hibernation_conf]; тоді
    echo "Файл конфігурації відсутній ('$ hibernation_conf'), переривання."
    вихід 1
фі
hibernation_timeout = $ (grep "^ [^ #]" $ hibernation_conf | grep "TIMEOUT =" | awk -F '=' '{print $ 2}' | awk -F '#' '{print $ 1}' | tr -d '[[\ t]]')
if ["$ hibernation_timeout" = ""]; тоді
    echo Параметр 'TIMEOUT' відсутній у файлі конфігурації ('$ hibernation_conf'), перериваючи. "
    вихід 1
еліф [[! "$ hibernation_timeout" = ~ ^ [0-9] + $]]; тоді
    echo параметр "Bad 'TIMEOUT" (' $ hibernation_timeout ') у файлі конфігурації (' $ hibernation_conf '), очікувана кількість секунд, перериваючи. "
    вихід 1
фі

# Обробка заданих параметрів
if ["$ 2" = "призупинити"]; тоді
    curtime = $ (дата +% s)
    if ["$ 1" = "pre"]; тоді
        якщо [-f $ hibernation_fail]; тоді
            echo "Виявлена ​​помилка сплячки, пропускаючи налаштування таймера пробудження RTC."
        ще
            ехо "Призупинено виявлення. Час запису, встановити таймер RTC"
            echo "$ curtime"> $ hibernation_lock
            rtcwake -m no -s $ hibernation_timeout
        фі
    elif ["$ 1" = "повідомлення"]; тоді
        якщо [-f $ hibernation_fail]; тоді
            rm $ hibernation_fail
        фі
        if [-f $ hibernation_lock]; тоді
            sustime = $ (cat $ hibernation_lock)
            rm $ hibernation_lock
            if [$ (($ curtime - $ sustime)) -ge $ hibernation_timeout]; тоді
                ехо "Автоматичне резюме з призупиненого виявлення. Зимує ..."
                systemctl сплячий
                якщо [$? -не 0]; тоді
                    echo "Автоматична сплячка не вдалася. Намагаємось призупинити її замість."
                    торкніться $ hibernation_fail
                    systemctl призупинити
                    якщо [$? -не 0]; тоді
                        echo "Автоматична сплячка та призупинення аварійної помилки не вдалося. Нічого іншого, щоб спробувати."
                    фі
                фі
            ще
                ехо "Відновлення вручну від виявлення призупинення. Очищення таймера RTC"
                rtcwake -m відключити
            фі
        ще
            echo "Файл" $ hibernation_lock "не знайдено, нічого робити"
        фі
    ще
        відлуння "Нерозпізнаний перший параметр:" $ 1 ", очікуваний" до "або" пост ""
    фі
ще
    echo "Цей сценарій призначений для запуску systemctl delay-hibernation.service (очікуваний другий параметр:" призупинити ")"
фі
  1. Зробіть сценарій виконуваним:
chmod 755 /usr/local/bin/delayed-hibernation.sh

Мені знадобилося досить багато, поки я написав цей сценарій на основі інших відповідей у ​​цій темі, таких речей, які я знайшов в Інтернеті, як https://bbs.archlinux.org/viewtopic.php?pid=1554259

Моя версія сценарію намагається вирішити багато проблем, як, наприклад, знову призупинити роботу, якщо сплячий стан не вдався, але не прокидайтеся знову після заздалегідь визначеного часу.

  1. Останнім кроком я вважаю, що це просто виконати

    sudo systemctl daemon-reload
    sudo systemctl enable delayed-hibernation.service 
    

    щоб переконатися, що нові сервіси / конфігурації використовуються.

Для перевірки журналу обслуговування можна скористатися:

статус sudo systemctl із затримкою-сплячка.сервіс

або для повного журналу використання послуги:

sudo journalctl -u відкладена-сплячка.сервіс

Звичайний журнал, який я отримую від запущеної служби:

mile @ mile-ThinkPad: ~ $ $ sudo systemctl статус відкладено-hibernation.service 
● послуга із затримкою зі сплячки.сервіс - тригер затримки сну
   Завантажено: завантажено (/etc/systemd/system/delayed-hibernation.service; увімкнено; попередньо встановлено постачальник: увімкнено)
   Активний: неактивний (мертвий)

09 червня 20:35:42 милі-ThinkPad systemd [1]: Запуск тригера затримки сплячки ...
09 червня 20:35:42 милі-ThinkPad відкладено-hibernation.sh [2933]: Призупинення виявлено. Час запису, встановити таймер RTC
09 червня 20:35:42 милі-ThinkPad відкладено-hibernation.sh [2933]: rtcwake: припускаючи, що RTC використовує UTC ...
09 червня 20:35:42 милі-ThinkPad відкладено-hibernation.sh [2933]: rtcwake: wakeup using / dev / rtc0 у Четвер 9, 18:55:43 2016
09 червня 20:55:44 миля-ThinkPad systemd [1]: Початок затримки затримки сплячки.
09 червня 20:55:44 миля-ThinkPad systemd [1]: delay-hibernation.service: Блок більше не потрібен. Зупинка
09 червня 20:55:44 миля-ThinkPad systemd [1]: Зупинка затримки затримки сплячки ...
09 червня 20:55:44 милі-ThinkPad відкладено-hibernation.sh [3093]: Автоматичне резюме з призупинення виявлено. Зимує ...
09 червня 20:55:44 миля-ThinkPad systemd [1]: Зупинка затримки затримки сплячки.
миля @ mile-ThinkPad: ~ $ 

Отже, це було б, я сподіваюся, що це дійсно допомагає комусь, оскільки я витратив дні, намагаючись з'ясувати правильну комбінацію конфігурацій та версій сценарію, щоб зробити цю зручну функцію.


Дякую за відповідь, це все ще працює як шарм на Ubuntu 18.04. Я не міг отримати вищезазначені відповіді в роботі, виконання /bin/systemctl hibernateзавжди повертає 1 під час запуску в системному сценарії, хоча це працює добре в командному рядку.
eugenhu

4

Про всяк випадок, коли щось піде не так, pm-hibernateя б швидше зупинив роботу комп'ютера, а не пустив його. Таким чином, ви можете використовувати:

   ...
/usr/sbin/pm-hibernate || /usr/sbin/pm-suspend
   ...

3

Ось оновлена ​​версія відповіді Дерека Пресналла, яка працює з systemd і включає пропозицію Елія Кагана , просто опустіть її в /usr/lib/systemd/system-sleep/delayed_hibernation.sh та зробіть її виконуваною:

#!/bin/bash

hibernation_timeout=1800  #30 minutes

if [ "$2" = "suspend" ]; then
    curtime=$(date +%s)
    if [ "$1" = "pre" ]; then
        echo -e "[($curtime) $@]\nExecuting pre-suspend hook..." >> /tmp/delayed_hibernation.log
        echo "$curtime" > /var/run/delayed_hibernation.lock
        rtcwake -m no -s $hibernation_timeout
    elif [ "$1" = "post" ]; then
        echo -e "[($curtime) $@]\nExecuting post-suspend hook..." >> /tmp/delayed_hibernation.log
        sustime=$(cat /var/run/delayed_hibernation.lock)
        if [ $(($curtime - $sustime)) -ge $hibernation_timeout ]; then
            echo -e "Automatic resume detected, hibernating.\n" >> /tmp/delayed_hibernation.log
            systemctl hibernate || systemctl suspend
        else
            echo -e "Manual resume detected, clearing RTC alarm.\n" >> /tmp/delayed_hibernation.log
            rtcwake -m no -s 1
        fi
        rm /var/run/delayed_hibernation.lock
    fi
fi

Це працювало чудово протягом декількох місяців 15.10, але щось про 16.04 заважає йому перезимувати, хоча сценарій все ще працює.
Шон

@Sean Ви спробували вирішити цю тему ?
Niccolò Maggioni

Дякую, що вказали на мене в правильному напрямку Я створив системну службу (/etc/systemd/system/delayed-hibernation.service), яка посилалась на вищезазначений скрипт, а потім змінила /etc/systemd/system/suspend.target, щоб вимагати відкладеного-hibernation.service.
Шон

2

Ось мій рецепт (випробував його на двох ноутбуках Ubuntu 16.04):

Покладіть цей скрипт куди вам подобається (я ставлю його до root, /syspend.sh) і зробіть його виконуваним ( chmod +x /suspend.sh)

TIMELOG=/tmp/autohibernate.log
ALARM=$(tail -n 1 $TIMELOG)
SLEEPTIME=5000 #edit this line to change timer, e.g. 2 hours "$((2*60*60))"
if [[ $1 == "resume" ]]
then
    if [[ $(date +%s) -ge $(( $ALARM + $SLEEPTIME )) ]]
    then
        echo "hibernate triggered $(date +%H:%M:%S)">>$TIMELOG
        systemctl hibernate 2>> $TIMELOG
    else
        echo "normal wakeup $(date +%H:%M:%S)">>$TIMELOG
    fi
elif [[ $1 == "suspend" ]]
then
    echo "$(date +%s)" >> $TIMELOG
    rtcwake -m no -s $SLEEPTIME
fi

Потім створіть системну ціль: # touch /etc/systemd/system/suspend-to-sleep.target Вставте цей вміст:

#/etc/systemd/system/suspend-to-hibernate.service
[Unit]
Description=Delayed hibernation trigger
Before=suspend.target
Conflicts=hibernate.target hybrid-suspend.target
StopWhenUnneeded=true

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash /suspend.sh suspend
ExecStop=/bin/bash /suspend.sh wakeup

[Install]
WantedBy=sleep.target
RequiredBy=suspend.target

Потім увімкніть це # systemctl enable suspend-to-sleep.target.

Я стикався з проблемою на одному із ноутбуків: закриття кришки не спричинило цю мету. Це було пов’язано з xfce4-power-manager. Існує два способи вирішити цю проблему. Перший з них полягає в редагуванні /etc/systemd/logind.confфайлу і замінити HandleLidSwitch=ignoreз HandleLidSwitch=suspend. Але це буде загальносистемно, тому я просто додав симпосилання до свого сценарію# ln -s /suspend.sh /etc/pm/sleep.d/0000rtchibernate


1

Ще один поширений спосіб вирішення, який ви можете використовувати hybrid-sleep(як це робить Mac OS). Якщо ваш комп'ютер підтримує сплячку, ви можете скористатися цією функцією:

systemctl hybrid-sleep

Ця команда повинна призупинити та відправити на диск (сплячий режим) комп'ютер. Через деякий час комп'ютер вимкнеться (при включенні він буде використовувати файли сплячки для пробудження).

ps: Я знаю, що це не зовсім те, що розміщено в ОП, але це досить близько


0

Не забудьте chmod + x цей файл, зробіть його виконуваним.

Є ще одне рішення без rtcwake, використовуючи будильник в / sys / class / rtc / rtc0. Скористайтеся застарілим кодом у функціях pm (/ usr / lib / pm-utils) після коментарів # оскільки ядро ​​не підтримує безпосередньо ..., ('тому що поточне ядро ​​(після 3.6 щось) безпосередньо підтримує). Поверніть цей код і поставте частину do_suspend () замість do_suspend_hybrid ().

Застарілий код (призупинити, потім перезимувати, коли викликається suspend_hybrid):

# since the kernel does not directly support hybrid sleep, we do
# something else -- suspend and schedule an alarm to go into
# hibernate if we have slept long enough.
# Only do this if we do not need to do any special video hackery on resume
# from hibernate, though.
if [ -z "$SUSPEND_HYBRID_MODULE" -a -w "$PM_RTC/wakealarm" ] && \
    check_suspend && check_hibernate && ! is_set $HIBERNATE_RESUME_POST_VIDEO; \
    then
    SUSPEND_HYBRID_MODULE="kernel"
    do_suspend_hybrid() {
    WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
    echo >"$PM_RTC/wakealarm"
    echo $WAKETIME > "$PM_RTC/wakealarm"
    if do_suspend; then
        NOW=$(cat "$PM_RTC/since_epoch")
        if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ]; then
        log "Woken by RTC alarm, hibernating."
        # if hibernate fails for any reason, go back to suspend.
        do_hibernate || do_suspend
        else
        echo > "$PM_RTC/wakealarm"
        fi
    else
        # if we cannot suspend, just try to hibernate.
        do_hibernate
    fi
    }
fi

Рекомендовано Ще простіше використовувати uswsusp, в той же час максимізуючи переваги s2both, тобто s2both при призупиненні. Помістіть повернутий код у do_suspend () частину модуля uswsusp (/usr/lib/pm-utils/module.d).

Звернений код (suspend_hybrid, коли викликається призупинення):

WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
echo >"$PM_RTC/wakealarm"
echo $WAKETIME > "$PM_RTC/wakealarm"
if do_suspend_hybrid; then
    NOW=$(cat "$PM_RTC/since_epoch")
    if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ];             then
    log "Woken by RTC alarm, hibernating."
    # if hibernate fails for any reason, go back to suspend_hybrid.
    do_hibernate || do_suspend_hybrid
    else
    echo > "$PM_RTC/wakealarm"
    fi
else
    # when do_suspend is being called, convert to suspend_hybrid.
    do_suspend_hybrid
fi      

За допомогою uswsusp ми можемо бачити хід призупинення / сплячки та зворотний процес, відображений у тексті, навіть ми можемо його перервати, натиснувши на зворотній простір. Без uswsusp, призупинення / сплячка просто з'являються-зникають прикро, особливо коли спрацьовує будильник і виконується сплячий режим (s2disk у uswsusp). Встановіть період сну перед сном у звичайному місці на файлі функцій pm.

# variables to handle hibernate after suspend support
PM_HIBERNATE_DELAY=900  # 15 minutes
PM_RTC=/sys/class/rtc/rtc0

Ось модуль uswsusp: (пам’ятайте, цей модуль викликається з функцій pm, тому вставлені змінні однакові)

#!/bin/sh

# disable processing of 90chvt and 99video.
# s2ram and s2disk handle all this stuff internally.
uswsusp_hooks()
{
    disablehook 99video "disabled by uswsusp"
}

# Since we disabled 99video, we need to take responsibility for proper
# quirk handling.  s2ram handles all common video quirks internally,
# so all we have to do is translate the HAL standard options to s2ram options.
uswsusp_get_quirks()
{
    OPTS=""
    ACPI_SLEEP=0
    for opt in $PM_CMDLINE; do
        case "${opt##--quirk-}" in # just quirks, please
            dpms-on)       ;; # no-op
            dpms-suspend)      ;; # no-op
            radeon-off)        OPTS="$OPTS --radeontool" ;;
            reset-brightness)  ;; # no-op
            s3-bios)       ACPI_SLEEP=$(($ACPI_SLEEP + 1)) ;;
            s3-mode)       ACPI_SLEEP=$(($ACPI_SLEEP + 2)) ;;
            vbe-post)      OPTS="$OPTS --vbe_post" ;;
            vbemode-restore)   OPTS="$OPTS --vbe_mode" ;;
            vbestate-restore)  OPTS="$OPTS --vbe_save" ;;
            vga-mode-3)        ;; # no-op
            save-pci)          OPTS="$OPTS --pci_save" ;;
            none)          QUIRK_NONE="true" ;;
            *) continue ;;
        esac
    done
    [ $ACPI_SLEEP -ne 0 ] && OPTS="$OPTS --acpi_sleep $ACPI_SLEEP"
    # if we were told to ignore quirks, do so.
    # This is arguably not the best way to do things, but...
    [ "$QUIRK_NONE" = "true" ] && OPTS=""
}

# Since we disabled 99video, we also need to handle displaying
# help info for the quirks we handle.
uswsusp_help()
{
    echo  # first echo makes it look nicer.
    echo "s2ram video quirk handler options:"
    echo
    echo "  --quirk-radeon-off"
    echo "  --quirk-s3-bios"
    echo "  --quirk-s3-mode"
    echo "  --quirk-vbe-post"
    echo "  --quirk-vbemode-restore"
    echo "  --quirk-vbestate-restore"
    echo "  --quirk-save-pci"
    echo "  --quirk-none"
}

# This idiom is used for all sleep methods.  Only declare the actual
# do_ method if:
# 1: some other sleep module has not already done so, and
# 2: this sleep method can actually work on this system.
#
# For suspend, if SUSPEND_MODULE is set then something else has already
# implemented do_suspend.  We could just check to see of do_suspend was
# already declared using command_exists, but using a dedicated environment
# variable makes it easier to debug when we have to know what sleep module
# ended up claiming ownership of a given sleep method.
if [ -z "$SUSPEND_MODULE" ] && command_exists s2ram && \
    ( grep -q mem /sys/power/state || \
        ( [ -c /dev/pmu ] && check_suspend_pmu; ); ); then
    SUSPEND_MODULE="uswsusp"
    do_suspend()
    {
        WAKETIME=$(( $(cat "$PM_RTC/since_epoch") + PM_HIBERNATE_DELAY))
        echo >"$PM_RTC/wakealarm"
        echo $WAKETIME > "$PM_RTC/wakealarm"
        if do_suspend_hybrid; then
            NOW=$(cat "$PM_RTC/since_epoch")
            if [ "$NOW" -ge "$WAKETIME" -a "$NOW" -lt $((WAKETIME + 30)) ];             then
            log "Woken by RTC alarm, hibernating."
            # if hibernate fails for any reason, go back to suspend_hybrid.
            do_hibernate || do_suspend_hybrid
            else
            echo > "$PM_RTC/wakealarm"
            fi
        else
            # when do_suspend is being called, convert to suspend_hybrid.
            do_suspend_hybrid
        fi      
    }
fi

if [ -z "$HIBERNATE_MODULE" ] && \
    [ -f /sys/power/disk ] && \
    grep -q disk /sys/power/state && \
    [ -c /dev/snapshot ] &&
    command_exists s2disk; then
    HIBERNATE_MODULE="uswsusp"
    do_hibernate()
    {
        s2disk
    }
fi

if [ -z "$SUSPEND_HYBRID_MODULE" ] && 
    grep -q mem /sys/power/state && \
    command_exists s2both && \
    check_hibernate; then
    SUSPEND_HYBRID_MODULE="uswsusp"
    do_suspend_hybrid()
    {   
        uswsusp_get_quirks
        s2both --force $OPTS 
    }
    if [ "$METHOD" = "suspend_hybrid" ]; then
        add_before_hooks uswsusp_hooks
        add_module_help uswsusp_help
    fi
fi  
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.