Pregunta

Tengo dos sistemas Slackware Linux en los que la llamada del semáforo POSIX sem_open () falla con errno configurado en 38. Código de muestra para reproducir a continuación (el código funciona bien en CentOS / RedHat).

¿Hay alguna opción de configuración del núcleo o del sistema que pueda causar esto? ¿Otras sugerencias?

Los sistemas con problemas son Slackware 10.1.0 kernel 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so, pero el mismo código funciona en el kernel RedHat 9 mucho más antiguo 2.4.20 / lib / librt-2.3.2.so /lib/tls/libpthread-0.29.so. (y también funciona en el núcleo CentOS 5 2.6.18 /lib/librt-2.5.so /lib/i686/nosegneg/libpthread-2.5.so).

man sem_open sugiere que este error significa que sem_open () no es compatible con el sistema.

#define ENOSYS          38      /* Function not implemented */

El espacio de usuario sem_open () está en librt que vinculamos dinámicamente y librt está presente en los sistemas afectados.

El sistema afectado afirma que admite semáforos POSIX: _POSIX_SEMAPHORES es verdadero y sysconf (_SC_SEMAPHORES) lo confirma.

Gracias Kieran

Edición 1: agregué más detalles sobre las versiones de software en uso y eliminé algunos comentarios irrelevantes.

Edición 2: / dev / shm está montado en los sistemas buenos y no está montado en los sistemas malos. Montarlo no cambió el comportamiento en los sistemas afectados. Creo que / dev / shm también es necesario, pero sem_open () falla antes de eso, y strace lo admite.

# /* Quick'n'dirty test program to illustrate sem_open failure
#Run this file to auto-build test and run as a.out

# Build
gcc <*> -lrt
if [ $? -ne 0 ] ; then exit ; fi

# Run
$( dirname <*>)/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);
 }
}
¿Fue útil?

Solución

¿Está montado / dev / shm? Las versiones anteriores de slackware pueden no haber montado este sistema de archivos en el arranque. Desde / etc / fstab:

tmpfs  /dev/shm  tmpfs  defaults  0   0

Editar: Probablemente ese no sea el problema después de todo. Creo que es posible que solo necesite actualizar su núcleo o tal vez incluso librt.

Edit2: creo que para slackware 11, que creo que está utilizando, necesitará un kernel más reciente que 2.6.13 para usar las bibliotecas de subprocesos NPTL (libs en / lib / tls) que parecen ser necesarias para el sem_open para trabajar.

Edit3: logré que funcione con un cuadro de slackware 11 que tengo a) montando / dev / shm yb) configurando la variable de entorno LD_ASSUME_KERNEL a 2.6.13 (cualquier versión de kernel > 2.6.12 funcionará). Eso parece funcionar a pesar de que el núcleo es 2.6.11.11, pero otras cosas como los hilos podrían no funcionar.

Otros consejos

Las versiones anteriores de las bibliotecas de subprocesos no admiten compartir semáforos POSIX entre procesos. Desde man sem_init

  

El argumento pshared indica si el semáforo es local para el   proceso actual (pshared es cero) o se debe compartir entre varios   procesos (pshared no es cero). LinuxThreads actualmente no   admite semáforos compartidos en el proceso, por lo que sem_init siempre regresa con   error ENOSYS si pshared no es cero.

Como sem_open () crea semáforos con nombre, siempre trata de compartirlos entre procesos.

Para permitir compartir semáforos anónimos entre procesos con sem_init () en Slackware 10

  • actualizar libpthread y (posiblemente) librt
  • actualizar el núcleo

Además, para admitir el uso compartido de semáforos con nombre con sem_open ()

  • agregue una línea a / etc / fstab para montar / dev / shm como tmpfs

    tmpfs / dev / shm tmpfs predeterminado 0 0

  • ejecuta mount / dev / shm o reinicia

El " proceso compartido sema4s no funciona " La hipótesis tiene algún sentido para mí. No es que te ayude, pero si tienes tiempo e inclinación, quizás quieras probar lo siguiente, para ver si el "proceso compartido" aspecto es lo que está fallando:

  1. crea un semáforo usando sem_init en la memoria no compartida (para hilos). Si funciona, sema4s funciona dentro del proceso.

  2. repite el experimento en la memoria compartida. Esto debería decirle si funcionan entre procesos. Tenga en cuenta que es posible que deba intentar utilizar el sema4 para ver si funciona entre procesos.

Otra forma de compartir un semáforo entre procesos es utilizar los semáforos de SystemV.

Estos funcionan incluso donde los semáforos POSIX compartidos no lo hacen (al menos en los sistemas descritos anteriormente).

Ver http: // www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html para ver ejemplos de los dos tipos de uso de semáforos.

Estaba trabajando con las colas de mensajes posix. Recibí el mismo error. mq_open falló con errono 38 (ENOSYS).

El trabajo en torno es reconstruir el núcleo con POSIX MESSGE QUEUE habilitado en la configuración del núcleo.

Esto construirá el núcleo con soporte de cola de mensajes POSIX y funcionó para mí.

Gracias

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top