이유 = -1 EACCES(권한 거부)로 인해 파일 I/O 작업이 실패했습니다.

이유 = -1 EACCES(권한 거부)로 인해 파일 I/O 작업이 실패했습니다.

내 프로그램에 버그가 있어서 strace를 사용하여 범위를 좁혔는데 다음과 같은 오류가 발생했습니다.

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)

배경 정보는 여기에서 이 주제에 대해 읽을 수 있습니다.https://stackoverflow.com/questions/39524234/bug-with-writing-to-file-in-linux-sys-class-gpio

테스트를 3번 개별적으로 실행했습니다. 한 번은 정상적으로 실행되고, 한 번은 sudo가 지정되고, 한 번은 의도적인 지연이 발생했습니다. 다음은 이러한 실행의 관련 strace 결과입니다.

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

이제 이걸 찾으려고 노력 중이야실수, 그러나 내가 찾은 것은 javascript, android 또는 nodejs 오류뿐이었고 원래 설명에 대한 링크는 없었습니다. 어떤 종류의 정보라도 저에게 큰 도움이 될 것입니다. 도움을 주셔서 감사합니다 :)

편집하다- 관련이 있다면 udev 규칙으로 게시하겠습니다 /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'"

그리고 ls -l 출력 -

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

현재 사용자도 GPIO 그룹의 일부입니다.

답변1

나는 귀하의 프로그램과 에 돈을 쓸 의향이 있습니다 udev.

분명히 노드 /sys/class/gpio/gpio17/value/sys/class/gpio/gpio17/direction나중에 어느 시점에 생성되었으며 처음에는 쓰기 권한이 없는 일반 사용자 open("/sys/class/gpio/export", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3가 소유했을 가능성이 높습니다 .root:root

그런 다음 udev 규칙이 적용되고 udev가 sh를 호출하여 권한을 설정하지만 open()이전에 다음 규칙을 시도하면 시간이 좀 걸립니다.

폴링 없이 udev가 완료될 때까지 기다릴 수 있는 방법이 있는지 모르겠습니다.

관련 정보