Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best practice for locking serial ports and other devices in Linux?

The goal is to "lock" access to a serial device or other Linux device, to ensure exclusive access to the device while it's in-use. This prevents, for example, two programs both opening the same serial device and "competing" to read bytes from the device.

The advice has been to use SYSV-style UUCP device lock files such as /var/lock/LCK..ttyS1. That is what is recommended by Linux Serial HOTWO: Locking Out Others. It is also documented in the Filesystem Heirarchy Standard. It is implemented by serial terminal programs such as gtkterm, picocom. There are libraries such as liblockdev and liblockfile to support this (although the implementation details differ between these two libraries).

However, I have found Debian bug #734086, which says on Linux, SYSV-style UUCP device locks are deprecated, and flock() advisory locks should be used instead.

However, I can't find a reliable document source to describe deprecation of these SYSV-style UUCP device locks, and recommendation of flock(), other than that Debian bug itself.

I've also found ioctl(fd, TIOCEXCL) which is used by the screen utility to lock a terminal.

Which is the modern "best practice" for locking serial ports and other devices in Linux? Where can we find up-to-date documentation describing this?

like image 822
Craig McQueen Avatar asked May 19 '15 04:05

Craig McQueen


1 Answers

As far as I can tell, using flock(fd, LOCK_EX | LOCK_NB) locking of serial ports or other devices is probably the best the way to go in Linux, following Debian's lead in Debian bug #734086. Note that the original advocate of this Debian change, Roger Leigh, has moved away from Debian and Linux and onto FreeBSD in 2014/2015 (see his comments here). But Debian seems to be sticking with the flock() method, so that's worth something.

However given how poorly this change has been communicated to the broader Linux community at this point, it could be good to support the older SYSV-style UUCP device lock files (/var/lock/LCK..ttyS1) as a compile-time option, for use in systems still using the older lock method.

E.g. picocom has now changed to using the flock() method, with a compile-time optional selection of SYSV-style UUCP device lock files.

Another answer on StackOverflow describes two methods:

  1. ioctl(fd, TIOCEXCL)
  2. the flock(fd, LOCK_EX | LOCK_NB) method

It says "An application can choose to do one, or both", further explaining:

The reason to use both, is to detect if another process has already opened the device without putting it into exclusive mode, but has hopefully set the advisory lock. In that case, the open() and ioctl() both succeed, but the flock() fails.

So, it is worth implementing ioctl(fd, TIOCEXCL) additionally.

like image 75
Craig McQueen Avatar answered Oct 09 '22 03:10

Craig McQueen