systemd: masalah izin dengan mkdir & ExecStartPre

37

Saya punya masalah dengan file layanan systemd (disingkat) ini:

[Unit]
Description=control FOO daemon
After=syslog.target network.target

[Service]
Type=forking
User=FOOd
Group=FOO
ExecStartPre=/bin/mkdir -p /var/run/FOOd/
ExecStartPre=/bin/chown -R FOOd:FOO /var/run/FOOd/
ExecStart=/usr/local/bin/FOOd -P /var/run/FOOd/FOOd.pid
PIDFile=/var/run/FOOd/FOOd.pid

[Install]
WantedBy=multi-user.target

Biarkan FOOd menjadi nama pengguna dan FOO nama grup, yang sudah ada untuk daemon saya /usr/local/bin/FOOd.

Saya perlu membuat direktori /var/run/FOOd/sebelum memulai proses daemon /usr/local/bin/FOOdvia # systemctl start FOOd.service. Ini gagal, karena mkdir tidak dapat membuat direktori karena izin:

...
Jun 03 16:18:49 PC0515546 mkdir[2469]: /bin/mkdir: cannot create directory /var/run/FOOd/: permission denied
Jun 03 16:18:49 PC0515546 systemd[1]: FOOd.service: control  process exited, code=exited status=1
...

Mengapa mkdir gagal di ExecStartPre dan bagaimana cara memperbaikinya? (Dan tidak, saya tidak bisa menggunakan sudo untuk mkdir ...)

Mat
sumber
FYI: Saya menggunakan Debian 8
Matt
Bisakah Anda menerjemahkan pesan kesalahan ke bahasa Inggris?
Thushi
1
... Jun 03 16:18:49 PC0515546 mkdir [2469]: / bin / mkdir: direktori / var / run / FOOd / tidak dapat dibuat: tidak ada izin Jun 03 16:18:49 PC0515546 systemd [1] : FOOd.service: proses kontrol keluar, kode = status keluar = 1 ...
Matt

Jawaban:

56

Anda perlu menambahkan

PermissionsStartOnly=true

untuk [Service]. Pengguna Anda FOOdtentu saja tidak diizinkan membuat direktori di /var/run. Untuk mengutip halaman manual:

Membawa argumen boolean. Jika benar, opsi eksekusi terkait izin, seperti yang dikonfigurasikan dengan User = dan opsi serupa (lihat systemd.exec (5) untuk informasi lebih lanjut), hanya diterapkan pada proses yang dimulai dengan ExecStart =, dan tidak ke berbagai ExecStartPre = lainnya , ExecStartPost =, ExecReload =, ExecStop =, dan ExecStopPost = perintah. Jika salah, pengaturan diterapkan ke semua perintah yang dikonfigurasi dengan cara yang sama. Default ke false.

embik
sumber
1
Luar biasa, persis apa yang saya cari.
robert
2
Opsi ini membuat perintah yang ExecReload=dijalankan di root privilege. Ini mungkin bukan yang Anda inginkan.
Rockallite
@Rockallite, itulah dokumentasi yang saya kutip secara harfiah, ya.
embik
2
PermissionsStartOnlysudah ditinggalkan. Referensi: github.com/NixOS/nixpkgs/issues/53852 Bagaimana melakukannya sekarang?
adrelanos
2
@adrelanos Sekarang, tambahkan +segera setelahnya ExecStartPre=. MisalnyaExecStartPre=+/bin/mkdir test
Jamie Scott
28

Ini bukan jawaban yang menjelaskan atau memperbaiki masalah izin, tapi saya pikir Anda harus menggunakan opsi systemds RuntimeDirectory. Mengutip halaman manual :

RuntimeDirectory=, RuntimeDirectoryMode=
       Takes a list of directory names. If set, one or more directories by
       the specified names will be created below /run (for system
       services) or below $XDG_RUNTIME_DIR (for user services) when the
       unit is started, and removed when the unit is stopped. The
       directories will have the access mode specified in
       RuntimeDirectoryMode=, and will be owned by the user and group
       specified in User= and Group=. Use this to manage one or more
       runtime directories of the unit and bind their lifetime to the
       daemon runtime. The specified directory names must be relative, and
       may not include a "/", i.e. must refer to simple directories to
       create or remove. This is particularly useful for unprivileged
       daemons that cannot create runtime directories in /run due to lack
       of privileges, and to make sure the runtime directory is cleaned up
       automatically after use. For runtime directories that require more
       complex or different configuration or lifetime guarantees, please
       consider using tmpfiles.d(5).

Jadi yang harus Anda lakukan adalah mengubah file layanan Anda menjadi:

[Unit]
Description=control FOO daemon
After=syslog.target network.target

[Service]
Type=forking
User=FOOd
Group=FOO
RuntimeDirectory=FOOd
RuntimeDirectoryMode=$some-mode
ExecStart=/usr/local/bin/FOOd -P /run/FOOd/FOOd.pid
PIDFile=/run/FOOd/FOOd.pid

[Install]
WantedBy=multi-user.target
Wieland
sumber
Terima kasih terima kasih. Sayangnya hilang dari paket OpenVPN Ubuntu !!
BaseZen