Re: Comportement mystérieux d'un programme C sur Debian 7

Pàgina inicial

Reply to this message
Autor: Olivier Allard-Jacquin
Data:  
A: BOITEUX, Frederic, ML Guilde (guilde@guilde.asso.fr)
Assumptes nous: RE: Comportement mystérieux d'un programme C sur Debian7
Assumpte: Re: Comportement mystérieux d'un programme C sur Debian 7
    Bonsjour,

Le 12/02/2016 08:50, BOITEUX, Frederic a écrit :
>     Bonjour,

>
> Je voudrais soumettre à votre sagacité le problème suivant où je sèche depuis qq jours :
>
> sur un serveur en Debian 7 (7.9), une application écrite en C/C++ effectue [entre autres] toutes les 20 secondes une mise à jour d'un gros fichier (~ 30 Mo) en écrivant des données dans un fichier temporaire, avant de supprimer le fichier nominal pour le remplacer par ce fichier temporaire par des unlink() / link().
> Or, on constate sur ce serveur que de temps en temps, le fichier temporaire qui vient d'être écrit n'est pas présent ! Du coup, comme on supprime ensuite le fichier principal pour le remplacer par ce fichier temporaire, on perd ce fichier principal.
> On a rajouté des tests de retour des appels système utilisés, et utilisé un « stat() » après l'écriture du fichier pour vérifier l'absence du fichier temporaire créé, et on le constate bien, sans pouvoir se l'expliquer ! Le code est plutôt simple, en gros un fopen(), fwrite(), fclose(), puis un stat() pour vérifier la présence du fichier, et des unlink() / link() pour le renommage ; on a essayé de rajouter un fsync() pour voir, sans amélioration :


    Problème du file system ? Est-ce que qu'un fsck.ext4 a été fait/forcé
récement ?


> int secu::ma_pub_sauve()
>
> {
>         FILE *fp;
>         char fic[80], fictmp[80];
>         long st;
>         int i;
>         struct stat buf;

>
>         /* ouverture */
>         sprintf(fic, "%s/%s", repPub, cf.nom);
>         sprintf(fictmp, "%s/%s.tmp", repPub, cf.nom);

>
>         if((fp = fopen(fictmp, "w")) == NULL) {
>                 cst_err(241, "'%s'", fictmp);
>                 return -1;
>         }


    Là, tu sors de la fonction avec un code d'erreur. Mais est-ce que le
programme appellant de "secu::ma_pub_sauve" traite bien le code d'erreur
"-1" ?


>         /* transfert */
>         st = fwrite(pp, (unsigned)cf.ln_pub, 1, fp);
>         JNL2("=>ma_pub_sauve() : fwrite() done st=%ld, errno=%d\n", st, errno);


    Ici tu ne fait pas d'action (arrêt du programme par exemple) si
l'écriture n'a pas marché ?


>         /* close */
>         i = fclose(fp);
>         JNL2("=>ma_pub_sauve() : fclosed done status=%d errno=%d\n", i, errno);
>         fp = (FILE *) 0;


    Pareil pour ici.


>         if (stat(fictmp, &buf) == 0) {
>                 JNL2("write file tmp ok, size %ld, date %ld\n", buf.st_size, buf.st_mtime);
>         }
>         else {
>                 JNL2("write file tmp file not found '%s'\n", fictmp);
>                 JNL2("fflush() it\n");
>                 fflush(NULL);
>                 if (stat(fictmp, &buf) == 0) {
>                         JNL2("fflush() file tmp ok, size %ld, date %ld\n", buf.st_size, buf.st_mtime);
>                 }
>                 else {
>                         JNL2("fflush file tmp file not found '%s'\n", fictmp);
>                 }
>         }


    Cordialement,


                            Olivier
-- 
~~~~~~~  _____/\_____  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Phoenix /   _ \/ _   \    Olivier Allard-Jacquin
       /   / \  / \   \   Web:  http://olivieraj.free.fr/
      /___/  /  \  \___\  Mail: olivieraj@???
~~~~ /////  ///\\\  \\\\\ ~~~~~~~~~~~~~~~~~~~~~~~ Linux Powered !!