fopen () falha ao abrir um arquivo no compartilhamento / tmp

1

Eu tenho um aplicativo C que ocasionalmente falha ao abrir um arquivo armazenado em /tmp share.

Aqui está a parte relevante do código:

  // open file and start parsing

  notStdin = strcmp(inFile, "-");
  if (notStdin) {
     coordsIn = fopen(inFile, "r");   <----- inFile = file that I want to open
     if (coordsIn == NULL) {
        fprintf(stderr, "ERROR: Could not open coordinates file: %s\n\t%s\n", inFile, strerror(errno));
        exit(EXIT_FAILURE);
     }
  }
  else
     coordsIn = stdin;

Uma vez entre oito e dez tentativas, recebo um ponteiro NULL FILE. Aqui está uma mensagem de erro de exemplo:

ERROR: Could not open coordinates file: /tmp/coordinates.txt
       File or directory does not exist

No entanto, o arquivo /tmp/coordinates.txt realmente existe, pois eu posso abri-lo com utilitários padrão como head , cat ou more , etc.

As permissões de diferentes arquivos /tmp/coordinates.txt trial são as mesmas.

Aqui está o resultado de uname -a :

$ uname -a
Linux hostname 2.6.18-128.2.1.el5 #1 SMP Wed Jul 8 11:54:47 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux

Se eu usar um inFile diferente armazenado em um compartilhamento diferente, não /tmp , não observarei esse sintoma.

Existe alguma coisa que faça com que fopen() falhe em um arquivo armazenado no /tmp share? Existem outras etapas de solução de problemas que posso seguir?

    
por Alex Reynolds 06.08.2009 / 12:09

5 respostas

5

Muitos arquivos abertos?
Seu programa está abrindo lotes de arquivos? Talvez você esteja ficando sem descritores de arquivos? Aqui está um link sobre como alterar seu programa, o shell e o sistema operacional se é o caso. Para ver muitos dos que você está usando com o seu programa:

sudo lsof | grep <PID> | wc -l

No meu sistema Ubuntu, o limite do shell é 1024, incluindo stdout, stderr e stdin. Isso está definido em /etc/security/limits.conf. O pequeno programa a seguir mostra isso:

#include <stdio.h>

int count=0;

int main( void ) {
    while(1) {
        FILE *fd = fopen("foo", "r");
        if ( fd == NULL) {
            printf("%i\n", count);
            return(1);
        }
        count++;
    }
    return(0);
}

Quando eu executo, ele imprime "1021" com um status de saída de 1.

Verifique os erros do sistema:
Mais genericamente, você sempre pode verificar a saída do dmesg ou / var / log / messages em busca de erros.

Assista ao arquivo, veja se alguma coisa está mexendo com ele:
Talvez o arquivo não exista, algo está excluindo debaixo de você? Você pode querer usar o inotify para assistir a todos os eventos no arquivo, ou ferramentas que usam inotify, como incron ou inotify-tools .

    
por 06.08.2009 / 12:32
0

Talvez algum programa esteja bloqueando esse arquivo? Pode ser outra cópia do seu programa.

O lsof /tmp/coordinates.txt mostra alguma coisa?

    
por 06.08.2009 / 13:21
0

Não consigo pensar em nada de especial com / tmp, o que deve fazer com que os arquivos não estejam lá intermitentemente. / tmp é apenas um diretório regular com permissões um pouco especiais, permitindo que todo mundo mexa, mas limita os usuários não-root a não possuir arquivos para excluí-los.

Existe algo externo ao seu programa modificando / alterando esse arquivo, ou o seu programa é multi-threaded e trabalha com esse arquivo? Se assim for, pode ser uma condição de corrida.

Para verificar se esse é o caso, você pode usar o inotify, como Kyle sugere (provavelmente você está após a exclusão e foi movido dos eventos) para ver exatamente o que acontece com o arquivo.

Alternativamente, você pode tentar estatizar o arquivo e ver se ele é ctime e / ou mtimes coincide com quando fopen falhou com ENOENT.

    
por 06.08.2009 / 15:10
0

Vim?

Apenas um palpite. Você tem o arquivo /tmp/coordinates.txt aberto no vim enquanto este problema ocorre?

Eu tive problemas com o arquivo que estou editando no vim desaparecendo do sistema de arquivos e reaparecendo pouco tempo depois. Eu nunca vi o arquivo faltando com o ls, mas eu tive O gcc falha ao tentar abrir o arquivo, apenas para ter sucesso na segunda tentativa.

Isso não é muito raramente um artefato, acontece regularmente durante o dia.

    
por 06.08.2009 / 16:08
0

Não sei qual é a solução, mas sei que observei esse mesmo problema e não apenas em / tmp. Isso pode acontecer em montagens NFS e até em montagens locais, como / lib. Um problema que encontrei hoje reproduz isso (incorretamente) abrindo, procurando, lendo um pouco e fechando o mesmo arquivo milhares de vezes (ao invés de apenas manter o arquivo aberto para toda a operação). Esporadicamente, um dos fopen () falharia com um erro ENOENT. Isso não é muitos arquivos abertos como uma pessoa sugeriu - ele literalmente acha que o arquivo não está lá por uma fração de segundo.

Eu tenho procurado para ver se alguém teve problemas semelhantes, e isso é o mais próximo que eu cheguei. Eu não tenho nenhuma resposta, apenas procurando uma solução.

Eu não acho que isso é endêmico para o Linux (ou RHEL), porque eu não vejo isso em todo lugar, apenas em um ambiente. Eu não sei o que é diferente sobre esse ambiente que poderia causar esse problema (existem diferenças). Embora não seja bom ver que o que quer que seja não está corrigido no RHEL5 (eu vejo isso no RHEL4).

    
por 08.07.2010 / 23:17

Tags