Une histoire d’étiquettes de vin et de contributions Open Source

This article is also available in English

Où nous plantons le décor

Après des années de travail dans le secteur des services, il y a une chose qui ne cesse de m’étonner : la variété des besoins de nos clients et la façon dont ils peuvent encore nous surprendre. Ils nous conduisent parfois dans des missions inattendues. C’est évidemment quelque chose que j’aime particulièrement.

Aujourd’hui, je vais vous raconter l’histoire d’une belle relation que enioka Haute Couture a nouée avec un client situé à l’autre bout de la planète.

Tout a commencé par un message sur une liste de diffusion KDE il y a quelques années. Des gens cherchaient de l’aide. C’est mon collègue Benjamin Port qui a démarré les échanges avec eux. Il s’est avéré que ces personnes venaient de De Bortoli Wines, une société viticole australienne. Ils sont connus pour utiliser beaucoup de logiciels libres et pour y contribuer quand ils le peuvent. Ils ont même été interviewés sur le KDE dot il y a dix ans !

Ils voulaient se débarrasser d’Acrobat Reader pour Linux en faveur d’Okular. Ils ont cependant rencontré un problème : le support de la prévisualisation des surimpressions (overprint preview) était visiblement défectueux dans Okular. Ceci est essentiel lorsque vous interagissez avec une société de reprographie qui renvoie des PDF en fonction de la façon dont elle superpose les couleurs (ou overprinting). Vous avez besoin de l’overprint preview pour simuler le rendu final sur écran. Nous étions bien sûr motivés pour les aider à se débarrasser d’Acrobat Reader pour Linux, car il s’agit d’un vieux logiciel propriétaire et obsolète.

S’attaquer en profondeur au rendu des PDF

Cela semblait au départ une tâche facile. Poppler (utilisé pour le rendu des PDF) exposait une API pour l’overprint preview mais Okular ne l’utilisait pas. Nous avons rapidement fait un patch pour utiliser l’API d’overprint preview.

Hélas, cela a mis au jour un autre problème. Dès que nous activions le support de l’overprint preview, l’application plantait. Nous avons trouvé le problème un niveau plus bas. D’une manière ou d’une autre, l’erreur se cachait dans la couche d’adaptation (binding) Poppler-Qt.

Après un examen plus approfondi, il s’est avéré que le binding déterminait de manière erronée la taille des lignes des images raster. Une conversion de l’espace colorimétrique a lieu entre la représentation initiale en mémoire et l’image raster cible. Le code obtenait cette taille de ligne avant que la transformation ne se produise… et finissait par insérer la mauvaise quantité de données dans l’image raster cible. Cela ne pouvait qu’échouer. Un autre correctif a donc été produit pour remédier à ce problème.

La bonne nouvelle, c’est que nous avons réussi à résoudre le problème en moins de temps que le budget alloué par le client. Nous lui avons donc laissé le choix entre s’arrêter là ou utiliser le budget restant pour faire autre chose.

Nous avions utilisé la suite Ghent Workgroup PDF Output pour valider notre travail au-delà des échantillons fournis par notre contact. Nous avons alors remarqué que Poppler ne parvenait pas à rendre correctement certains autres cas. Nous avons proposé d’étudier également ces cas.

Après avoir passé un peu de temps sur ces problèmes… nous avons fait des tentatives de correction, mais malheureusement elles ont conduit à une régression. En accord avec le client, nous avons donc préféré créer un rapport de bug détaillé afin de ne pas gaspiller leur budget. Cela a aidé la communauté Poppler à comprendre le problème et à produire un correctif. Nous avons alors réalisé que nous étions à un moment donné très proches de la bonne solution. Il est clair qu’une vision d’expert sur le fonctionnement des différents espaces colorimétriques PDF était nécessaire. Il était donc judicieux de créer un rapport détaillé.

Alors qu’il restait encore un peu de budget, notre contact nous a proposé d’ajouter le support de l’overprint preview lors de l’impression depuis Okular. Cette fonctionnalité n’était initialement pas prévue, mais elle est nécessaire lorsque vous souhaitez imprimer votre aperçu sur une imprimante laser classique. Cela a nécessité d’ajuster Okular et d’ajuster Poppler-Qt une fois de plus. En fin de compte, le budget a été respecté.

Des difficultés avec les points de montage CIFS

Comme le client était satisfait du travail effectué, lorsqu’il a eu des besoins similaires il est revenu vers nous. Il a alors alloué un petit budget pour l’année avec lequel ils nous sollicitent pour résoudre les problèmes qu’ils rencontrent sur des logiciels Open Source.

À cette période, leur attention s’est portée sur les points de montage CIFS, qu’ils utilisent largement pour leurs bureaux distants. En tant qu’utilisateurs intensifs de cette fonctionnalité du noyau Linux, ils rencontrent des problèmes dans les applications de bureau que l’on ne rencontrerait pas autrement.

