Biasanya tidak memposting di sini tapi saya ripping rambut saya lebih dari ini. Saya memiliki skrip Python yang bercabang saat diluncurkan, dan bertanggung jawab untuk memulai banyak proses lainnya. Skrip ini dulunya diluncurkan saat startup melalui sysvinit, tetapi baru-baru ini saya memutakhirkan ke Debian Jessie sehingga telah mengadaptasinya untuk diluncurkan melalui systemd.
Sayangnya, saya mengalami masalah yang tidak bisa saya selesaikan. Ketika Anda meluncurkan skrip secara langsung di shell pengguna, itu meluncurkan proses anak itu dengan benar, dan ketika skrip keluar proses anak menjadi yatim piatu dan terus berjalan.
Ketika diluncurkan Via systemd, jika proses induk keluar, anak-anak juga akan keluar (Ya, Layar yang mereka luncurkan mati dan muncul sebagai Mati ???)
Idealnya saya harus bisa memulai kembali skrip induk tanpa membunuh semua proses anak, apakah ada sesuatu yang saya lewatkan?
Terima kasih!
[Unit]
Description=Server commander
After=network.target
[Service]
User=serveruser
Type=forking
PIDFile=/var/Server/Server.pid
ExecStart=/var/Server/Server.py
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
Sunting: Mungkin relevan bagi saya untuk menunjukkan bahwa skrip Python pada dasarnya adalah 'pengontrol' untuk proses anaknya. Ini memulai dan menghentikan server di layar gnu seperti yang diminta dari server pusat. Biasanya selalu berjalan, itu tidak menelurkan layanan dan keluar. Namun ada beberapa kasus di mana saya ingin dapat memuat ulang skrip tanpa membunuh proses anak, bahkan jika itu berarti prosesnya menjadi yatim menjadi pid 1. Sebenarnya, bahkan tidak masalah jika skrip Python memulai proses sebagai proses induk, jika itu bahkan mungkin.
Penjelasan yang lebih baik tentang cara kerjanya:
- Systemd memunculkan / Server.py
- Server.py memetik dan menulis file pid untuk Systemd
- Server.py kemudian memunculkan proses server di layar gnu berdasarkan instruksinya
- Server.py terus berjalan untuk melakukan restart yang diminta dari server
Ketika meluncurkan tanpa Systemd, Server.py dapat di-restart dan layar gnu yang diluncurkan tidak terpengaruh. Saat meluncurkan dengan Systemd, ketika Server.py dimatikan, alih-alih proses layar tersebut menjadi yatim piatu ke pid 1, mereka terbunuh.
sumber
Server.py
kode dan deskripsi bagaimana garpu layanan diluncurkan (jika mereka bercabang). Namun, secara umum, ini adalah masalah ketidakcocokan protokol kesiapan .ExecStop=
itu tidak diperlukan. tindakan standar systemd saat berhenti adalah mematikan proses. Anda mungkin ingin melihat dokumentasi untukKillMode=
direktif.simple
atauforking
, sebenarnya), pilihan terakhir adalahType=oneshot
,RemainAfterExit=yes
danKillMode=control-group
.Jawaban:
Saya berhasil memperbaikinya hanya dengan mengatur KillMode untuk memproses alih-alih grup kontrol (default). Terima kasih semuanya
sumber
Yang menunjukkan bahwa Anda salah melakukannya. Lebih dalam sebentar lagi.
Ini bukan perilaku demon yang benar. Jika proses "utama" - dalam hal ini anak yang telah Anda garpu, sejak Anda tentukan
Type=forking
- keluar, systemd menganggap layanan telah dinonaktifkan dan menghentikan proses lain yang masih berjalan (dalam kelompok kontrol) untuk merapikan .Terkadang konversi dari
rc
skrip System 5 ke systemd tidak mudah, karena cara yang tepat untuk melakukan hal-hal di bawah systemd sangat berbeda. Cara yang tepat untuk melakukan (misalnya) OpenVPN, atau OpenStack, atau OSSEC HIDS di systemd tidak sama dengan yang akan dilakukan denganrc
skrip. Fakta bahwa Anda memiliki skrip yang bercabang-cabang, lalu menelurkan seluruh proses cucu, kemudian keluar dengan mengharapkan cucu-cucu itu terus berjalan menunjukkan bahwa Anda sedang melakukan jenis kengerian yang samaossec-control
, walaupun dengan dua tingkat percabangan yang kurang. Jika Anda menemukan diri Anda menulis skrip "master" yang memeriksa tanda "aktifkan" dan menjalankan proses anak untuk bagian "diaktifkan" dari sistem Anda, maka Anda membuat kesalahan yang sama dengan yang menghebohkanossec-control
.Tidak ada mekanisme buatan sendiri yang diperlukan dengan systemd. Sudah merupakan manajer layanan. Per /unix//a/200365/5132 , cara yang benar untuk melakukan ini dalam systemd adalah tidak memiliki satu layanan yang memunculkan beberapa upaya aneh dan membingungkan untuk memiliki "sub-layanan". Ini adalah untuk memiliki setiap proses anak sebagai layanan systemd sepenuhnya matang dalam haknya sendiri. Kemudian seseorang mengaktifkan dan menonaktifkan, dan memulai dan menghentikan, berbagai bagian sistem menggunakan kontrol sistem normal. Seperti yang Anda lihat dalam kasus OSSEC HIDS, unit layanan template sederhana mencakup hampir semua (satu pengecualian adalah di /ubuntu//a/624871/43344 ) layanan, memungkinkan seseorang untuk melakukan hal-hal seperti
systemctl enable [email protected]
mengaktifkan opsi opsionalagentlessd
layanan, tanpa perlu sama sekali untuk mekanisme "skrip master" yang menghebohkan yang diperlukan dengan Sistem 5rc
.Ada banyak kasus, tidak mungkin ekstrem seperti OSSEC HIDS, di mana pemikiran ulang seperti itu diperlukan. MTS seperti exim dan sendmail adalah dua. Seseorang mungkin memiliki
rc
skrip tunggal yang menghasilkan runner antrian, sebuah SMTP Submission dæmon, dan SMTP Relay dæmon, dengan sekelompok variabel ad hoc shell dalam file konfigurasi untuk mengontrol apa yang dijalankan. Tetapi cara yang tepat untuk melakukan ini dengan systemd adalah memiliki tiga unit layanan yang tepat (dua di antaranya memiliki unit soket terkait ) dan sama sekali tidak ada hal-hal khusus, hanya mekanisme biasa dari manajer layanan.sumber
Anda bisa saja tidur dengan orang tua, dan menunggu systemd membunuhnya pada waktu berhenti.
sumber