Служба systemd: в доступе отказано

У меня есть новая служба systemd, которая не запускается с ошибкой "Отказано в доступе". Я купил Thinkpad L480. К сожалению, похоже, что проблема в том, что ядро ​​не обнаруживает тачпад. Это здесь может быть решено путем

sudo sh -c 'echo -n "elantech" > /sys/bus/serio/devices/serio1/protocol'

Поскольку я не хочу делать это при каждом запуске, я создал службу systemd, которая работает не так, как ожидалось.

Мой touchpad_enabler.service является

[Unit]
Description=FooBar

[Service]
Type=oneshot
ExecStart=/usr/local/bin/enable_touchpad.sh

[Install]
WantedBy=default.target

Файл сценария просто

#!/bin/bash

echo -n "elantech" > /sys/bus/serio/devices/serio1/protocol

Но я также попробовал это с sh -c версия. Я настроил разрешения через

sudo chmod 744 /usr/local/bin/enable_touchpad.sh
sudo chmod 644 /etc/systemd/system/touchpad_enabler.service

поэтому оба файла принадлежат пользователю root. Затем я включил его через

systemctl enable enable_touchpad.sh

Когда я вручную запускаю сервис через systemctl start touchpad_enabler.service, он работает совершенно нормально, и тачпад работает как надо. Тем не менее, при запуске службы происходит сбой и отображается как "сбой" в systemctl list-units,

Выход из journalctl -b -u touchpad_enabler.service является:

systemd[1]: Starting Solves bug that Thinkpad L480 Touchpad is not correctly detected...
enable_touchpad.sh[516]: sh: /sys/bus/serio/devices/serio1/protocol: permission denied
systemd[1]: touchpad_enabler.service: Main process exited, code=exited, status=1/FAILURE
systemd[1]: touchpad_enabler.service: Failed with result 'exit-code'.
systemd[1]: Failed to start FooBar

Похоже, проблема в разрешении на запись в сам файл. Но запуск службы вручную работает нормально, и, насколько я понимаю, systemd должен выполнить команду от имени пользователя root, верно?

От чтения man systemctl.service У меня появилась идея добавить '+' к пути к файлу, чтобы он читал

ExecStart=+/usr/local/bin/enable_touchpad.sh

Без эффекта.

Я не очень понимаю, где это protocol файл приходит из. Похоже, он создается ядром при запуске? Так что я также экспериментировал с After= параметр, но systemd должен запускать службы после полной загрузки ядра, верно? Файл также принадлежит пользователю root, поэтому я не ожидаю никаких проблем.

Я надеюсь, что кто-то может помочь мне. Заранее спасибо.

2 ответа

Кажется, у вас немного запутаны файлы сервиса и скриптов. Кажется, что содержимое файлов должно работать.

Systemd нужен служебный файл. Поместите этот файл сюда

/etc/systemd/system/touchpad_enabler.service

С содержанием:

[Unit]
Description=FooBar

[Service]
Type=oneshot
ExecStart=/usr/local/bin/enable_touchpad.sh

[Install]
WantedBy=default.target

Затем ваш сценарий (я изменил имя, чтобы сделать разделение между служебным файлом и файлом сценария более четким. Также /usr/local/bin это лучшее место, потому что оно обычно предназначено для локальных скриптов / программ)

/usr/local/bin/enable_touchpad.sh

И это будет иметь содержимое (без изменений):

#!/bin/bash
echo -n "elantech" > /sys/bus/serio/devices/serio1/protocol

Убедитесь, что права доступа к сценарию и служебному файлу верны. Они должны принадлежать пользователю root, а скрипт должен быть исполняемым.

sudo chmod 744 /usr/local/bin/enable_touchpad.sh
sudo chmod 644 /etc/systemd/system/touchpad_enabler.service

Затем вы включаете сервис systemd.

sudo systemctl enable touchpad_enabler.service

Это включает службу, поэтому она будет работать при загрузке. Его также можно запустить вручную с помощью:

sudo systemctl start touchpad_enabler.service

или вы можете напрямую запустить скрипт, минуя сервис systemd:

sudo /usr/local/bin/enable_touchpad.sh

Я не могу говорить об ошибке или о том, когда создается файл протокола, но служба должна работать.

РЕДАКТИРОВАТЬ:
Вы можете добавить After= параметр к [Unit] раздел службы, чтобы убедиться, что он работает после определенной цели, как default.target или же multi-user.target, По умолчанию каждый сервис зависит от sysinit.target, поэтому я не уверен, насколько это будет иметь значение в вашем случае.

Если вы посмотрите здесь, https://stackoverflow.com/questions/27511139/how-to-make-sysfs-changes-persistent-in-centos-7-systemd, есть другие способы выполнить то, что вы хотите без специальной службы, Может быть, вы можете попробовать правило udev.

У меня та же проблема в моей службе высокой доступности postgresql с именем: «Patroni». Поэтому я просто закомментирую строки пользователя и группы, как показано ниже:

      [Service]
Type=simple

#User=postgres
#Group=postgres

ExecStart=/root/.local/bin/patroni /etc/patroni.yml

А затем перезагрузите новую конфигурацию:

      systemctl daemon-reload;
systemctl start <service>

Просто это!

Другие вопросы по тегам