Как мне остановить sem_open () с ошибкой в ​​ENOSYS? - PullRequest
3 голосов
/ 06 ноября 2008

У меня есть две системы Slackware Linux, в которых сбой вызова семафора POSIX sem_open() с ошибкой, равной 38. Пример кода для воспроизведения ниже (код отлично работает на CentOS / RedHat).

Существуют ли какие-либо параметры конфигурации ядра или системы, которые могут вызвать это? Другие предложения?

Проблемными системами являются ядро ​​Slackware 10.1.0 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so, но тот же код работает на гораздо более старом ядре RedHat 9 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) подтверждает это.

Спасибо, Киран

Редактировать 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);
 }
}

Ответы [ 5 ]

5 голосов
/ 07 ноября 2008

Установлен ли / dev / shm? Старые версии slackware, возможно, не монтировали эту файловую систему при загрузке. Из / etc / fstab:

tmpfs  /dev/shm  tmpfs  defaults  0   0

Edit: Это, вероятно, не проблема в конце концов. Я думаю, вам может понадобиться обновить ядро ​​или даже librt.

Edit2: я думаю, что для slackware 11, который, я думаю, вы используете, вам понадобится ядро ​​новее, чем 2.6.13, чтобы использовать библиотеки потоков NPTL (libs в / lib / tls), которые, по-видимому, необходимы для sem_open для работы.

Edit3: мне удалось заставить его работать с Slackware 11, который у меня есть: а) монтировать / dev / shm и б) установить переменную окружения LD_ASSUME_KERNEL в 2.6.13 (любая версия ядра> 2.6.12 будет Работа). Кажется, это работает, хотя ядро ​​2.6.11.11, но другие вещи, такие как потоки, могут не работать.

1 голос
/ 07 ноября 2008

Гипотеза «процесс совместно используемый sema4s не работает» имеет некоторый смысл для меня. Не то чтобы это помогло вам, но если у вас есть время и желание, вы можете попробовать следующее, чтобы увидеть, является ли аспект «совместного использования процесса» неудачным:

  1. создать семафор, используя sem_init в неразделенной памяти (для потоков). Если это работает, тогда sema4s работает внутри процесса.

  2. повторить эксперимент в общей памяти. Это должно сказать вам, если они работают между процессами. Обратите внимание, что вам, возможно, придется на самом деле попытаться использовать sema4, чтобы проверить, работает ли он между процессами.

1 голос
/ 07 ноября 2008

Старые версии потоковых библиотек не поддерживают совместное использование семафоров POSIX между процессами. От man sem_init

Аргумент pshared указывает, является ли семафор локальным по отношению к текущий процесс (pshared равен нулю) или должен быть разделен между несколькими процессы (pshared не ноль). LinuxThreads в настоящее время не поддержка семафоров, совместно используемых процессом, поэтому sem_init всегда возвращается с ошибка ENOSYS, если pshared не равен нулю.

Поскольку sem_open () создает именованные семафоры, он всегда пытается разделить их между процессами.

Для поддержки совместного использования анонимных семафоров между процессами с помощью sem_init () в Slackware 10

  • обновить libpthread и (возможно) librt
  • обновить ядро ​​

Кроме того, для поддержки совместного использования именованных семафоров с помощью sem_open ()

  • добавить строку в /etc/fstab для монтирования /dev/shm как tmpfs

    tmpfs / dev / shm tmpfs по умолчанию 0 0

  • запустить mount /dev/shm или перезагрузить

0 голосов
/ 19 мая 2010

Я работал с очередями сообщений posix. Я получил ту же ошибку. Ошибка mq_open в errono 38 (ENOSYS).

Задача состоит в том, чтобы перестроить кенел с включенной POSIX MESSGE QUEUE в конфигурации ядра.

Это создаст ядро ​​с поддержкой очереди сообщений POSIX, и это сработало для меня.

Спасибо

0 голосов
/ 07 ноября 2008

Другим способом совместного использования семафора между процессами является использование семафоров SystemV.

Они работают даже там, где общие семафоры POSIX не работают (по крайней мере, в системах, описанных выше.).

См. http://www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html для примеров двух типов использования семафоров.

...