如何阻止 sem_open() 在 ENOSYS 中失败?

发布于 2024-07-08 04:15:36 字数 1966 浏览 14 评论 0原文

我有两个 Slackware Linux 系统,其中 POSIX 信号量 sem_open() 调用失败,errno 设置为 38。下面重现示例代码(该代码在 CentOS / RedHat 上运行良好)。

是否有任何内核或系统配置选项可能导致此问题? 其他建议?

有问题的系统是 Slackware 10.1.0 kernel 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so,但相同的代码可以在更旧的 RedHat 9 kernel 2.4.20 /lib/librt 上运行-2.3.2.so /lib/tls/libpthread-0.29.so。 (也适用于 CentOS 5 内核 2.6.18 /lib/librt-2.5.so /lib/i686/nosegneg/libpthread-2.5.so)。

man sem_open 提示此 errno 表示系统不支持 sem_open()

#define ENOSYS          38      /* Function not implemented */

sem_open() 用户空间位于我们动态链接的 librt 中,并且 librt 存在于受影响的系统上。

受影响的系统声称支持 POSIX 信号量:_POSIX_SEMAPHORES 为 true,并且 sysconf(_SC_SEMAPHORES) 证实了这一点。

谢谢, Kieran

编辑 1:我添加了有关正在使用的软件版本的更多详细信息,并删除了一些不相关的注释。

编辑2: /dev/shm 安装在好的系统上,而不安装在坏的系统上。 安装它不会改变受影响系统上的行为。 我认为 /dev/shm 也是必要的,但 sem_open() 在此之前就失败了,strace 支持这一点。

# /* 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);
 }
}

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);
 }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

扶醉桌前 2024-07-15 04:15:36

/dev/shm 是否已安装? 较旧版本的 slackware 可能未在启动时安装此文件系统。 来自 /etc/fstab:

tmpfs  /dev/shm  tmpfs  defaults  0   0

编辑:这可能根本不是问题。 我认为你可能只需要升级你的内核甚至 librt。

Edit2:我认为对于我认为您正在使用的 slackware 11,您需要一个比 2.6.13 更新的内核才能使用 NPTL 线程库(/lib/tls 中的库),这似乎是 sem_open 所必需的工作。

Edit3:我设法让它与我拥有的 slackware 11 盒子一起工作,方法是:a)安装 /dev/shm 和 b)将环境变量 LD_ASSUME_KERNEL 设置为 2.6.13(任何内核版本 > 2.6) .12 将起作用)。 即使内核是 2.6.11.11,这似乎也可以工作,但线程等其他东西可能不会。

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.

穿透光 2024-07-15 04:15:36

旧版本的线程库不支持在进程之间共享 POSIX 信号量。 来自man sem_init

pshared 参数指示信号量是否是本地信号量
当前进程( pshared 为零)或在多个进程之间共享
进程( pshared 不为零)。 LinuxThreads 目前没有
支持进程共享信号量,因此 sem_init 总是返回
如果 pshared 不为零,则错误 ENOSYS。

当 sem_open() 创建命名信号量时,它总是尝试在进程之间共享它们。

为了支持在 Slackware 10 上使用 sem_init() 在进程之间共享匿名信号量,

  • 请升级 libpthread 和(可能)librt
  • 升级内核

此外,为了支持使用 sem_open() 共享命名信号量

  • 将一行添加到 /etc/fstab< /code> 将 /dev/shm 挂载为 tmpfs

    tmpfs /dev/shm tmpfs defaults 0 0

  • 运行 mount /dev/shm 或重新启动

Older versions of the threading libraries don't support sharing POSIX semaphores between processes. From man sem_init

The pshared argument indicates whether the semaphore is local to the
current process ( pshared is zero) or is to be shared between several
processes ( pshared is not zero). LinuxThreads currently does not
support process-shared semaphores, thus sem_init always returns with
error ENOSYS if pshared is not zero.

As sem_open() creates named semaphores, it always tries to share them between processes.

To support sharing anonymous semaphores between processes with sem_init() on Slackware 10

  • upgrade libpthread and (possibly) librt
  • upgrade the kernel

Additionally, to support sharing named semaphores with sem_open()

  • add a line to /etc/fstab to mount /dev/shm as a tmpfs

    tmpfs /dev/shm tmpfs defaults 0 0

  • run mount /dev/shm or reboot

故人如初 2024-07-15 04:15:36

“进程共享 sema4 不起作用”的假设对我来说有一定道理。 并不是说它对您有帮助,但如果您有时间和意愿,您可能想尝试以下操作,看看“进程共享”方面是否失败:

  1. 在非共享内存中使用 sem_init 创建信号量(对于线程)。 如果它有效,则 sema4s 在进程内工作。

  2. 在共享内存中重复实验。 这应该告诉您它们是否在进程之间工作。 请注意,您可能需要实际尝试使用 sema4 来查看它是否在进程之间工作。

The "process shared sema4s don't work" hypothesis makes some sense to me. Not that it helps you, but if you have time and inclination you might want to try the following, to see whether the "process-shared" aspect is what is failing:

  1. create a semaphore using sem_init in unshared memory (for threads). If it works then sema4s work within the process.

  2. repeat experiment in shared memory. This should tell you if they work between processes. Note that you may need to actually try to USE the sema4 to see whether it works between processes.

从此见与不见 2024-07-15 04:15:36

跨进程共享信号量的另一种方法是使用 SystemV 信号量。

即使共享 POSIX 信号量不起作用(至少在上述系统上),它们也能起作用。

请参阅 http://www.linuxdevcenter .com/pub/a/linux/2007/05/24/semaphores-in-linux.html 有关两种类型信号量使用的示例。

Another way to share a semaphore across processes is to use SystemV semaphores.

These do work even where shared POSIX semaphores don't (at least on the systems described above.).

See http://www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html for examples of the two types of semaphore use.

等待圉鍢 2024-07-15 04:15:36

我正在使用 POSIX 消息队列,并且我遇到了同样的错误,mq_open 失败了错误 38 (ENOSYS)。

解决方法是在内核配置中启用 POSIX MESSAGE QUEUE 来重建内核。

这将构建具有 POSIX 消息队列支持的内核,它对我有用。

I was working with POSIX message queues, and I have got the same error, mq_open was failed with errono 38 (ENOSYS).

The workaround is to rebuild the kernel with POSIX MESSAGE QUEUE enabled in the kernel configuration.

This will build the kernel with POSIX message queue support and it worked for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文