Question

J'ai deux systèmes Linux Slackware sur lesquels l'appel du sémaphore POSIX sem_open () échoue avec errno défini sur 38. Le code à reproduire ci-dessous (le code fonctionne correctement sous CentOS / RedHat).

Existe-t-il des options de configuration du noyau ou du système qui pourraient en être la cause? Autres suggestions?

Les systèmes en cause sont le noyau Slackware 10.1.0 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so, mais le même code fonctionne sur le noyau plus ancien RedHat 9 2.4.20 / lib / librt-2.3.2.so /lib/tls/libpthread-0.29.so. (et fonctionne également sur les noyaux CentOS 5 2.6.18 /lib/librt-2.5.so /lib/i686/nosegneg/libpthread-2.5.so).

man sem_open suggère que cette erreur signifie que sem_open () n'est pas pris en charge par le système.

#define ENOSYS          38      /* Function not implemented */

L'espace utilisateur sem_open () se trouve dans librt auquel nous lions de manière dynamique et librt est présent sur les systèmes affectés.

Le système affecté prétend prendre en charge les sémaphores POSIX: _POSIX_SEMAPHORES est true et sysconf (_SC_SEMAPHORES) le confirme.

Merci, Kieran

Éditer 1: j'ai ajouté plus de détails sur les versions du logiciel en cours d'utilisation et j'ai supprimé certains commentaires inutiles.

Éditer 2: / dev / shm est monté sur les bons systèmes et non sur les mauvais. Le monter ne change pas le comportement sur les systèmes affectés. Je pense que / dev / shm est nécessaire aussi, mais sem_open () échoue avant cela, et strace le supporte.

# /* 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);
 }
}
Était-ce utile?

La solution

Est-ce que / dev / shm est monté? Les anciennes versions de slackware n'ont peut-être pas monté ce système de fichiers au démarrage. Depuis / etc / fstab:

tmpfs  /dev/shm  tmpfs  defaults  0   0

Edit: Ce n’est probablement pas le problème après tout. Je pense que vous devrez peut-être simplement mettre à niveau votre noyau ou peut-être même votre bibliothèque.

Edit2: Je pense que pour slackware 11, que vous utilisez, vous aurez besoin d’un noyau plus récent que 2.6.13 pour utiliser les bibliothèques de threading NPTL (libs dans / lib / tls) qui semblent être nécessaires à le sem_open au travail.

Edit3: J'ai réussi à le faire fonctionner avec un slackware 11 que j'ai a) en montant) / dev / shm et b) en définissant la variable d'environnement LD_ASSUME_KERNEL sur 2.6.13 (toute version du noyau > 2.6.12 fonctionnera). Cela semble fonctionner même si le noyau est 2.6.11.11, mais d'autres choses, comme les threads, pourraient ne pas l'être.

Autres conseils

Les anciennes versions des bibliothèques de threads ne prennent pas en charge le partage de sémaphores POSIX entre processus. De man sem_init

  

L'argument pshared indique si le sémaphore est local au   processus en cours (pshared est zéro) ou doit être partagé entre plusieurs   processus (pshared n’est pas nul). LinuxThreads n'est actuellement pas   supporte les sémaphores partagés par le processus, ainsi sem_init revient toujours avec   erreur ENOSYS si pshared n’est pas nul.

Comme sem_open () crée des sémaphores nommés, il essaie toujours de les partager entre processus.

Pour prendre en charge le partage de sémaphores anonymes entre processus avec sem_init () sur Slackware 10

  • met à jour libpthread et (éventuellement) librt
  • mettre à jour le noyau

De plus, pour prendre en charge le partage de sémaphores nommés avec sem_open ()

  • ajoutez une ligne à / etc / fstab pour monter / dev / shm en tant que tmpfs

    tmpfs / dev / shm tmpfs par défaut 0 0

  • exécuter mount / dev / shm ou redémarrer

Le "processus de traitement des sema4 partagés ne fonctionne pas" l'hypothèse a du sens pour moi. Ce n’est pas que cela vous aide, mais si vous avez le temps et l’envie, essayez d’essayer ce qui suit pour voir si le " processus-partagé " aspect est ce qui échoue:

  1. créez un sémaphore en utilisant sem_init dans la mémoire non partagée (pour les threads). Si cela fonctionne, sema4s fonctionne dans le processus.

  2. répéter l'expérience dans la mémoire partagée. Cela devrait vous dire s'ils fonctionnent entre les processus. Notez que vous devrez peut-être réellement utiliser la sema4 pour voir si elle fonctionne entre les processus.

Un autre moyen de partager un sémaphore entre plusieurs processus consiste à utiliser des sémaphores SystemV.

Ils fonctionnent même là où les sémaphores POSIX partagés ne fonctionnent pas (du moins sur les systèmes décrits ci-dessus).

Voir http: // www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html pour des exemples d'utilisation des deux types de sémaphores.

Je travaillais avec des files de messages posix. La même erreur mq_open a échoué avec erreur 38 (ENOSYS).

Le travail consiste à reconstruire le kenel avec POSIX MESSGE QUEUE activé dans la configuration du noyau.

Ceci construira le noyau avec le support de la file d’attente de messages POSIX et cela a fonctionné pour moi.

Merci

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top