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

Page principale

Répondre à ce message
Auteur: BOITEUX, Frederic
Date:  
À: Patrice Karatchentzeff
CC: ML Guilde (guilde@guilde.asso.fr)
Sujet: RE: Comportement mystérieux d'un programme C sur Debian 7
    Bonjour Patrice,

Le fsync() est pour moi là pour s'assurer que le fichier est bien écrit sur le disque en cas par exemple d'arrêt brutal de la machine… mais sur un système qui fonctionne sans problème, même si le fichier est écrit uniquement en cache, le système Linux devrait le voir comme s'il était sur le disque, non ?
  La partition-cible est en ext4, sur du LVM, sur un disque RAID 1 (avec carte et gestion matérielle, la machine est une HP Gen8).
Et sinon, on n'a rien dans les journaux système ou noyau…

    Fred.

-----Message d'origine-----
De : Patrice Karatchentzeff [mailto:patrice.karatchentzeff@gmail.com] 
Envoyé : vendredi 12 février 2016 09:27
À : BOITEUX, Frederic
Cc : ML Guilde (guilde@???)
Objet : 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
    '---''(_/--'  `-'\_)
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.