Como executar o processo de longo tempo no evento do Udev?

7

Eu quero executar uma conexão ppp quando meu modem USB estiver conectado, então eu uso essa regra udev :

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

(Meu modem aparece em /dev as ttyACM0 )

newPPP.sh:

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

Problema:

O evento udev é acionado e newPPP.sh está em execução, mas newPPP.sh process é eliminado após ~ 4-5s. ppp não tem tempo para se conectar (seu tempo limite é de 10 segundos para discagem).

Como posso executar um processo de longo prazo que não será eliminado?

Eu tentei usar nohup , mas também não funcionou.

Sistema: Arch Linux

Atualizar

Eu encontrei uma solução aqui , graças a maxschlepzig .

Eu uso at now para executar meu trabalho desconectado do processo do udev.

Mas a única questão permanece sem resposta: Por que nohup e & não funcionam?

    
por Community 20.11.2012 / 10:51

5 respostas

7

Se você executar uma distribuição decente com suporte ao systemd, a maneira mais fácil e tecnicamente mais segura é usar um unidade de dispositivo .

Dessa forma, o systemd terá controle total do script de longa duração e poderá até mesmo finalizar o processo quando o dispositivo for encerrado / removido - desvincular o processo significa que você está desistindo de ter controle total sobre o processo. o estado do processo e sua história.

Além disso, você poderá inspecionar o status do dispositivo e do serviço anexado executando systemctl status my-ppp-thing.device .

Veja também esta postagem do blog para mais alguns exemplos e detalhes.

    
por 22.01.2014 / 22:24
4

Hoje em dia, o udev usa cgroups para procurar e destruir tarefas geradas. Uma solução é usar "agora" ou "lote". Outra solução é fazer o double fork e o processo de "realocação" para outro cgroup. Este é um exemplo de código python (código semelhante pode ser escrito em qualquer idioma):

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

A saída de depuração pode ser enviada para, por exemplo, syslog.

    
por 17.11.2015 / 18:10
2

O Shell tem a capacidade de executar comandos em segundo plano:

(

lots of code

) &

Os comandos agrupados pelas chaves com "e" comercial depois deles serão executados de forma assíncrona em um subshell. Eu uso isso para autoconectar quando um modem USB é inserido e comutado. Demora cerca de 20 segundos e funciona bem sob o udev.

    
por 02.07.2013 / 20:09
1

Eu tenho que trabalhar com o setsid. Minha parte do RUN da regra do udev:

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

então no script:

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

A primeira chamada para o script retorna com status de saída 0, mas a segunda chamada para o script continua sendo executada com PPID = 1.

    
por 16.06.2013 / 01:54
0

Provavelmente porque seu processo pai é finalizado e o sinal de terminação se propaga para seus filhos, que não o bloqueiam (e no caso de SIGKILL eles ainda não conseguem).

    
por 22.11.2012 / 00:06

Tags