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

Top Page

Reply to this message
Author: Patrice Karatchentzeff
Date:  
To: BOITEUX, Frederic
CC: ML Guilde (guilde@guilde.asso.fr)
Subject: Re: Comportement mystérieux d'un programme C sur Debian 7
Salut Fabrice,

Le fsync est obligatoire pour s'assurer que le fichier est bien écrit
et pas dans le cache du noyau.

Qu'y-a-t-il sous le système de fichier ? Un disque dur ? Un RAID ? un
NFS ? un filer ?

As-tu des messages dans les log au moment d'écriture ?

PK

2016-02-12 8:50 GMT+01:00 BOITEUX, Frederic <fboiteux@???>:
>         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.
>
>




-- 
      |\      _,,,---,,_           Patrice KARATCHENTZEFF
ZZZzz /,`.-'`'    -.  ;-;;,_   mailto:patrice.karatchentzeff@gmail.com
     |,4-  ) )-,_. ,\ (  `'-'      http://p.karatchentzeff.free.fr
    '---''(_/--'  `-'\_)