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

Top Page

Reply to this message
Author: BOITEUX, Frederic
Date:  
To: ML Guilde (guilde@guilde.asso.fr)
Subject: Comportement mystérieux d'un programme C sur Debian 7
    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  :


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;
        }
 
        /* transfert */
        st = fwrite(pp, (unsigned)cf.ln_pub, 1, fp);
        JNL2("=>ma_pub_sauve() : fwrite() done st=%ld, errno=%d\n", st, errno);

        /* close */
        i = fclose(fp);
        JNL2("=>ma_pub_sauve() : fclosed done status=%d errno=%d\n", i, errno);
        fp = (FILE *) 0;
 
        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);
                }
        }
 
 
        /* check */
        if(st != 1) {
                // KO
                JNL("INFO Failure fwrite ma_pub_sauve(%ld # %d)\n",
                        st, (unsigned)cf.ln_pub);
                unlink(fictmp);
        }
        else {
                // OK : link
                JNL2("=>ma_pub_sauve() : ok st=%ld\n", st);
                i = unlink(fic);
                JNL2("=>ma_pub_sauve() : unlink done status=%d errno=%d\n", i, errno);
                i = link(fictmp, fic);
                JNL2("=>ma_pub_sauve() : link done status=%d errno=%d\n", i, errno);
 
                if(i == -1) {
                        if (stat(fictmp, &buf) == 0) {
                               JNL2("File tmp ok, size %ld, date %ld\n", buf.st_size, buf.st_mtime);
                        }
                        else {
                                JNL2("File tmp file not found '%s'\n", fictmp);
                        }
                }
                i = unlink(fictmp);
                JNL2("=>ma_pub_sauve() : unlink tmp file done status=%d errno=%d\n", i, errno);
        }
        // file is here ?
        if (stat(fic, &buf) == 0) {
                JNL2("File ok, size %ld, date %ld\n", buf.st_size, buf.st_mtime);
        }
        else {
                JNL2("ERROR ma_pub_sauve() file not found '%s'\n", fic);
        }
        return st;
}

On obtient des traces du genre :

15:13:04.349 =>ma_pub_sauve() : fwrite() done st=1, errno=4
15:13:04.360 =>ma_pub_sauve() : fclosed done status=0 errno=4
15:13:04.360 write file tmp file not found '/appli/ datas.d/mlp01/mlp01.tmp'
15:13:04.360 =>ma_pub_sauve() : ok st=1
15:13:04.363 =>ma_pub_sauve() : unlink done status=0 errno=2
15:13:04.363 =>ma_pub_sauve() : link done status=-1 errno=2
15:13:04.363 File tmp file not found '/appli/ datas.d/mlp01/mlp01.tmp'
15:13:04.363 =>ma_pub_sauve() : unlink tmp file done status=-1 errno=2
15:13:04.363 ERROR ma_pub_sauve() file not found '/appli/ datas.d/mlp01/mlp01'


Le fichier est situé sur une partition formatée classiquement en ext4.

Auriez-vous une explication possible à ce comportement ? ou encore mieux une solution :-P ?

    Merci
        Fred.



This message contains information that may be privileged or confidential and is the property of the Capgemini Group. It is intended only for the person to whom it is addressed. If you are not the intended recipient, you are not authorized to read, print, retain, copy, disseminate, distribute, or use this message or any part thereof. If you receive this message in error, please notify the sender immediately and delete all copies of this message.