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

トップ ページ

このメッセージに返信
著者: Raphaël Dorado
日付:  
To: guilde
題目: Re: Comportement mystérieux d'un programme C sur Debian 7

Bonsoir,

Je pense que le problème n'est pas lié à Debian spécifiquement,
mais plutôt à la gestion des erreurs système sous Unix en général.

>> 15:13:04.349 =>ma_pub_sauve() : fwrite() done st=1, *errno=4*


Le ERRNO sur fwrite() est "4", une EINTR (interrupted system call),
ce qui provient en général d'une I/O d'un filesystem sur socket / réseau.

Cela signifie qu'une interruption prioritaire a pris le dessus sur le
syscall() sous-jacent (write()), et que l'opération demandée n'a pas
pu être effectuée. Il suffit en général de répéter l'opération, mais
si problème sérieux (créseau cassé) il faut éviter d'avoir une attente
"trop" active.

Il faut donc enrober les fonctions I/O (f)open/(f)write/(f)close/(f)stat du
genre (pour fwrite):

size_t my_fwrite(const void *ptr, size_t wsize, size_t nmemb,FILE *stream)
{
     size_t      sz;
     unsigned    delay = 0;


     /* Tant que erreur I/O ET que errno == EINTR, attendre 1 milliseconde */
     while( (sz = fwrite(ptr , wsize , nmemb , stream) < 0 && errno == EINTR) )
     {
         if (delay == 0)
         {
             /* La première fois, on ré-essaie tout de suite  */
             /* et on active le delai pour les fois suivantes */
             delay = 1000;
         }
         else
         {
             /* Si réseau cassé, ne pas occuper le CPU */
             /* A partir de la 2eme tentative échouée, */
             /* on attendra 1 ms avant chaque essai    */
             usleep(delay);
         }
     }


     return(sz);
}




--Raf


Le 12/02/2016 15:32, BOITEUX, Frederic a écrit :
>     Bonjour Jérémy,

>
> Pour l'usage de rename(), ce serait judicieux, en effet, mais on a parfois gardé des habitudes héritées de systèmes Unix anciens :-)
> En tout cas, le souci est avant, dans la création du fichier temporaire, pas dans son renommage… et cela n'arrive que de temps à autre…
>
> [et pour l'espace dans le nom de fichier, il n'est pas dans le log original, j'ai dû l'introduire en copiant/collant :-( ]
>
>     Cordialement,
>         Fred.

>
> -----Message d'origine-----
> De : Jérémy Bobbio [mailto:lunar@debian.org]
> Envoyé : vendredi 12 février 2016 14:46
> À : ML Guilde (guilde@???)
> Objet : Re: Comportement mystérieux d'un programme C sur Debian 7
>
> BOITEUX, Frederic:
>> 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().
>
> Je suis confus. Pourquoi ne pas utiliser rename(2)? J'ai justement le seul appel système qui garantie qu'on peut remplacer un fichier par une nouvelle version de manière atomique.
>
>> 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'
>                                                       ^

>
> Il est normal l'espace, là ?
>
> (Si c'est un vrai répertoire que quelqu'un·e a nommé '\x20datas.d', je suggère d'expliquer à cette personne que ce genre de blagues ne fait rire personne.)
>