web-dev-qa-db-fra.com

Implémentation d'un système de mise à jour / mise à niveau pour les périphériques Linux embarqués

J'ai une application qui s'exécute sur un périphérique Linux intégré et de temps en temps des modifications sont apportées au logiciel et parfois aussi au système de fichiers racine ou même au noyau installé.

Dans le système de mise à jour actuel, le contenu de l'ancien répertoire d'application est simplement supprimé et les nouveaux fichiers sont copiés dessus. Lorsque des modifications ont été apportées au système de fichiers racine, les nouveaux fichiers sont fournis dans le cadre de la mise à jour et simplement copiés sur les anciens.

Maintenant, il y a plusieurs problèmes avec l'approche actuelle et je cherche des moyens d'améliorer la situation:

  • Le système de fichiers racine de la cible qui est utilisée pour créer des images de système de fichiers n'est pas versionné (je ne pense pas que nous ayons même les rootfs d'origine).
  • Les fichiers rootfs qui entrent dans la mise à jour sont sélectionnés manuellement (au lieu d'un diff)
  • La mise à jour se développe continuellement et cela devient un pita. Il y a maintenant une séparation entre la mise à jour/mise à niveau où la mise à niveau contient des modifications rootfs plus importantes.
  • J'ai l'impression que les contrôles de cohérence dans une mise à jour sont assez fragiles voire pas du tout mis en œuvre.

Les exigences sont:

  • Le package de mise à jour de l'application ne doit pas être trop volumineux et doit également pouvoir changer le système de fichiers racine dans le cas où des modifications ont été apportées.
  • Une mise à niveau peut être beaucoup plus importante et ne contient que les éléments qui vont dans le système de fichiers racine (comme les nouvelles bibliothèques, le noyau, etc.). Une mise à jour peut nécessiter une mise à niveau pour avoir été installée.
    La mise à niveau peut-elle contenir tout le système de fichiers racine et simplement faire un dd sur le lecteur flash de la cible?
  • La création des packages de mise à jour/mise à niveau doit être aussi automatique que possible.

J'ai absolument besoin d'un moyen de faire le versioning du système de fichiers racine. Cela doit être fait d'une manière, que je peux calculer une sorte de diff à partir de celui-ci qui peut être utilisé pour mettre à jour les rootfs du périphérique cible.

J'ai déjà étudié Subversion depuis que nous l'utilisons pour notre code source mais cela n'est pas approprié pour le système de fichiers racine Linux (autorisations de fichiers, fichiers spéciaux, etc.).

J'ai maintenant créé des scripts Shell qui peuvent me donner quelque chose de similaire à un svn diff mais j'aimerais vraiment savoir s'il existe déjà une solution fonctionnelle et testée pour cela.

En utilisant de tels diff, je suppose qu'une mise à niveau deviendrait alors simplement un package qui contient des mises à jour incrémentielles basées sur un état de système de fichiers racine connu.

Quelles sont vos pensées et vos idées à ce sujet? Comment mettriez-vous en œuvre un tel système? Je préfère une solution simple qui peut être mise en œuvre en peu de temps.

49
trenki

Je crois que le problème vous semble erroné - toute mise à jour qui n'est pas atomique (par exemple, dd une image de système de fichiers, remplacer des fichiers dans un répertoire) est cassée par conception - si le courant s'éteint au milieu d'une mise à jour, le système est un brique et pour le système embarqué, l'alimentation peut s'éteindre au milieu d'une mise à niveau.

J'ai écrit un livre blanc sur la façon de faire correctement la mise à niveau/mise à jour sur les systèmes Linux embarqués [1]. Il a été présenté à l'OLS. Vous pouvez trouver le document ici: https://www.kernel.org/doc/ols/2005/ols2005v1-pages-21-36.pdf

[1] Ben-Yossef, Gilad. "Construire des systèmes Linux embarqués compatibles Murphy." Symposium Linux . 2005.

32
gby

Je suis absolument d'accord qu'une mise à jour doit être atomique - j'ai récemment lancé un projet Open Source dans le but de fournir un moyen sûr et flexible pour la gestion de logiciels, avec une mise à jour locale et à distance. Je sais que ma réponse arrive très tard, mais elle pourrait peut-être vous aider dans les prochains projets.

Vous pouvez trouver des sources pour "swupdate" (le nom du projet) sur github.com/sbabic/swupdate .

Stefano

9
sbabic

L'atomicité est essentielle pour les appareils embarqués, l'une des raisons mises en évidence est la perte de puissance; mais il pourrait y en avoir d'autres comme des problèmes de matériel/réseau.

L'atomicité est peut-être un peu mal comprise; c'est une définition que j'utilise dans le contexte des mises à jour:

  • Une mise à jour est toujours soit entièrement terminée, soit pas du tout
  • Aucun composant logiciel à part le programme de mise à jour ne voit une mise à jour à moitié installée

La mise à jour complète de l'image avec une disposition de partition double A/B est le moyen le plus simple et le plus éprouvé pour y parvenir.

Pour Embedded Linux, il existe plusieurs composants logiciels que vous voudrez peut-être mettre à jour et différentes conceptions parmi lesquelles choisir; il existe un article plus récent à ce sujet ici: https://mender.io/resources/Software%20Updates.pdf

Fichier déplacé vers: https://mender.io/resources/guides-and-whitepapers/_resources/Software%2520Updates.pdf

Si vous travaillez avec le projet Yocto, vous pourriez être intéressé par Mender.io - le projet open source sur lequel je travaille. Il se compose d'un client et d'un serveur et l'objectif est de rendre beaucoup plus rapide et plus facile l'intégration d'un programme de mise à jour dans un environnement existant; sans avoir à repenser trop ni à consacrer du temps au codage personnalisé/local. Il vous permettra également de gérer les mises à jour de manière centralisée avec le serveur.

2
rduio

Actuellement, il existe de nombreux outils de mise à jour Linux embarqué Open Source en pleine croissance, avec une orientation différente chacun.

Un autre qui mérite d'être mentionné est RAUC , qui se concentre sur la gestion des installations sécurisées et atomiques de faisceaux de mise à jour signés sur votre cible tout en étant très flexible dans la façon dont vous l'adapter à votre application et à votre environnement. Les sources sont sur GitHub: https://github.com/rauc/rauc

En général, un bon aperçu et une comparaison des solutions de mise à jour actuelles que vous pourriez trouver sur la page Wiki du projet Yocto sur les mises à jour du système:

https://wiki.yoctoproject.org/wiki/System_Update

2
ejoerns

Vous pouvez journaliser une mise à jour et diviser votre mise à jour flash en deux emplacements. Une panne de courant vous ramène toujours à l'emplacement en cours d'exécution. La dernière étape consiste à modifier la valeur du journal. Non atomique et aucun moyen de le rendre en brique. Même si cela échoue au moment d'écrire les drapeaux du journal. Une mise à jour atomique n'existe pas. Déjà. Je ne l'ai jamais vu de ma vie. Iphone, adroid, mon commutateur réseau - aucun d'entre eux n'est atomique. Si vous n'avez pas assez de place pour faire ce type de conception, corrigez la conception.

0
MaxDeusPhallus