How do I stop sem_open() failing with ENOSYS?
c, ipc, linux, posix, semaphore
Solution
Is /dev/shm mounted? Older versions of slackware may not have mounted this filesystem at boot. From /etc/fstab:
tmpfs /dev/shm tmpfs defaults 0 0
Edit: That is probably not the problem after all. I think you may just need to upgrade your kernel or maybe even librt.
Edit2: I think that for slackware 11, which I think you are using, you'll need a kernel newer than 2.6.13 to use the NPTL threading libraries (libs in /lib/tls) which appear to be required for the sem_open to work.
Edit3: I managed to get it to work with a slackware 11 box I have by a) mounting /dev/shm and b) setting the environment variable `LD_ASSUME_KERNEL` to 2.6.13 (any kernel version > 2.6.12 will work). That seems to work even though the kernel is 2.6.11.11, but other things like threads might not.
Problem
I have two Slackware Linux systems on which the POSIX semaphore `sem_open()` call fails with errno set to 38. Sample code to reproduce below (the code works fine on CentOS / RedHat). Are there any kernel or system configuration options that could cause this? Other suggestions? Systems with issue are Slackware 10.1.0 kernel 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so, but the same code works on the much older RedHat 9 kernel 2.4.20 /lib/librt-2.3.2.so /lib/tls/libpthread-0.29.so. (and also works on CentOS 5 kernel 2.6.18 /lib/librt-2.5.so /lib/i686/nosegneg/libpthread-2.5.so). `man sem_open` suggests this errno means `sem_open()` is not supported by system. ``` #define ENOSYS 38 /* Function not implemented */ ``` The `sem_open()` userspace is in `librt` which we link against dynamically and `librt` is present on the affected systems. The affected system claims to support POSIX semaphores: `_POSIX_SEMAPHORES` is true and `sysconf(_SC_SEMAPHORES)` confirms this. Thanks, Kieran Edit 1: I've added more detail on the software versions in use and removed some irrelevant comments. Edit 2: /dev/shm is mounted on the good systems and not mounted on the bad systems. Mounting it did not change the behaviour on the affected systems. I think /dev/shm is necessary too but sem_open() is failing before that, and strace supports this. ``` # /* Quick'n'dirty test program to illustrate sem_open failure #Run this file to auto-build test and run as a.out # Build gcc $0 -lrt if [ $? -ne 0 ] ; then exit ; fi # Run $( dirname $0)/a.out exit */ #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #include <semaphore.h> int main(int argc, char *argv[]) { const char *SEM_NAME = "SHRMEM_SCXL"; /* name of mutex */ sem_t *mutex = SEM_FAILED; /* ptr to mutex */ #ifdef _POSIX_SEMAPHORES printf("_POSIX_SEMAPHORES %ld\n", _POSIX_SEMAPHORES); #else puts("Undefined"); #endif printf("sysconf %s\n", sysconf(_SC_SEMAPHORES) ? "Yes" : "No" ); mutex = sem_open(SEM_NAME, O_CREAT, 0666, 1); if (mutex == SEM_FAILED) printf("Failed %d\n", errno); else { puts("Success - pause while you check /dev/shm "); sleep(5); sem_close(mutex); sem_unlink(SEM_NAME); } } ```