Bagaimana menulis file systemd .service yang menjalankan systemd-tmpfiles

16

Saya perlu menjalankan systemd-tmpfiles --createselama proses boot dengan distro systemd. Jadi saya perlu membuat file systemd .service melakukan pekerjaan ini.

Dalam pertanyaan ini Anda dapat membaca semua detail tentang apa yang saya butuhkan dan mengapa: Bagaimana cara kerja systemd-tmpfiles?

Saya telah membaca beberapa dokumen tentang hal itu dan saya menulis tes berikut:

[Unit]
Description=Execute tmpfiles to disable usb-wakeup # see details in the link above
Requires=multi-user.target # see details in the link above
After=multi-user.target    # see details in the link above

[Service]
Type=oneshot
ExecStart=/usr/bin/systemd-tmpfiles --create

[Install]
WantedBy=multi-user.target

Tapi saya tidak yakin, karena systemd-tmpfilesbukan program yang sederhana tetapi sepotong systemd itu sendiri. Saya tidak ingin merusak sistem saya.

Adakah kiat tentang file .service yang benar?

eang
sumber
Periksa dokumentasi berlebihan pada systemd di freedesktop.org/wiki/Software/systemd . Anda dapat mengganti default sistem dengan file Anda sendiri.
vonbrand

Jawaban:

30

[Ini tidak secara langsung membahas masalah systemd-tmpfiles tapi saya pikir Anda sudah mengenali bahwa dalam kasus khusus ini Anda lebih baik hanya menggunakan gema.]

Pertama, "multi-user.target" mungkin atau mungkin bukan yang ingin Anda gunakan. Jika Anda terbiasa dengan konsep runlevel dari hal-hal init style SysV, multi-user adalah systemd yang setara dengan runlevel 3, yang merupakan sistem multi-pengguna yang melakukan booting ke konsol, bukan GUI. Setara dengan runlevel 5, yang melakukan boot ke X, adalah graphical.target . Default ditentukan oleh symlink di /etc/systemd/system(dan / atau /lib/systemd/system; yang di /etcakan mengesampingkan yang di /lib) yang disebut default.target , gunakan ls untuk menemukan di mana ia menunjuk:

»ls -l /etc/systemd/system/default.target
default.target -> /usr/lib/systemd/system/multi-user.target

Untuk desktop linux normal ini akan menjadi graphical.target. Ini sebenarnya tidak penting jika Anda ingin layanan boot yang Anda buat untuk memulai terlepas dari apa runlevel / target default - dalam hal ini, kita bisa menggunakan default.target, dan tidak khawatir untuk apa itu alias. Namun, jika Anda menggunakan multi-pengguna, dan standar Anda adalah grafis, layanan Anda tidak akan terjadi.

Tergantung pada layanan, mungkin ada target atau layanan yang lebih tepat dan spesifik yang ingin Anda mulai terkait. Berdasarkan pertanyaan Anda yang lain, default.target mungkin baik-baik saja. Sebagai catatan, perbedaan antara "target" dan "layanan" adalah bahwa layanan berisi [Service]bagian yang benar-benar menjalankan proses; target hanyalah cara mengelompokkan layanan melalui berbagai arahan "tergantung" dan "membutuhkan"; itu tidak melakukan apa pun sendiri selain memicu target atau layanan lain.

Ketika suatu layanan dimulai ditentukan oleh apa layanan lain secara eksplisit bergantung padanya. Dalam kasus acara yang sederhana dan berdiri sendiri seperti ini yang kita inginkan terlambat dalam proses boot, kita dapat menggunakan kombinasi arahan ini:

[Unit]
After=default.target

[Install]
WantedBy=default.target

Bagian "Instal" digunakan ketika layanan diinstal; "WantedBy" menentukan target yang ingin kita sertakan layanan ini (artinya akan berjalan jika target itu melakukannya, tetapi nb. Ini tidak menentukan kapan akan berjalan dalam kaitannya dengan yang lain ). Karena kami benar-benar ingin layanan ini berjalan lebih lama daripada lebih cepat, kami kemudian menentukan klausa "Setelah". Ini sebenarnya tidak harus sama dengan target WantedBy (biasanya tidak) dan dapat sepenuhnya dihilangkan jika Anda tidak peduli ketika itu terjadi; Saya hanya menggunakannya pada firasat bahwa sebagian besar hal lain akan dijalankan dalam kaitannya dengan hal-hal yang ada di suatu tempat dirantai dengan sesuatu yang telah ditentukan Before=default.target(yang juga bisa kita gunakan; keinginan target dinilai sebelum target dijalankan).

Sebagai contoh, saya hanya akan menggema "halo dunia" ke konsol. Layanan itu sendiri dijelaskan di [Service]bagian:

[Service]
Type=forking
ExecStart=/usr/local/bin/helloworld

Perintah itu membutuhkan path lengkap. Alasan saya tidak hanya menggunakan /usr/bin/echo "hello world"adalah bahwa itu tidak akan berfungsi (output pergi ke / dev / null, saya pikir), dan sementara layanan yang melakukan echo "hello world" > /dev/consolekehendak, eksperimen menunjukkan bahwa menggunakan pengalihan shell dalam arahan ExecStart tidak akan . Jadi / usr / local / bin / helloworld adalah skrip shell dengan satu baris echo "hello world" > /dev/console,.

Perhatikan Type=forking, yang diperlukan untuk skrip shell.

Lengkap, minimal berkas layanan kami hanya tiga bagian ( [Unit], [Service], dan [Install]). Untuk menginstal, letakkan file atau symlink ke file tersebut di / etc / systemd / system atau / usr / lib / systemd / system, dan:

systemctl --system enable helloworld

Itu harus dicetak ln -s .... Ini tidak menjalankan layanan, itu hanya mengkonfigurasi untuk dijalankan saat boot seperti yang dibahas di atas.

Singkatnya. man systemd.unitdan man systemd.servicememiliki lebih banyak detail.

goldilocks
sumber
1
Terima kasih, jawaban yang sangat berguna dan masalah terpecahkan. Hanya sebuah catatan, di distro saya (Chakra Linux) default.targettidak ada /etc/systemd/system, tetapi hanya di/usr/lib/systemd/system
eang
Output dari perintah akan dicatat (ke mana lagi bisa pergi)?
vonbrand
File / usr / lib / systemd / ... adalah fallback (default), Anda seharusnya
meletakkan
Hari-hari default.targetini dapat ditemukan di/lib/systemd/system/default.target
czerasz
1
@ czerasz saya perhatikan pada Fedora 27, jika saya systemctl set-default ...meninggalkan symlink /etc/systemd/system, tetapi itu tidak mengubah yang masuk /lib, yaitu, mereka menunjuk pada target yang berbeda, tetapi barang-barang di bekas harus menimpa yang terakhir. Jika Anda mengaturnya sendiri itulah yang mungkin terjadi. Lagi pula, saya sudah mengedit di kedua lokasi.
goldilocks
2

Untuk layanan systemd-tmpfiles: ia harus dikirimkan bersama distribusi Anda, tetapi Anda selalu dapat memperoleh file layanan dari repositori git hulu

SimonPe
sumber