Bagaimana cara mengkonfigurasi systemd untuk membunuh dan me-restart daemon saat memuat ulang?

12

Saya memiliki daemon old-school yang ingin saya kontrol menggunakan systemd. Ketika file konfigurasinya berubah, ia harus dimatikan dan dihidupkan ulang. Dengan kata lain, setelah mengedit file konfigurasi, systemctl reload MYSERVICEharus mematikan proses dan me-restart itu.

Percobaan 1: Coba yang standar. Ini memberi tahu systemd bagaimana memulai daemon, tetapi tidak bagaimana memuatnya kembali.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

Akibatnya, startdan restartbekerja, tetapi reloadmemberikan kesalahan ini:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

Percobaan 2: Katakan bagaimana cara mematikan proses itu. Ini membunuh proses tetapi systemd tidak me-restart untuk saya.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

...diikuti oleh...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... membunuh proses tetapi tidak dimulai ulang secara otomatis.

Percobaan 3: Gunakan ExecReload untuk memulai kembali proses juga. Ini gagal karena beberapa alasan:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

... pesan kesalahan yang saya dapatkan ...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

Saya berharap ada ReloadType = kill_and_restart atau sesuatu tapi tidak ada keberuntungan.

Bagaimana cara memberitahu systemd untuk membunuh dan memulai ulang daemon saat memuat ulang?

TomOnTime
sumber
Apakah ini benar-benar perlu disisipkan ke dalam reload , di mana itu tidak cocok? Tidak bisakah kau membuat daemon berperilaku bijaksana?
Michael Hampton
Terima kasih @MichaelHampton, tapi ini bukan situasi di mana saya dapat menulis ulang program. Saya menghargai saran Anda yang bermanfaat. Yang mengatakan, saya yakin ini adalah kasus penggunaan systemd umum dan jawaban kanonik mungkin membantu banyak orang.
TomOnTime
1
Saya yakin jawaban mungkin membantu seseorang, jadi saya benar-benar menjawab pertanyaan itu. Saya hanya tidak yakin bahwa ini adalah kasus penggunaan umum. Setelah menggunakan systemd selama sekitar lima tahun, hampir sejak hari itu dilepaskan ke dunia, ini adalah pertama kalinya saya ingat pernah mendengar tentang siapa pun yang mencoba skenario semacam ini. Mungkin saja saya salah memahami sesuatu karena detail yang hilang.
Michael Hampton

Jawaban:

16

Jawabannya adalah, "kamu tidak"! Tapi kami punya kabar baik.

filosofi systemd adalah bahwa memuat ulang adalah opsional dan harus dibiarkan tidak terdefinisi jika tidak ada fungsi memuat yang benar. Saya akan mendefinisikan "fungsi reload yang benar" sebagai reload yang tidak mematikan dan me-restart layanan, atau membuat layanan mengubah PID-nya. Dengan kata lain, systemd hanya ingin mencerminkan fitur apa yang ada.

Sebagai gantinya, Anda harus menggunakan systemctl reload-or-restartyang akan melakukan reload jika ada, dan restart jika tidak.

Dari halaman manual ...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

Oleh karena itu: (1) biarkan ExecReload kosong, (2) gunakan systemctl reload-or-restart MYSERVICEdan, (3) Anda harus siap.

Jika Anda mencoba menggunakan ExecReload untuk menentukan cara untuk mematikan dan me-restart layanan, itu akan memiliki PID baru dan systemd akan bingung.

TomOnTime
sumber
3

filosofi systemd reloadadalah opsional dan pengguna systemd harus tahu, untuk setiap layanan, apakah harus memanggil reloadatau memalsukannya dengan menelepon restart.

Karena itu, jawaban untuk pertanyaan Anda adalah, "Itu tidak berfungsi, dan seharusnya tidak. Tolong selesaikan ini di lapisan selanjutnya yang lebih tinggi."

Dengan kata lain, systemd ingin Anda hanya menerapkan " reload " jika layanan yang mendasarinya mendukung fungsionalitas reload yang benar ... yaitu reload yang tidak mematikan dan memulai kembali layanan, atau membuat layanan mengubah PID-nya. Dengan kata lain, systemd hanya ingin mencerminkan fitur apa yang ada.

Anda mungkin bertanya pada diri sendiri: Tetapi bukankah lebih mudah jika saya dapat menerapkan pemuatan "palsu" dengan mengizinkan ExecReloaduntuk membunuh dan memulai kembali layanan? Maka saya bisa menggunakan systemctl reload FOOuntuk semua layanan saya dan saya tidak harus ingat mana yang mendukungnya dan mana yang tidak?

Ya, itu akan lebih mudah, tetapi itu tidak akan menjadi cara systemd. Systemd ingin penelepon menjadi hal yang tahu jika reloadada untuk layanan ini. Systemd ingin menjadi antarmuka umum untuk fitur yang ada, tidak ingin bertanggung jawab untuk mengisi kekosongan.

Sebagai contoh, boneka mengasumsikan bahwa layanan yang digerakkan oleh sistem tidak memiliki reloaddan default untuk membunuh dan memulai kembali proses . Jika jenis Layanan [] menambahkan cara untuk menentukan bahwa memuat ulang, dan bahwa itu harus digunakan pada pemberitahuan, ia perlu mempelajari layanan mana yang memiliki atau tidak memiliki memuat ulang asli. Chef dan semua sistem lain juga harus mempelajari hal yang sama karena systemd ingin itu diselesaikan pada lapisan itu. (MiniRant: untuk memulai proses systemd tampaknya merupakan sistem i-do-everything-at-my-layer saya yang serba tahu, serba guna, dan menyesuaikan. Oleh karena itu saya tidak dapat memberi tahu Anda mengapa tidak dilakukan. memperluas filosofi ini menjadi memuat ulang. Mungkin salah satu penulis dapat berpadu di sini.)

TomOnTime
sumber
1
Ada systemctl reload-or-restart, yang akan memuat ulang layanan jika mendukungnya, dan memulai kembali jika tidak. Tidak tahu mengapa Wayang membuat asumsi ini.
Michael Hampton