Вопрос

У меня есть две системы 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 является правдой и 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);
 }
}
Это было полезно?

Решение

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

tmpfs  /dev/shm  tmpfs  defaults  0   0

Редактировать:Вероятно, в конце концов, проблема не в этом.Я думаю, вам, возможно, просто нужно обновить ваше ядро или, возможно, даже librt.

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

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

Другие советы

Более старые версии библиотек потоков не поддерживают совместное использование семафоров 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 или перезагрузите компьютер

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

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

  2. повторите эксперимент в общей памяти.Это должно сказать вам, работают ли они между процессами.Обратите внимание, что вам, возможно, придется попробовать ИСПОЛЬЗОВАТЬ sema4, чтобы увидеть, работает ли он между процессами.

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

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

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

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

Задача состоит в том, чтобы перестроить kenel с включенной в конфигурации ядра ОЧЕРЕДЬЮ СООБЩЕНИЙ POSIX.

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

Спасибо

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top