Непонимание systemd-inhibit

Вопрос или проблема

Я провел эксперимент. Я использовал K3b для записи iso на CD-RW. Во время этого процесса я выполнил systemctl suspend.

Компьютер действительно ушел в спящий режим.

Я неправильно понимаю systemd-inhibit?

Я посмотрел на это и не уверен, может ли это помочь.

Как временно запретить спящий режим?

  systemd-inhibit может быть использован для выполнения программы с блокировкой отключения, спящего режима или бездействия.
       Блокировка будет получена перед выполнением указанной командной строки и освобождена после.

       Блокировки-инхибиторы могут использоваться для блокировки или задержки запросов на спящий режим и отключение системы от пользователя, а также для автоматической обработки бездействия ОС. Это полезно для предотвращения спящего режима системы во время записи оптического диска или аналогичных операций, которые не должны прерываться.

У меня была такая же проблема — после вызова команды, завернутой в systemd-inhibit, мой ноутбук успешно вошел в спящий режим. Я не нашел решения этой проблемы, но у меня есть хороший обходной путь. (Я использую archlinux, но, я полагаю, это должно работать в большинстве случаев.)

Основная идея состоит в обертке основной службы (бинарного файла или скрипта), реализующей функциональность сна.

1. Найдите основную службу

$ systemctl status systemd-suspend.service
○ systemd-suspend.service - System Suspend
     Loaded: loaded (/usr/lib/systemd/system/systemd-suspend.service; static)

Проверьте содержимое /usr/lib/systemd/system/systemd-suspend.service

$ cat /usr/lib/systemd/system/systemd-suspend.service
...
[Service]
Type=oneshot
ExecStart=/usr/lib/systemd/systemd-sleep suspend

И победителем является /usr/lib/systemd/systemd-sleep.
Обратите внимание, что он принимает один аргумент, поэтому обертка-скрипт не должна его терять. В качестве бонуса мы исправим все другие режимы (poweroff и hibernate) в одном месте.

$ file /usr/lib/systemd/systemd-sleep
/usr/lib/systemd/systemd-sleep: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=fa6da37bf95f4a7255909a8e18fecbc1f3910acc, for GNU/Linux 4.4.0, stripped

2. Переместите его

sudo mv /usr/lib/systemd/systemd-sleep /usr/lib/systemd/systemd-sleep.bin

3. Создайте обертку-скрипт

Например, в моем .bash_aliases у меня есть:
alias lxcexport="systemd-inhibit lxc image export". Экспорт, вызванный этой псевдокомандой, должен блокировать сервис сна, пока lxc не завершит экспорт контейнера.

В отчете systemd-inhibit указывается, что он заблокирован командой systemd-inhibit:

$ systemd-inhibit --list --no-pager
WHO                                UID  USER PID    COMM            WHAT                                WHY      MODE 
...
lxc image export server:container… 1000 cot 868971 systemd-inhibit shutdown:sleep:idle                 Unknown… block
...

Таким образом, в скрипте-обертке мы задерживаем вызываемое действие сна на заранее определенную задержку (например, 5 секунд), пока systemd-inhibit --list --no-pager --no-legend|grep systemd-inhibit возвращает ненулевой результат. После освобождения блокировки grep вернет ничего и скрипт продолжит выполнение и вызовет основной бинарный файл службы сна с переданным аргументом.

NB Имейте в виду, что когда это произойдет, это не остановится автоматически при повторной активации пользователя. То есть это будет игнорировать вас.

sudo vi /usr/lib/systemd/systemd-sleep.wrapper

#!/bin/sh
while test -n "$(systemd-inhibit --list --no-pager --no-legend|grep systemd-inhibit)" ; do 
    printf '.'
    sleep 5
done

/usr/lib/systemd/systemd-sleep.bin $1

Сделайте его исполняемым.

sudo chmod +x /usr/lib/systemd/systemd-sleep

Наконец, создайте ссылку на скрипт-обертку. Таким образом, вы не потеряете скрипт-обертку, если запланированное обновление системы перезапишет systemd-sleep.

sudo ln -s /usr/lib/systemd/systemd-sleep.wrapper /usr/lib/systemd/systemd-sleep

В журнале это выглядит примерно так:

May 09 08:54:53 LIVE.ARCH.BOX systemd-logind[798]: The system will suspend now!
May 09 08:54:53 LIVE.ARCH.BOX systemd[1]: Reached target Sleep.
May 09 08:54:53 LIVE.ARCH.BOX systemd[1]: Starting System Suspend…
May 09 08:54:53 LIVE.ARCH.BOX systemd-logind[798]: Operation ‘sleep’ finished.
May 09 08:58:27 LIVE.ARCH.BOX systemd[1545]: snap.lxd.lxc.9a9d4293-449f-4314-91b3-02aca1c4006b.scope: Consumed 4min 39.349s CPU time.
May 09 08:58:29 LIVE.ARCH.BOX systemd-sleep[859442]: …………………………………….
May 09 08:58:29 LIVE.ARCH.BOX systemd-sleep[863081]: Going to suspend…
May 09 08:58:29 LIVE.ARCH.BOX systemd-sleep[863080]: Going to suspend…
May 09 08:58:29 LIVE.ARCH.BOX systemd-sleep.bin[863078]: Entering sleep state ‘suspend’…
May 09 08:58:29 LIVE.ARCH.BOX kernel: PM: suspend entry (deep)
May 09 08:58:29 LIVE.ARCH.BOX kernel: Filesystems sync: 0.487 seconds

СОВЕТ
То же самое можно сделать с pm-utils (но на этот раз я изменил скрипт действия напрямую):

