Udev etkinliğinde uzun süre nasıl çalıştırılır?


11

USB modemim bağlıyken ppp bağlantısı çalıştırmak istiyorum , bu yüzden bu udevkuralı kullanıyorum:

ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="16d8",\
    RUN+="/usr/local/bin/newPPP.sh $env{DEVNAME}"

(My Modem göründüğü /devkadar ttyACM0)

newPPP.sh:

#!/bin/bash
/usr/bin/pon prov $1 >/dev/null 2>&1 &

Sorun:

udevOlay patlar ve newPPP.sh çalıştığı, ancak newPPP.shsüreç ~ 4-5s sonra öldürüldü. pppbağlanmak için zamanı yok (çevirmeli bağlantı için zaman aşımı süresi 10 saniyedir).

Öldürülmeyecek uzun süreli bir süreci nasıl yürütebilirim?

Kullanmayı denedim nohup, ama işe yaramadı.

Sistem: Arch Linux

Güncelleme

Maxschlepzig sayesinde burada bir çözüm buldum .

Kullandığım at nowUdev sürecinden müstakil işimi çalıştırın.

Ancak tek soru cevapsız kalıyor: Neden çalışıyor nohupve &çalışmıyor?

Yanıtlar:


11

Systemd desteği ile iyi bir dağıtım yaparsanız, en kolay ve teknik olarak en güvenli yol bir cihaz birimi kullanmaktır .

Bu şekilde, systemd uzun süredir çalışan komut dosyasının tam kontrolüne sahip olacak ve hatta cihaz kapatıldıktan / çıkarıldıktan sonra işlemi düzgün bir şekilde sonlandırabilecektir - süreci ayırmak, işlem durumunun tam kontrolünde olmaktan vazgeçtiğiniz anlamına gelir. ve tarihi.

Bunun yanı sıra, cihazın durumunu ve ekli servisini çalıştırarak inceleyebilirsiniz systemctl status my-ppp-thing.device.

Daha fazla örnek ve ayrıntı için bu blog yayınına da bakın .


6

Günümüzde udev, ortaya çıkan görevleri aramak-yok etmek için cgroups kullanıyor. Bir çözüm "şu anda" veya "parti" kullanmaktır. Başka bir çözüm, çift ​​çatal yapmak ve işlemi başka bir gruba "yeniden konumlandırmak" tır. Bu bir örnek python kodudur (benzer kod herhangi bir dilde yazılabilir):

os.closerange(0, 65535)  # just in case
pid = os.fork()
if not pid:
  pid = os.fork()  # fork again so the child would adopted by init
  if not pid:
    # relocate this process to another cgroup
    with open("/sys/fs/cgroup/cpu/tasks", "a+") as fd:
      fd.write(str(os.getpid()))
    sleep(3)  # defer execution by XX seconds
    # YOUR CODE GOES HERE
sleep(0.1)  # get forked process chance to change cgroup

Hata ayıklama çıktısı, örneğin syslog'a gönderilebilir.


1
Udev neden ortaya çıkan süreçleri yok etmek için bu kadar uzağa gidesin ki?
user30747

Ben udev tarafından başlatılan programların daemon'u engellediği için tahmin ediyorum (örn. Harici ekrana takmaya bağlı bir udev kuralıyla, uzun süren bir program yeni ekranın gerçekten kullanılmasını önleyecektir). Bunun arkasında kendi teknik akıl yürütme olduğuna eminim, ancak ortaya çıkan süreçlerin sistemin büyük bölümlerini tutabileceği ve öldürülmesi gerektiği anlamına gelir.
tobek

2

Kabuk, arka planda komut çalıştırma yeteneğine sahiptir:

(

lots of code

) &

Parantezlerin ardından ve işareti ile gruplanan komutlar alt kabukta eşzamansız olarak yürütülür. Bunu bir USB modem takıldığında ve değiştirildiğinde otomatik olarak bağlanmak için kullanıyorum. Yaklaşık 20 saniye sürer ve udev altında iyi çalışır.


Böyle bir durumda stderr, stdout ve stderr'i yönlendirmek isteyebilirsiniz.
mdpc

@mdpc hmm ... neden? Usb_modeswitch'in bu senaryoda akışları kapattığını gördüm: exec 1 <& - 2 <& - 5 <& - 7 <& -
user42295

1

Setsid ile çalışmaya başladım. Udev kuralının RUN kısmı:

RUN+="/bin/bash script.sh"

sonra senaryoda:

#!/bin/bash
if [ "$1" != "fo_real" ]; then
  /usr/bin/setsid $(/usr/bin/dirname $0)/$(/usr/bin/basename $0) fo_real &
  exit
fi

Rest of script is here....

Komut dosyasına ilk çağrı çıkış durumu 0 ile döner, ancak komut dosyasına ikinci çağrı PPID = 1 ile çalışmaya devam eder.


0

Muhtemelen ana süreci sonlandırıldığından ve sonlandırma sinyali çocuklarına yayılır, bu da onu engellemez (ve SIGKILLhatta yapamazlarsa).

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.