Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
817 views
in Technique[技术] by (71.8m points)

c - How do I stop sem_open() failing with ENOSYS?

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
", _POSIX_SEMAPHORES);
#else
  puts("Undefined");
#endif

 printf("sysconf %s
", sysconf(_SC_SEMAPHORES) ? "Yes" : "No" );

 mutex = sem_open(SEM_NAME, O_CREAT, 0666, 1);

 if (mutex == SEM_FAILED) printf("Failed %d
", errno);
 else {
        puts("Success - pause while you check /dev/shm ");
        sleep(5);
        sem_close(mutex);
        sem_unlink(SEM_NAME);
 }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...