$ which pm-hibernate
/usr/bin/pm-hibernate
10:24:34 [cot@LIVE ~]$ ls -la /usr/bin/pm-hibernate
lrwxrwxrwx 1 root root 31 May  8  2021 /usr/bin/pm-hibernate -> /usr/lib/pm-utils/bin/pm-action

.

$ cat /usr/lib/pm-utils/bin/pm-action

...
command_exists "check_$METHOD" && command_exists "do_$METHOD" || {
log "pm-utils не знает, как $METHOD на этой системе."
    exit 1
}

##задержка, если systemd-inhibit была вызвана кем-то
while test -n "$(systemd-inhibit --list --no-pager --no-legend|grep systemd-inhibit)" ; do 
    printf '.'
    sleep 55
done
...

Суть путаницы

Вы привели цитату из руководства systemd-inhibit. Однако, вы, вероятно, путаетесь, как это должно работать, возможно, из-за формулировки руководства.

В руководстве говорится, что systemd-inhibit полезен для предотвращения спящего режима системы во время операций, таких как запись оптического диска.

Итак, в то время, когда вы используете K3b (программа записи дисков), вы можете ошибочно ожидать, что система автоматически запрещает спящий режим во время записи.

К сожалению, это не так, как systemd-inhibit работает по умолчанию. Это не демон, который автоматически обнаруживает и предотвращает сон для всех критических операций. Хотя вы можете быть введены в заблуждение, полагая, что все программы systemd — это демоны, работающие в фоне, systemd-inhibit — это инструмент командной строки, который позволяет вам как пользователю явно запрещать спящие, отключенные или бездействующие состояния во время выполнения определенной команды.

Другая недопонимание заключается в том, что вы выполнили команду systemd-inhibit после того, как начали K3b. systemd-inhibit принимает имя программы для запуска, а не идентификатор процесса уже запущенной программы.

Если вы хотите предотвратить спящий режим системы во время работы K3b, вам нужно заранее использовать systemd-inhibit следующим образом:

systemd-inhibit --what=sleep --who="K3b" --why="Запись ISO" k3b

Эта команда гарантирует, что система не перейдет в спящий режим, пока работает K3b.

Ошибочные ожидания

Если вы запускаете K3b сначала, а затем пытаетесь использовать systemd-inhibit для уже запущенного процесса, это не сработает. Например, следующее неверно:

[неверно] systemd-inhibit --what=sleep --who="K3b" --why="Запись ISO" --pid= [/неверно]

Это не сработает, потому что systemd-inhibit не поддерживает присоединение к уже существующим процессам.

Аргументы командной строки (из руководства)

  • --what=: Указывает, что следует запретить (например, спящий режим, отключение, бездействие). По умолчанию — idle:sleep:shutdown, если не указано.
  • --who=: Краткое описание программы, берущей блокировку (по умолчанию используется командная строка).
  • --why=: Краткое описание причины блокировки (по умолчанию «Неизвестная причина»).
  • --mode=: Указывает, как применяется блокировка (block, delay или block-weak). По умолчанию — block.

Автоматизация

Хотя systemd-inhibit – мощный инструмент, он требует ручного вмешательства для эффективной работы. Идеально было бы, чтобы приложения, такие как K3b, решали бы это сами путем программного получения и освобождения блокировок-инхибиторов во время критических операций (например, записи диска). Это обеспечило бы лучший пользовательский опыт и предотвратило бы потерю данных или повреждение оборудования из-за неожиданного перехода в спящий режим системы.

Если бы K3b был разработан для этого, он использовал бы интерфейс D-Bus для автоматического получения и освобождения блокировок-инхибиторов. До тех пор вам необходимо явно использовать systemd-inhibit, чтобы гарантировать, что критические задачи не будут прерваны переходом в спящий режим системы.

.

Ответ или решение

Теория

systemd-inhibit — это инструмент командной строки, который позволяет пользователю временно блокировать действия системы, такие как переход в спящий режим или выключение, во время выполнения определенной команды. Цель этого инструмента — предотвратить неожиданные системные действия, которые могут прервать важные процессы, например, запись диска. Однако существует некоторое непонимание того, как systemd-inhibit работает, особенно среди пользователей, которые ожидают, что он будет автоматически выявлять и блокировать такие действия для всех критических операций.

Пример

Проблема, описанная пользователем, касалась попытки использования systemd-inhibit для предотвращения перехода системы в спящий режим во время записи ISO-образа на CD-RW диске с помощью K3b. Пользователь запустил K3b, а затем выполнил команду systemctl suspend, и система ушла в спящий режим, что и вызвало сомнения в корректности понимания работы systemd-inhibit. Этот инцидент подчеркивает важность корректного использования systemd-inhibit.

Применение

Для правильной работы systemd-inhibit необходимо вызвать его перед началом выполнения критичной операции. Например, чтобы предотвратить переход системы в спящий режим во время работы K3b, следует выполнить команду:

systemd-inhibit --what=sleep --who="K3b" --why="Burning an ISO" k3b

Эта команда инициирует запуск K3b под контролем systemd-inhibit, тем самым гарантируя, что система не перейдет в спящий режим до завершения операции.

Заключение

Важно понимать, что systemd-inhibit не является сервисом, который автоматически контролирует системные действия для всех программ. Он требует явного использования. Поэтому, для обеспечения безопасности и непрерывности работы определенных приложений, таких как запись дисков, пользователю необходимо заранее планировать использование systemd-inhibit. Наилучшим решением будет взаимодействие приложений с D-Bus для автоматического управления блокировками, что, в свою очередь, может улучшить пользовательский опыт и предотвратить возможные потери данных.

Оцените материал
Добавить комментарий

Капча загружается...