Systemd'yi yeniden yükleme sırasında bir arka plan programı öldürecek ve yeniden başlatacak şekilde nasıl yapılandırılır?


12

Systemd kullanarak kontrol etmek istediğim eski bir daemon'um var. Yapılandırma dosyası değiştiğinde, öldürülmesi ve yeniden başlatılması gerekir. Başka bir deyişle, yapılandırma dosyasını systemctl reload MYSERVICEdüzenledikten sonra işlemi sonlandırmalı ve yeniden başlatmalısınız.

Deneme 1: Varsayılanları deneyin. Bu, sistemd'e arka plan programının nasıl başlatılacağını söyler, ancak nasıl yeniden yükleneceğini değil.

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

Sonuç olarak startve restartçalışmak, ancak reloadbu hatayı verir:

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

Deneme 2: Süreci nasıl öldüreceğini söyle. Bu işlemi öldürür ancak systemd benim için yeniden başlatmaz.

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

...bunu takiben...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... işlemi öldürür ancak otomatik olarak yeniden başlatılmaz.

Deneme 3: İşlemi yeniden başlatmak için ExecReload kullanın. Bu birkaç nedenden dolayı başarısız olur:

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

... aldığım hata mesajı ...:

# 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.

Ben bir ReloadType = kill_and_restart ya da bir şey ama böyle bir şans olmasını beklenir.

Systemd'ye yeniden yükleme sırasında bir arka plan programını öldürmesini ve yeniden başlatmasını nasıl söyleyebilirim?


Bunun gerçekten tam olarak uymadığı yeniden yükleme işlemine sokulması gerekiyor mu? Daemon'un mantıklı davranmasını sağlayamaz mısınız?
Michael Hampton

Teşekkürler @ MichaelHampton, ama bu programı yeniden yazabileceğim bir durum değil. Yardımcı öneriniz için teşekkür ederiz. Bununla birlikte, bunun yaygın bir sistem kullanımı olduğundan eminim ve kanonik bir cevap birçok insana yardımcı olabilir.
TomOnTime

1
Eminim bir cevap birine yardımcı olabilir, bu yüzden soruyu onayladım. Bunun yaygın bir kullanım örneği olduğundan emin değilim. Systemd'yi beş yıl kadar kullandıktan sonra, neredeyse dünyaya açıldığı günden bu yana, bu tür bir senaryo girişiminde bulunan herkesi duyduğumu ilk kez hatırlayabiliyorum. Eksik detaylar nedeniyle bir şeyi yanlış anlıyorum.
Michael Hampton

Yanıtlar:


17

Cevap, "bilmiyorsun"! Ama iyi haberlerimiz var.

systemd'in felsefesi, yeniden yüklemenin isteğe bağlı olması ve gerçek yeniden yükleme işlevselliği yoksa tanımsız bırakılması gerektiğidir. "Gerçek yeniden yükleme işlevselliği", hizmeti öldürmez ve yeniden başlatmaz veya hizmetin PID'sini değiştirmeyen bir yeniden yükleme olarak tanımlarsınız. Başka bir deyişle, systemd sadece hangi özelliklerin var olduğunu yansıtmak ister.

Bunun yerine, varsa systemctl reload-or-restartyeniden yükleme yapacağını ve yoksa yeniden başlatmayı kullanmalısınız.

Man sayfasından ...

   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.

Bu nedenle: (1) ExecReload'u boş bırakın, (2) kullanın systemctl reload-or-restart MYSERVICEve (3) hepiniz ayarlanmış olmalısınız.

Hizmeti öldürmenin ve yeniden başlatmanın bir yolunu tanımlamak için ExecReload'u kullanmayı denerseniz, yeni bir PID'ye sahip olur ve systemd karıştırılır.


3

systemd'in felsefesi reloadisteğe bağlıdır ve systemd kullanıcısı, her servis için arayarak reloadveya arayarak sahte olup olmadığını bilmelidir restart.

Bu nedenle, sorunuzun cevabı "Çalışmıyor ve olmamalı. Lütfen bunu bir sonraki üst katmanda çözün."

Başka bir deyişle, systemd yalnızca " yeniden yükleme " işlevini yalnızca temel hizmet gerçek bir yeniden yükleme işlevini destekliyorsa ... yani hizmeti öldürmeyen ve yeniden başlatmayan veya hizmetin PID'sini değiştirmesini gerektirmeyen bir yeniden yükleme gerçekleştirmenizi ister. Başka bir deyişle, systemd sadece hangi özelliklerin var olduğunu yansıtmak ister.

Kendinize şu soruyu soruyor olabilirsiniz: Ama ExecReloadhizmeti öldürüp yeniden başlatarak "sahte" bir yeniden yükleme uygulayabilirsem daha kolay olmaz mıydı ? O zaman systemctl reload FOOtüm hizmetlerim için kullanabilirdim ve hangilerinin onu desteklediğini ve hangilerinin desteklemediğini hatırlamak zorunda kalmazdım?

Evet, bu daha kolay olurdu, ama sistemd'in yolu bu değildi. Systemd, arayanın reloadhizmet için olup olmadığını bilen bir şey olmasını ister . Systemd mevcut özellikler için ortak bir arayüz olmak istiyor, boşlukları doldurmaktan sorumlu olmak istemiyor.

Örneğin, kukla bir systemd odaklı hizmet yok olduğunu varsayar reloadve öldürme ve süreci yeniden başlatma için varsayılan . Hizmet [] türü, yeniden yüklemenin var olduğunu ve bildirimde kullanılması gerektiğini belirten bir yol eklediyse, hangi hizmetlerin yerel yeniden yüklemeye sahip olup olmadığını öğrenmesi gerekir. Chef ve diğer tüm sistemler de aynı şeyi öğrenmek zorunda kalacaklardı çünkü systemd bu katmanda çözülmesini istiyor. (MiniRant: bir işlem sistemi başlatmak için, her şeyi bilen, her şeyi bağlayan, tüm ad alanı özelleştiren bir katmanımdaki her şeyi bilen bir sistem gibi görünüyor. belki de yazarlardan biri buraya girebilir.)


1
Orada systemctl reload-or-restarto destekliyorsa hizmetini yeniden yükleyin ve bunları yapmazsa onu yeniden başlatılır. Kukla'nın bu varsayımı neden yaptığını bilmiyorum.
Michael Hampton
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.