Por que esse bloqueio de regras do udev está bloqueado?

5

Aqui está uma regra do meu diretório /lib/udev/rules.d :

SUBSYSTEM=="input", ATTRS{idVendor}=="045e", ATTRS{idProduct}=="008c", RUN+="/home/mikeknoop/scripts/udev-receiver.sh"

Aqui está o conteúdo simples do script udev-receiver.sh :

#!/bin/bash

echo "UDEV-RECEIVER INIT" >> /var/log/external.log

{
sleep 5;
echo "Done" >> /var/log/external.log
} &

echo "UDEV-RECEIVER FINISH" >> /var/log/external.log

Quando eu conecto meu dispositivo, a saída de external.log é como você esperaria:

UDEV-RECEIVER INIT
UDEV-RECEIVER FINISH
Done

No entanto, estou acompanhando também o syslog /var/log/syslog e posso ver que, embora eu tenha bifurcado o processo sleep de execução longa, udev inicialização do dispositivo está bloqueando até que Done apareça em external.log file.

O motivo é importante porque estou tentando definir algumas propriedades do dispositivo por meio de xinput , mas o dispositivo não está listado por xinput list até que a inicialização udev inteira seja concluída (até que Done apareça em external.log ).

De acordo com a udev (7) - página man do Linux

  

"Adicione um programa à lista de programas a serem executados para um   dispositivo. Isso só pode ser usado para tarefas de execução muito curtas. Executando um   processo de evento por um longo período de tempo pode bloquear todos os outros eventos   para este ou um dispositivo dependente. Tarefas de longa duração precisam ser   imediatamente desanexado do próprio processo do evento. "

Não consigo reconciliar a página de manual e o comportamento que estou vendo. Alguém pode esclarecer ou oferecer uma maneira melhor de definir propriedades por meio de xinput quando um dispositivo é inserido?

Obrigado!

    
por Mike Knoop 05.05.2013 / 01:46

1 resposta

3

Respondendo a minha própria pergunta depois de muita pesquisa.

A nova "filosofia" do udev

Aparentemente, a nova maneira "correta" de usar udev não é incorrer em processos de execução longa.

Via link :

  

RUN ... Iniciar daemons ou outros processos de execução longa não é   apropriado para o udev; os processos bifurcados, separados ou não, serão   incondicionalmente morto após o término do tratamento do evento.

Note como isso está em contradição com a citação de página do homem no OP.

Meu melhor palpite é que uma mudança recente de udev (~ 2012 em algum momento) força todos os processos incluindo seus bifurcados a terminar antes de permitir que a execução continue como um mecanismo de aplicação dessa nova filosofia.

Portanto, todas as documentações e respostas facilmente acessíveis na web que fornecem o padrão no OP como solução estão quebradas.

A nova filosofia de padrão de longa duração é compreensível na instância quando se fala de algum daemon que está sempre em execução quando o dispositivo está conectado. No entanto, elimina o efetivo defer use-case junto com ele.

Solução alternativa

No entanto, também descobri uma solução alternativa:

/lib/udev/rules.d/98-mouse-config.rules/

SUBSYSTEM=="usb", ATTRS{idVendor}=="045e", ATTRS{idProduct}=="008c", ACTION=="add|remove", ENV{ID_TYPE}!="hid", RUN+="/home/mikeknoop/scripts/udev-receiver.sh"

udev-receiver.sh

#!/bin/bash
echo /home/mikeknoop/scripts/mouse.sh | at now

mouse.sh

#!/bin/bash
sleep 3;
export DISPLAY=":0.0"
export XAUTHORITY="/home/mikeknoop/.Xauthority"
/usr/bin/xinput --set-prop 'pointer:Microsoft Microsoft Wireless Optical Mouse® 1.0A' 'Device Accel Constant Deceleration' 2.00000
... more xinput rules here

Nota Isto foi testado e funciona no Ubuntu 13.04

Observação Você precisará instalar o at , que é um pacote de tarefas assíncronas via sudo apt-get install at

Eu reuni a solução alternativa de link

    
por Mike Knoop 05.05.2013 / 04:55