Échecs lors de la copie de fichiers

Ils ont été affectés par un bug empêchant Okular de sauvegarder sur des points de montage CIFS. Il avait été identifié depuis un peu plus d’un an sans solution en vue. Certaines applications pouvaient modifier et sauvegarder un fichier ouvert sur un point de montage CIFS, mais pas Okular.

Il s’est avéré que cela était dû à du code dans KIO lui-même (l’API de KDE Frameworks utilisée pour les opérations de manipulations de fichiers transparentes au réseau) qui interagissait de manière indésirable avec les points de montage CIFS.

En effet, le comportement de unlink() (suppression de fichiers) sur les points de montage CIFS peut être un peu « étonnant ». Si le fichier que l’on tente de supprimer est ouvert par un autre processus, l’opération est considérée comme réussie mais le nom du fichier reste visible dans la hiérarchie des fichiers jusqu’à ce que le dernier descripteur soit fermé. Ceci est différent du comportement habituel d’UNIX, en dehors des points de montage CIFS, le fichier ne serait plus visible dans la hiérarchie. Nous avons donc constaté le problème parce qu’Okular garde un descripteur ouvert sur le fichier.

Lors de la sauvegarde, KIO tente (à juste titre) de d’abord écrire sous un nom temporaire, puis de supprimer le fichier original et de renommer le fichier temporaire sous le nom final. Cette opération échoue alors car l’appel à unlink() réussit, mais le renommage échoue de façon inattendue à cause de la présence d’un fichier qui ne devrait plus être listé dans le répertoire.

Nous avons donc proposé un correctif pour KIO qui effectue une copie directe pour les fichiers sur les points de montage CIFS. Cette modification a été mergée. L’écrasement direct des fichiers fonctionne et le bug rencontré avec Okular a donc été résolu.

Lenteur du listing des répertoires

Ce n’était pas la fin des problèmes avec les points de montage CIFS (loin de là). Ils rencontraient également des problèmes de performance lors de l’affichage du contenu des dossiers. Il est intéressant de noter que ce problème n’apparaissait que dans la vue détaillée de la boîte de dialogue de fichiers KDE.

