Tuesday, February 10, 2009

linux: key for sem_open/shm_open

sem_open and shm_open are used to associate key with system semaphore and shared memory object accordingly.
I used them without any problems with a key randomly generated until I started to fail to receive valid object descriptors with ENOENT("No such file or directory").
According to man pages ENOENT could happen if there was an attempt to open an object with a name that did not exist, and O_CREAT was not specified.
I wondered why that could happen because I used O_CREAT and if even object didn't exist with given name it should be created.
I remember that in linux named semaphores and shared data objects are being created in a virtual filesystem usually mounted under /dev/shm.
I started to analyze the key I used to generate.
The problem was that in the name I've generated could appear slash characters and characters not conforming to filesystem valid file name. That caused failure of creating inode on the filesystem and sem_open and shm_open failed also.

To summarize the key for sem_open and shm_open should have leading slash and contain no other slashes or non-valid characters of file name on filesystem. This is of course implementation-defined but for portability this rule should be used to generate the key.

Some notes for FreeBSD.
sem_open is known to be buggy in FreeBSD. The name of semaphore shouldn't be longer than 13 characters.
shm_open behaves differently in FreeBSD than in Linux. path argument should be valid pathname within filesystem. shm_open is a wrapper over open libc call. So the best solution to generate path with tmpnam from libc to make it unique or to prefix with '/tmp/' for other cases to ensure that this file won't be lost somewhere in the filesystem. shm_unlink should remove it but in case of application crush it could not happen.

No comments: