J'ai commencé à réfléchir à cette question dans le contexte de l'étiquette sur la liste de diffusion Linux Kernel. En tant que projet de logiciel libre le plus connu et sans doute le plus réussi et le plus important au monde, le noyau Linux reçoit beaucoup de presse. Et le fondateur et chef de projet, Linus Torvalds, n'a clairement pas besoin d'être présenté ici.
Linus suscite parfois des controverses avec ses flammes sur le LKML. De son propre aveu, ces flammes ont souvent pour but de casser l’espace utilisateur. Ce qui m'amène à ma question.
Puis-je avoir une perspective historique sur la raison pour laquelle casser l’espace utilisateur est une si mauvaise chose? Si je comprends bien, casser l’espace utilisateur demanderait des corrections au niveau de l’application, mais est-ce une si mauvaise chose d’améliorer le code du noyau?
Si je comprends bien, la politique déclarée de Linus est que ne pas casser l’espace utilisateur prime sur tout le reste, y compris la qualité du code. Pourquoi est-ce si important et quels sont les avantages et les inconvénients d'une telle politique?
(Il y a clairement des inconvénients à une telle politique, appliquée systématiquement, étant donné que Linus a parfois des "désaccords" avec ses principaux lieutenants du LKML sur exactement ce sujet. Pour autant que je sache, il réussit toujours.)
la source
Réponses:
La raison n’est pas historique mais pratique. Il y a beaucoup de nombreux programmes qui s'exécutent sur le noyau Linux; Si une interface de noyau casse ces programmes, tout le monde devra les mettre à jour.
Il est vrai que la plupart des programmes ne dépendent pas directement des interfaces du noyau ( appels système ), mais uniquement des interfaces de la bibliothèque standard C ( enveloppeurs C autour des appels système). Oh, mais quelle bibliothèque standard? Glibc? uClibC? Dietlibc? Bionique? Musl? etc.
Cependant, de nombreux programmes implémentent des services spécifiques au système d'exploitation et dépendent d'interfaces du noyau qui ne sont pas exposées par la bibliothèque standard. (Sur Linux, beaucoup d’entre eux sont offerts par
/proc
et/sys
.)Et puis il y a des binaires compilés statiquement. Si une mise à niveau du noyau casse l'un de ces problèmes, la seule solution serait de les recompiler. Si vous en avez la source: Linux prend également en charge les logiciels propriétaires.
Même lorsque la source est disponible, tout rassembler peut être une douleur. Surtout lorsque vous mettez à niveau votre noyau pour corriger un bogue avec votre matériel. Les gens mettent souvent à niveau leur noyau indépendamment du reste de leur système car ils ont besoin du support matériel. Dans les mots de Linus Torvalds :
Il explique également que l’une des raisons pour faire de cette règle une règle stricte est d’éviter toute dépendance, car il vous faudrait non seulement mettre à niveau un autre programme pour que le nouveau noyau fonctionne, mais également mettre à niveau un autre programme, et un autre, et un autre. , parce que tout dépend d’une certaine version de tout.
En espace utilisateur, ces dépendances mutuelles sont généralement résolues en conservant différentes versions de bibliothèque. mais vous ne pouvez exécuter qu'un seul noyau, il doit donc prendre en charge tout ce que les gens peuvent vouloir en faire.
officiellement ,
En pratique cependant,
Ce qui change le plus souvent, ce sont les interfaces destinées uniquement aux programmes liés au matériel, en format
/sys
. (/proc
en revanche, qui depuis l'introduction de/sys
a été réservé aux services non liés au matériel, ne se casse presque jamais de manière incompatible.)En résumé,
Et c'est dommage car il n'y a qu'un seul noyau que les utilisateurs souhaitent mettre à niveau indépendamment du reste de leur système, mais il existe de nombreuses applications aux interdépendances complexes. Il est plus facile de garder le noyau stable que de garder des milliers d'applications à jour sur des millions de configurations différentes.
la source
Dans tous les systèmes interdépendants, il existe essentiellement deux choix. Abstraction et intégration. (Je n'utilise pas volontairement des termes techniques) Avec Abstraction, vous dites que lorsque vous appelez une API, le résultat sera toujours le même, même si le code derrière l'API peut changer. Par exemple, lorsque nous appelons
fs.open()
, peu importe qu'il s'agisse d'un lecteur réseau, d'un SSD ou d'un disque dur, nous obtiendrons toujours un descripteur de fichier ouvert avec lequel nous pourrons travailler. Avec "intégration", l’objectif est de fournir le "meilleur" moyen de faire une chose, même si la façon de le faire change. Par exemple, l'ouverture d'un fichier peut être différente pour un partage réseau et pour un fichier sur disque. Les deux méthodes sont assez utilisées dans le bureau Linux moderne.Du point de vue des développeurs, il s’agit de "fonctionne avec n’importe quelle version" ou "fonctionne avec une version spécifique". OpenGL est un bon exemple de cela. La plupart des jeux sont configurés pour fonctionner avec une version spécifique d'OpenGL. Peu importe si vous compilez à partir des sources. Si le jeu a été écrit pour utiliser OpenGL 1.1 et que vous essayez de le faire tourner sous 3.x, vous n’allez pas passer un bon moment. À l’autre bout du spectre, certains appels devraient fonctionner de toute façon. Par exemple, je veux appeler
fs.open()
je ne veux pas me soucier de la version de mon noyau. Je veux juste un descripteur de fichier.Il y a des avantages dans chaque sens. L'intégration fournit des fonctionnalités "plus récentes" au détriment de la compatibilité ascendante. Tandis que l’abstraction offre une stabilité par rapport aux appels "plus récents". Bien qu'il soit important de noter que c'est une question de priorité, pas de possibilité.
D'un point de vue commun, sans une très bonne raison, l'abstraction est toujours préférable dans un système complexe. Par exemple, imaginez si vous
fs.open()
travaillez différemment selon la version du noyau. Ensuite, une simple bibliothèque d’interaction avec le système de fichiers doit gérer plusieurs centaines de méthodes de "fichiers ouverts" (ou de blocs). Quand une nouvelle version du noyau est sortie, vous ne pouvez pas "mettre à jour", vous devez tester chaque logiciel que vous utilisez. Le noyau 6.2.2 (faux) peut juste casser votre éditeur de texte.Pour certains exemples concrets, OSX a tendance à ne pas se soucier de casser l’espace utilisateur. Ils visent plus fréquemment «l'intégration» à «l'abstraction». Et à chaque mise à jour majeure du système d'exploitation, les choses se cassent. Cela ne veut pas dire qu'une façon est meilleure que l'autre. C'est un choix et une décision de conception.
Plus important encore, l'écosystème Linux regorge de projets Open Source impressionnants, dans lesquels des personnes ou des groupes travaillent sur le projet pendant leur temps libre ou parce que l'outil est utile. En gardant cela à l’esprit, à la seconde où cela cesse d’être amusant et commence à être une PIA, ces développeurs iront ailleurs.
Par exemple, j'ai soumis un correctif à
BuildNotify.py
. Non pas parce que je suis altruiste, mais parce que j'utilise l'outil et que je voulais une fonctionnalité. C'était facile, alors voici un patch. Si c'était compliqué ou lourd, je ne l'utiliserais pasBuildNotify.py
et je trouverais autre chose. Si chaque fois qu'une mise à jour du noyau était publiée, mon éditeur de texte tombait en panne, j'utiliserais simplement un système d'exploitation différent. Mes contributions à la communauté (si petites soient-elles) ne continueraient pas ou n'existeraient pas, etc.Ainsi, la conception a été prise pour des appels système abstraits, de sorte que lorsque je le fais,
fs.open()
cela fonctionne. Cela signifie maintenirfs.open
longtemps après avoirfs.open2()
gagné en popularité.Historiquement, c'est l'objectif des systèmes POSIX en général. "Voici un ensemble d'appels et les valeurs de retour attendues, vous déterminez le milieu." Encore une fois pour des raisons de portabilité. Pourquoi Linus a choisi d'utiliser cette méthodologie est interne à son cerveau, et vous devrez lui demander de savoir exactement pourquoi. Si c’était moi cependant, je choisirais l’abstraction sur l’intégration sur un système complexe.
la source
C'est une décision de conception et de choix. Linus veut pouvoir garantir aux développeurs d’espace utilisateur que, sauf circonstances extrêmement rares et exceptionnelles (liées à la sécurité, par exemple), les modifications apportées au noyau ne casseront pas leurs applications.
Les pros sont que les développeurs en espace utilisateur ne verront pas leur code déferler brusquement sur de nouveaux noyaux pour des raisons arbitraires et capricieuses.
Les inconvénients sont que le noyau doit conserver l'ancien code et les anciens appels système, etc., pour toujours (ou, du moins, longtemps après leur date de péremption).
la source