web-dev-qa-db-ja.com

systemdサービス:権限が拒否されました

「permission denied」エラーで開始に失敗する新しい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も所有しているため、問題は発生しません。

誰かが私を助けてくれることを願っています。前もって感謝します。

3
Bloch

サービスファイルとスクリプトファイルが少し混乱しているようです。ただし、ファイルの内容は機能するはずです。

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.targetmulti-user.targetなどの特定のターゲットの後に実行されるようにします。デフォルトでは、すべてのサービスがsysinit.targetに依存しているため、どの程度重要かはわかりません。

ここを見ると https://stackoverflow.com/questions/27511139/how-to-make-sysfs-changes-persistent-in-centos-7-systemd 、他に達成する方法がありますカスタムサービスなしで必要なもの。多分あなたはudevルールを試すことができます。

1
nitram