causa da falha de operação do arquivo i / o = -1 EACCES (Permission denied)

0

Eu estou no meio de um bug no meu programa e o reduzi com o uso de strace para o seguinte erro -

open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)

Para informações básicas, você pode ler este tópico aqui - link

Eu tenho 3 execuções separadas do meu teste, uma normal, uma com o sudo especificado e outra com atraso intencional especificado. Aqui estão os resultados de strace relevantes dessas execuções -

Normal

open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 EACCES (Permission denied)
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3

sudo

open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3

Delayed

("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/value", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
open("/sys/class/gpio/gpio17/direction", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 4
open("/sys/class/gpio/unexport", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3

Agora, tentei pesquisar este erro , mas todos Eu acho que é javascript, android ou nodejs erros sem link para a descrição original. Qualquer tipo de informação seria extremamente benéfica para mim, então obrigado pela sua ajuda:)

EDIT - Se for relevante, tenho isso como regra do udev em /etc/udev/rules.d/99-com.rules -

SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="gpio", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"

e ls -l output -

total 0
--w--w---- 1 root gpio 4096 Sep 16 07:13 export
lrwxrwxrwx 1 root root    0 Sep 16 07:13 gpio17 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio17
lrwxrwxrwx 1 root root    0 Jul 31 05:23 gpiochip0 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpiochip0
--w--w---- 1 root gpio 4096 Sep 16 06:50 unexport

O usuário atual também faz parte do grupo do gpio.

    
por Abhinav Gauniyal 16.09.2016 / 09:10

1 resposta

2

Eu estaria disposto a colocar dinheiro nessa condição de corrida entre seu programa e udev .

Aparentemente, os nós /sys/class/gpio/gpio17/value e /sys/class/gpio/gpio17/direction são criados em algum momento depois de open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3 e, inicialmente, eles provavelmente pertencem a root:root , sem acesso de gravação para seu usuário comum.

Em seguida, a regra do udev entra em ação e o udev chama sh para definir as permissões, mas isso demora um pouco; se você tentar o próximo open() antes, ele falhará.

Não sei se existe uma maneira de você esperar que o udev termine sem pesquisa.

    
por 16.09.2016 / 10:01