Le problème central était la demande d’un trop grand nombre d’informations. Lors de l’affichage d’un dossier connu pour être distant par KIO (par exemple en passant par une URL smb://), la vue limitait la quantité d’informations qu’elle demandait sur les sous-dossiers. En particulier, elle ne tentait pas de déterminer le nombre de fichiers dans les sous-dossiers. Cette opération est aujourd’hui rapide sur les disques modernes, mais elle entraîne un trafic et une latence supplémentaires sur le réseau.

Cela semblait être une solution simple… mais en fait, cela a demandé un peu plus de travail que prévu.

Sans surprise, nous avons rapidement constaté que le code décidait d’aller chercher plus ou moins de détails uniquement en fonction de l’URL. Puisque les points de montage CIFS ont des URLs file:/, ils finissent par être traités comme des fichiers locaux… nous avons donc décidé de faire une vérification un peu plus agressive. Il existe une méthode isSlow() sur les éléments de l’arbre de la vue détaillée que nous avons étendue pour vérifier la présence d’un point de montage CIFS.

Mais ce n’était pas suffisant. Nous avons immédiatement réalisé que le nouveau goulot d’étranglement était les appels à isSlow() lui-même. Cela conduisait à plusieurs appels à statfs qui sont également coûteux. La solution consistait donc à mettre en cache les informations dans les nœuds de l’arborescence et à permettre aux enfants d’interroger le cache de leur parent. En effet, si le parent est considéré comme lent, nous avons décidé de considérer les enfants du dossier comme également lents. Cette heuristique nous a permis de supprimer tous les appels à isSlow() après celui du dossier du point de montage lui-même.

C’est un très ancien morceau de code que nous avons touché à cette occasion. Un peu de temps a donc été utilisé pour nettoyer le code. Nous avons refactorisé et renommé des variables et fonctions pour mieux les aligner avec d’autres parties de KIO.

Fichiers de sauvegarde de LibreOffice pendant l’enregistrement

Ils utilisent si activement les points de montage CIFS qu’ils ont trouvé un autre problème ! Cette fois-ci avec une ancienne version de LibreOffice. Dans cette version, le problème n’apparaît que si l’intégration KDE est utilisée. Je peux vous dire que nous avons été un peu surpris. L’enquête n’a pas été facile, mais nous avons réussi à trouver la cause.

Le problème apparaît lorsqu’un fichier se trouvant sur un point de montage CIFS est ouvert avec LibreOffice. Si vous modifiez le fichier, puis cliquez sur « Enregistrer sous… » et sélectionnez le même fichier à écraser, vous obtenez une erreur « Impossible de créer une copie de sauvegarde » et le fichier n’est pas sauvegardé. Cela survient uniquement lorsque l’intégration KDE est active, tout se passe bien sans cette intégration.

Qu’est-ce qui serait différent avec et sans l’intégration KDE ? Et bien, dans un cas, il y a un processus supplémentaire ! Lorsque la boîte de dialogue de fichier s’ouvre, s’il s’agit de la boîte de dialogue de fichier KDE, le listing du répertoire est réalisé par un KIO Worker. Dans ce cas particulier, c’est important. En effet, nous avons compris que LibreOffice conserve un descripteur de fichier ouvert sur le fichier. De plus, il détient également un verrou de lecture sur le fichier. Le KIO Worker est forké à partir de LibreOffice, il a donc lui aussi un descripteur de fichier ouvert avec un verrou.

Cela nous a permis de réaliser qu’il y avait une fuite de descripteurs de fichiers, ce qui n’est pas une bonne chose en soi. Nous avons donc modifié KIO pour qu’il nettoie les descripteurs de fichiers ouverts lors de la création de workers, c’est toujours une bonne idée de nettoyer les ressources inutilisées. De plus, dès que nous avons supprimé la fuite du descripteur de fichier, le problème a disparu. C’était une solution facile à mettre en œuvre.

Nous avons ensuite cherché à vérifier le comportement avec la dernière version de LibreOffice. Et même avec le KIO corrigé, nous avons obtenu l’erreur « Impossible de créer une copie de sauvegarde » ! Cette fois-ci, l’erreur survient même sans l’intégration de KDE. Sans entrer dans les détails de LibreOffice, il s’est avéré que la version la plus récente avait du code supplémentaire activé pour produire la version de sauvegarde, et qu’elle a deux descripteurs de fichiers ouverts sur le même fichier. Nous sommes donc revenus au problème des deux descripteurs de fichiers et des verrous de lecture. Mais cette fois, ce n’était pas dû à une fuite vers un autre processus. De plus, l’architecture de LibreOffice ne facilitait pas la réutilisation du descripteur de fichier original créé lors de l’ouverture du fichier.

La seule chose que nous pouvions faire à ce stade était simplement de ne pas verrouiller lorsque le fichier est sur un point de montage CIFS. Ce n’est pas une solution très satisfaisante, mais elle a permis de faire le travail dans le temps imparti.

D’une certaine manière, nous ne pouvions pas laisser les choses en l’état. Si vous connaissez bien les vraiment très critiqués verrous de fichier POSIX (qui ont des difficultés supplémentaires vis à vis de CIFS), quelque chose cloche encore. Nous avons deux processus avec un descripteur de fichier sur le fichier à sauvegarder, et pourtant il y a un seul processus qui détient un verrou de lecture. Pendant la sauvegarde, lorsque l’échec se produit, LibreOffice est encore en train de faire une « copie de sauvegarde ». Il n’écrit pas encore dans le fichier. Il ne fait que le lire… cela devrait donc être autorisé !

Nous avons donc commencé à suspecter un problème avec le noyau Linux lui-même… et notre contact a accepté de l’explorer plus avant. Dans ce but, le client nous a mis en contact avec Andrew Bartlett de Catalyst car il devait pouvoir nous aider à explorer et raffiner nos idées sur ce domaine. Et en effet, cela nous a aidé. Grâce a des tests que nous avions écrits et aux conversations avec Andrew, nous avons rapidement confirmé qu’il s’agissait d’un bug du noyau. En fonction des options passées au moment du montage, le pilote CIFS gère correctement les verrous ou non. Nous avons donc discuté d’un correctif avec le mainteneur du driver CIFS du noyau. Ces correctifs ont été intégrés la semaine dernière (fin août 2024).

Un client qui inspire la joie

C’est vraiment un plaisir d’avoir un client comme celui-ci. Comme en témoigne leur volonté d’approfondir des questions que d’autres considéreraient comme obscures, ils démontrent qu’ils réfléchissent à long terme. Cela signifie également qu’ils nous soumettent des questions intéressantes et stimulantes… et qu’ils apprécient ce que nous avons réalisé pour eux !

En effet, nous avons eu le plaisir de recevoir ce message par email au cours de nos conversations :

Nous apprécions beaucoup le travail que vous avez accompli et les difficultés liées aux défis que vous relevez. Votre approche et vos résultats sont spectaculaires, et nous sommes très reconnaissants d’avoir pu y participer.

Bien entendu, si vous avez des projets en lien avec des communautés de logiciels libres ou des questions plus proches du système, n’hésitez pas à nous contacter et nous verrons ce que nous pouvons faire pour vous aider. Peut-être serez-vous vous aussi un client audacieux qui inspire la joie !


Publié

dans

par

Étiquettes :

En savoir plus sur enioka

Abonnez-vous pour poursuivre la lecture et avoir accès à l’ensemble des archives.

Poursuivre la lecture