Linux: gpio export timing issue

Created on 27 Mar 2014  ·  9Comments  ·  Source: raspberrypi/linux

If the following three commands are executed individually from the command line on the Raspberry Pi using Raspbian (2014-01-07-wheezy-raspbian.zip) then they execute successfully:

pi@raspberrypi ~ $ echo 23 > /sys/class/gpio/unexport
pi@raspberrypi ~ $ echo 23 > /sys/class/gpio/export
pi@raspberrypi ~ $ echo out > /sys/class/gpio/gpio23/direction 
pi@raspberrypi ~ $ 

However, if they are executed together on the same line, there is a permission denied error:

pi@raspberrypi ~ $ echo 23 > /sys/class/gpio/unexport; echo 23 > /sys/class/gpio/export; echo out > /sys/class/gpio/gpio23/direction
-bash: /sys/class/gpio/gpio23/direction: Permission denied
pi@raspberrypi ~ $ 

The permission denied error occurs because "echo out > /sys/class/gpio/gpio23/direction" is being executed before the group and permission bits for "/sys/class/gpio/gpio23/direction" have been set to the appropriate values. The group and permission bits are "root" and "-rw-r--r--", but they should be "gpio" and "-rwxrwx---".

This timing issue can be seen in the command sequence below which exports gpio 23 and lists the contents of "/sys/class/gpio/gpio23/" twice. The output of the first ls command is quite different to the output of the second ls command. Both the group and the permissions for all files have changed.

pi@raspberrypi ~ $ echo 23 > /sys/class/gpio/unexport; echo 23 > /sys/class/gpio/export; ls -l /sys/class/gpio/gpio23/; ls -l /sys/class/gpio/gpio23/
total 0
-rw-r--r-- 1 root root 4096 Mar 27 21:51 active_low
-rw-r--r-- 1 root root 4096 Mar 27 21:51 direction
-rw-r--r-- 1 root root 4096 Mar 27 21:51 edge
drwxr-xr-x 2 root root    0 Mar 27 21:51 power
lrwxrwxrwx 1 root root    0 Mar 27 21:51 subsystem -> ../../../../class/gpio
-rw-r--r-- 1 root root 4096 Mar 27 21:51 uevent
-rw-r--r-- 1 root root 4096 Mar 27 21:51 value
total 0
-rwxrwx--- 1 root gpio 4096 Mar 27 21:51 active_low
-rwxrwx--- 1 root gpio 4096 Mar 27 21:51 direction
-rwxrwx--- 1 root gpio 4096 Mar 27 21:51 edge
drwxrwx--- 2 root gpio    0 Mar 27 21:51 power
lrwxrwxrwx 1 root gpio    0 Mar 27 21:51 subsystem -> ../../../../class/gpio
-rwxrwx--- 1 root gpio 4096 Mar 27 21:51 uevent
-rwxrwx--- 1 root gpio 4096 Mar 27 21:51 value

Is this an issue that needs to be addressed?

Most helpful comment

This is a very annoying issue that requires ugly workarounds. It should not have been closed.

All 9 comments

I just edited the above post. Initially none of the occurrences of "echo 23 > /sys/class/gpio/unexport" were there. The unexport is only necessary to get the gpio back into its initial unexported state.

I get:

pi@raspberrypi:~ $ ls -l /sys/class/gpio/
total 0
--w------- 1 root root 4096 Mar 27 17:41 export
lrwxrwxrwx 1 root root    0 Mar 27 17:41 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
--w------- 1 root root 4096 Mar 27 17:41 unexport
pi@raspberrypi:~ $ echo 23 > /sys/class/gpio/unexport
-bash: /sys/class/gpio/unexport: Permission denied

which is what I'd expect. Only root has permission to access /sys/class/gpio/unexport so when pi tries to do this it correctly gets permission denied.

If I run "sudo su" first, then the command works as expected.

That's what I used to get on older versions or Raspbian, but on 2014-01-07-wheezy-raspbian I get:

pi@raspberrypi ~ $ ls -l /sys/class/gpio/
total 0
-rwxrwx--- 1 root gpio 4096 Mar 28 16:58 export
lrwxrwxrwx 1 root gpio    0 Jan  1  1970 gpiochip0 -> ../../devices/virtual/gpio/gpiochip0
-rwxrwx--- 1 root gpio 4096 Mar 28 17:01 unexport
pi@raspberrypi ~ $ echo 23 > /sys/class/gpio/export 
pi@raspberrypi ~ $ 

Everything works fine and there are no errors. Everyone in group gpio has permission to access /sys/class/gpio/export and pi is a member of group gpio.

pi@raspberrypi ~ $ groups pi
pi : pi adm dialout cdrom sudo audio video plugdev games users netdev input spi gpio

uname outputs the following:

pi@raspberrypi ~ $ uname -a
Linux raspberrypi 3.10.34+ #661 PREEMPT Thu Mar 27 00:36:02 GMT 2014 armv6l GNU/Linux

The behaviour changed as we're using some udev stuff from the piface folks. You're right that you have to wait for udev to change the permissions on the created device. This is a userspace thing so not really for this repo, but I'm not really sure there's a way to improve it.

does this work?

echo 23 > /sys/class/gpio/unexport; echo 23 > /sys/class/gpio/export; sleep 1; echo out > /sys/class/gpio/gpio23/direction

@asb Ok, thanks for the info. I think I'll change the code in onoff so that it waits for the permissions to change. The advantage is that applications using onoff can then avoid superuser issues.

@popcornmix yes, that works, thanks.

I can see value in extension of the GPIO permission process into user space, but this implementation
has corrupted the semantics of the kernel GPIO export operation. The write to /sys/class/gpio/export
should wait for the user space process to report it has completed its work before the write returns.

Work-around solutions that say users must wait some time for sysfs metadata to settle after an
export operation are very ugly because there is no correct period to wait. Work-around strategy that
looks for changes in metadata (e.g. group set to gpio) are inadequate because the purpose of the
user space permission process is flexibility - it might decide root is the proper group and no change
occurs.

The semantic change to kernel GPIO export operation is an obstacle to portable code, not only
between Raspberry Pi and other hardware platforms, but also between different Linux
distributions on Raspberry Pi.

Agreed. It's the kernel's responsibility to provide a working sysfs implementation, and Raspbian's implementation in clearly broken in an ugly way. I don't see how this issue can have been marked closed.

This is a very annoying issue that requires ugly workarounds. It should not have been closed.

Was this page helpful?
0 / 5 - 0 ratings