Domanda

Ho due sistemi Slackware Linux su cui la chiamata del semaforo POSIX sem_open () non riesce con errno impostato su 38. Codice di esempio da riprodurre di seguito (il codice funziona bene su CentOS / RedHat).

Esistono opzioni di configurazione del kernel o del sistema che potrebbero causare questo? Altri suggerimenti?

I sistemi con problemi sono il kernel Slackware 10.1.0 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so, ma lo stesso codice funziona sul kernel RedHat 9 molto vecchio 2.4.20 / lib / librt-2.3.2.so /lib/tls/libpthread-0.29.so. (e funziona anche con il kernel 2.6.18 di CentOS 5 /lib/librt-2.5.so /lib/i686/nosegneg/libpthread-2.5.so).

man sem_open suggerisce che questo errore significa che sem_open () non è supportato dal sistema.

#define ENOSYS          38      /* Function not implemented */

Lo spazio utente sem_open () è in librt che colleghiamo dinamicamente e librt è presente sui sistemi interessati.

Il sistema interessato afferma di supportare i semafori POSIX: _POSIX_SEMAPHORES è vero e sysconf (_SC_SEMAPHORES) lo conferma.

Grazie, Kieran

Modifica 1: ho aggiunto maggiori dettagli sulle versioni del software in uso e rimosso alcuni commenti irrilevanti.

Modifica 2: / dev / shm è montato sui sistemi buoni e non sui sistemi cattivi. Il montaggio non ha modificato il comportamento sui sistemi interessati. Penso che anche / dev / shm sia necessario ma sem_open () non riesce prima, e strace lo supporta.

# /* 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);
 }
}
È stato utile?

Soluzione

/ dev / shm è montato? Versioni precedenti di slackware potrebbero non aver montato questo filesystem all'avvio. Da / etc / fstab:

tmpfs  /dev/shm  tmpfs  defaults  0   0

Modifica: probabilmente non è questo il problema. Penso che potresti aver solo bisogno di aggiornare il tuo kernel o magari anche di librt.

Edit2: Penso che per lo slackware 11, che penso tu stia usando, avrai bisogno di un kernel più recente della 2.6.13 per usare le librerie di threading NPTL (libs in / lib / tls) che sembrano essere richieste per sem_open per funzionare.

Edit3: sono riuscito a farlo funzionare con una slackware 11 box che ho a) montaggio / dev / shm eb) impostando la variabile di ambiente LD_ASSUME_KERNEL su 2.6.13 (qualsiasi versione del kernel > 2.6.12 funzionerà). Sembra funzionare anche se il kernel è 2.6.11.11, ma altre cose come i thread potrebbero non funzionare.

Altri suggerimenti

Le versioni precedenti delle librerie di threading non supportano la condivisione di semafori POSIX tra processi. Da man sem_init

  

L'argomento pshared indica se il semaforo è locale per il   processo corrente (pshared è zero) o deve essere condiviso tra più   processi (pshared non è zero). LinuxThreads attualmente no   supporta i semafori condivisi dal processo, quindi sem_init restituisce sempre con   errore ENOSYS se pshared non è zero.

Mentre sem_open () crea semafori nominati, cerca sempre di condividerli tra processi.

Supportare la condivisione di semafori anonimi tra processi con sem_init () su Slackware 10

  • aggiorna libpthread e (possibilmente) librt
  • aggiorna il kernel

Inoltre, per supportare la condivisione di semafori denominati con sem_open ()

  • aggiungi una linea a / etc / fstab per montare / dev / shm come tmpfs

    tmpfs / dev / shm tmpfs predefinito 0 0

  • esegui mount / dev / shm o riavvia

Il processo "sema4s condiviso non funziona" l'ipotesi ha un senso per me. Non che ti aiuti, ma se hai tempo e inclinazione potresti voler provare quanto segue, per vedere se il "processo condiviso" " l'aspetto è ciò che sta fallendo:

  1. crea un semaforo usando sem_init nella memoria non condivisa (per i thread). Se funziona, allora i sema4 funzionano all'interno del processo.

  2. ripeti l'esperimento nella memoria condivisa. Questo dovrebbe dirti se funzionano tra i processi. Si noti che potrebbe essere necessario provare effettivamente a USARE sema4 per vedere se funziona tra i processi.

Un altro modo per condividere un semaforo tra processi è usare i semafori SystemV.

Funzionano anche dove i semafori POSIX condivisi non lo fanno (almeno sui sistemi sopra descritti).

Vedi http: // www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html per esempi dei due tipi di utilizzo dei semafori.

Stavo lavorando con le code dei messaggi posix ho avuto lo stesso errore mq_open non è riuscito con errono 38 (ENOSYS).

Lo scopo principale è ricostruire il kenel con POSIX MESSGE QUEUE abilitato nella configurazione del kernel.

Questo genererà il kernel con il supporto per la coda dei messaggi POSIX e ha funzionato per me.

Grazie

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top