Como faço para parar de sem_open () falha com ENOSYS?
Pergunta
Eu tenho dois sistemas Slackware Linux em que o POSIX semáforos chamada sem_open()
falha com errno definido para 38. O código de exemplo para reproduzir abaixo (o código funciona bem no CentOS / RedHat).
Existem opções de configuração do kernel ou sistema que poderiam causar isso? Outras sugestões?
Sistemas com problema são Slackware 10.1.0 do kernel 2.6.11 /lib/librt-2.3.4.so /lib/libpthread-0.10.so, mas as mesmas obras de código na muito mais velho RedHat 9 do kernel 2.4.20 / lib / librt-2.3.2.so /lib/tls/libpthread-0.29.so. (E também funciona em CentOS 5 do kernel 2.6.18 /lib/librt-2.5.so /lib/i686/nosegneg/libpthread-2.5.so).
man sem_open
sugere que este meio errno sem_open()
não é suportada pelo sistema.
#define ENOSYS 38 /* Function not implemented */
O userspace sem_open()
está em librt
que ligar contra dinamicamente e librt
está presente nos sistemas afetados.
As afirmações sistema afetado para apoiar semáforos POSIX:. _POSIX_SEMAPHORES
é verdadeiro e sysconf(_SC_SEMAPHORES)
confirma esta ??p>
Obrigado, Kieran
Editar 1:. Eu adicionei mais detalhes sobre as versões de software em uso e removido alguns comentários irrelevantes
Edit 2: / dev / shm é montado sobre os sistemas bons e não montados nos sistemas ruins. Montagem não alterar o comportamento nos sistemas afetados. Eu acho que / dev / shm é necessário também, mas sem_open () está a falhar antes disso, e strace suporta isso.
# /* 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);
}
}
Solução
é / dev / shm montou? Versões mais antigas do slackware pode não ter montado este sistema de arquivos durante a inicialização. De / etc / fstab:
tmpfs /dev/shm tmpfs defaults 0 0
Edit: Isso provavelmente não é o problema, afinal. Eu acho que você pode apenas precisa atualizar o seu kernel ou talvez até mesmo librt.
Edit2: Eu acho que para slackware 11, que eu acho que você está usando, você vai precisar de um kernel mais recente que 2.6.13 usar as bibliotecas NPTL segmentação (libs em / lib / TLS), que parecem ser necessários para o sem_open ao trabalho.
Edit3: Eu consegui-lo para trabalhar com uma caixa de slackware 11 Tenho por um) de montagem / dev / shm e b) definir a variável de ambiente LD_ASSUME_KERNEL
a 2.6.13 (qualquer versão do kernel> 2.6.12 trabalho vontade) . Que parece funcionar mesmo que o kernel é 2.6.11.11, mas outras coisas como tópicos talvez não.
Outras dicas
As versões mais antigas das bibliotecas de threading não suportam o compartilhamento semáforos POSIX entre processos. De man sem_init
O argumento pshared indica se o semáforo é local para o processo atual (pshared é zero) ou é para ser compartilhado entre vários processos (pshared não é zero). LinuxThreads atualmente não apoio semáforos compartilhada de processo, assim sem_init sempre retorna com ENOSYS erro se pshared não é zero.
Como sem_open () cria nomeado semáforos, ele sempre tenta compartilhá-los entre processos.
Para apoiar a partilha de semáforos anônimos entre processos com sem_init () no Slackware 10
- libpthread atualização e (possivelmente) librt
- atualizar o kernel
Além disso, para apoiar a partilha de semáforos nomeados com sem_open ()
-
adicionar uma linha para
/etc/fstab
para montar/dev/shm
como tmpfstmpfs / dev / shm tmpfs defaults 0 0
-
mount /dev/shm
ou reiniciar executar
O "processo compartilhado sema4s não funcionam" hipótese faz algum sentido para mim. Não que ele ajuda você, mas se você tiver tempo e disposição que você pode querer tentar o seguinte, para ver se o "processo-compartilhada" aspecto é o que está a falhar:
-
criar um semáforo usando sem_init na memória não compartilhada (para threads). Se funcionar trabalho, então sema4s dentro do processo.
-
experimento repita na memória compartilhada. Isso deve dizer se eles trabalham entre processos. Note que você pode precisar para realmente tentar usar o sema4 para ver se ele funciona entre processos.
Outra maneira de compartilhar um semáforo entre processos é a utilização de semáforos SystemV.
Estes trabalhos sequer onde semáforos POSIX compartilhados não (pelo menos nos sistemas descritos acima.).
Consulte http: // www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html para exemplos dos dois tipos de uso semáforo.
Eu estava trabalhando com filas de mensagens POSIX i têm os mesmos mq_open erro foi falhadas com errono 38 (ENOSYS).
O espalhados trabalho é reconstruir o kenel com POSIX Messge FILA habilitado na configuração do kernel.
Isto irá construir o kernel com suporte a fila de mensagens POSIX e funcionou para mim.
Graças