Présentation générale de GNU/Hurd

Gnu

Hurd est un ensemble de serveurs (une horde de GNU  ;)),

Horde
basé sur le micro-noyau Mach. L'objectif principal est de reporter le maximum de fonctionnalités sur Hurd, Mach ne s'occupant que de la gestion de la mémoire, de l'ordonnancement des processus et de la gestion des interruptions matérielles.

D'un point de vue technique, l'aspect le plus intéressant de Hurd vient de son architecture multi serveurs. Les serveurs s'exécutent dans l'espace utilisateur, au dessus du micro noyau, pour fournir les services aux applications.
Le système est conçu de manière très modulaire de façon à ce que chaque composant puisse être remplacé ou modifié. L'utilisateur a ainsi la possibilité de changer de serveur si des besoins en ce sens se font sentir et ce, sans mettre en péril la sécurité ou la liberté des autres utilisateurs. Les processus dialoguent avec le système par l'intermédiaire de bibliothèques qui feront les appels nécessaires aux différents serveurs (qui s'appuieront sur Mach pour tout ce qu'ils ne pourront réaliser eux mêmes). En particulier, la bibliothèque C implémante l'équivalent des appels systèmes Unix. Rien n'empêche donc l'utilisateur de remplacer ces fonctions par les siennes pour des besoins d'optimisation ou parce que les services dont il a besoin n'existent pas.
Avec les caractérisques de transparence réseau, les serveurs peuvent être répartis sur plusieurs machines. Lorsqu'une nouvelle tâche est créée, le système lui alloue des ressources sur la même machine ou sur une machine distante.
Enfin, le code du système est réentrant. Le système peut donc servir plusieurs requêtes simultanément et de manière asynchrone, contrairement l'Unix classique où le noyau ne peut fournir qu'un seul service à la fois en suspendant les autres processus accédant au noyau.
Point négatif : les besoins en ressources d'un tel système sont bien plus grands en comparaison à Linux ou à FreeBSD. Ainsi sur une machine peu puissante tel qu'un PC, sa vivacité est sensiblement inférieure et un processeur RISC doté de beaucoup de mémoire et de disques SCSI rapides ne sont pas inutiles.




Comparaison des  Noyaux
Noyau Linux Hurd
Noyau monolithique µ-noyau
Mono-serveur Multi serveurs
Diverses architectures Intel 32 bits (pour l'instant ;))
pour système de puissance variable           Pour sytème puissant            

architecture de Hurdarchitecture du noyau Linux


Présentation du µ-noyau Mach


Son architecture :
Mach, développé par l'université amércaine de Carnegie Mellon (1985-1994)  est micro-noyau gratuit, écrit en C et orienté objet , ses sources sont librement distribuables. Il est techniquement très au point, c'est un système temps réel et satisfait les critères de sécurité de niveau B3 du standard TCSEC (Trusted Centralized System Evaluation Criteria) du NIST.
Sécurité faibleechelle sécurité TCSECTrès sécurisé

 Mach est portable sur plusieurs plateformes. Hurd sera donc autant portable que le sont Mach et GCC, et ce n'est donc pas un système réservé au PC (même si c'est le cas pour l'instant), mais bien un OS pouvant être implant sur à peu près toutes les machines existantes, du micro ordinateur au super système. Ce sont tous ces avantages qui ont justifié et qui justifient toujours le choix de Mach comme base pour Hurd.
Mach est orienté objet et même s'il ne propose pas de mécanismes d'héritage ou de polymorphisme, il consiste en un ensemble d'interfaces bien définies, par lesquelles on accède aux objets Mach : les ports, les messages, les tâches, les threads et la mémoire virtuelle. Les changements internes ne remettent donc pas en cause le code des programmes les utilisant.  Une des motivation de Mach est d'émuler Unix.
Une tâche Mach correspond grossièrement à un processus Unix. Elle correspond l'environnement d'excution reprsentant les ressources auxquelles accès le programme, telle que la mémoire virtuelle. À la différence d'Unix, une tâche Mach ne contient pas implicitement un thread. Pour qu'une tâche soit utile, il faudra donc qu'elle contienne au moins un thread.Lesthreads Mach correspondent aux threadsdes autres systèmes d'exploitation modernes: il s'agit d'un flot d'excution partageant des ressources (mémoire, CPU ...) avec les autres threads appartenant la même tâche.
Pour permettre aux différentes tâches de communiquer, Mach fournit un mécanisme de port. Un port Mach est analogue au port utilisé dans la programmation avec les socket: c'est un canal de communication entre deux tâches. De la même manière qu'avec les sockets, un port Mach permet  à deux tâches de communiquer et ce même si elles ne sont pas sur le même processeur (cas d'un systme multiprocesseur ou sur deux machines sparées). Et comme les ports Mach représentent le moyen privilgié de communication entre tâches, il est aisé de répartir les applications sur un ensembles d'ordinateurs (passage l'échelle).
Mach présente encore de nombreuses caractéristiques, mais elles sont moins intéressantes du point de vue de Hurd. En s'appuyant sur Mach, Hurd bénéficie implicitement et dès le début de ses caractéristiques temps réel, multiprocesseurs, multithread et de la possibilité de former des clusters transparents, contrairement aux autres systèmes.

Signification de termes informatique sous Mach (souvent appelées Notions de Bases de Mach) :

Tâche environnement d'execution
Thread unité d'exécution élémentaire
Port mécanisme de communication sous Mach
Message communication entre thread :   

1)Port destination

2)Port de réponse

     3)Taille du message
Objet mémoire fichier, pipe, disque

Pour résumer et insister sur la définition des termes importants, relatifs aux notions de bases de Mach, voici un récapitulatif :

Une tâche est un environnement d'exécution (un espace mémoire virtuel) permettant d'accéder aux ressources systèmes via des ports et pouvant contenir un ou plusieurs threads.

    -->    Une tâche possédant un thread est l'équivalent d'un processus traditionnel Unix.

Le thread est l'unité d'exécution de base et s'exécute dans le contexte d'une tâche. Tous les threads d'une tâche partagent les ressources de cette tâche (ports, mémoire, ).

    -->    Les threads sont particulièrement utiles dans les applications clients serveurs(une tâche possédant plusieurs threads peut satisfaire plusieurs requêtes) et le calcul parallèle.

Les ports constituent le mécanisme de communication de base sous Mach. En effet, les communications sous effectuées en envoyant des messages vers des ports. Chacun d'eux possède des droits et une tâche doit détenir ce droit pour pouvoir envoyer un message vers un port ou recevoir un message d'un port.

    -->    Il existe aussi la notion d'ensemble de port (port set) qui est un groupe de ports partageant la même file de messages. Un thread peut recevoir un message d'un ensemble de port et ainsi servir plusieurs ports.

Un objet mémoire peut représenter un fichier, un pipe, ou tout autre donnée pouvant être lu ou écrite. Il représente tout objet pouvant se dans l'espace mémoire secondaire (ex: le disque).

Une tâche peut accéder à un objet mémoire en mappant la totalité ou une partie de cet objet dans son propre espace d'adressage.

Gestion des processus et communication

Mach utilise une politique d'ordonnancement simple. En fait seuls les threads sont ordonnancés et rentrent en compétition pour obtenir des ressources ce qui signifie que les tâches n'entrent pas en jeu.

En fonction de leur utilisation du CPU, chaque thread se voit associé un numéro de priorité allant de 0 à 127. Ainsi, plus un thread utilise le CPU, plus sa priorité sera faible. On retrouve d'ailleur le même fonctionnement sous Unix et GNU/Linux.

En fonction de cette priorité, le thread sera placé dans une file d'exécution globale (visible par tous les processeurs) ou locale (visible par un seul processeur seulement et permettant de gérer les threads ne pouvant s'exécuter que sur un seul processeur).Une notion assez nouvelle et efficace pour intégrée dans ce micro noyau et celle de Quantum de temps variable. Etant donné que l'on se trouve dans un système multiprocesseur, il se peut très bien qu'il y ait à un moment donné moins de threads en cours d'exécution qu'il n'y ait de processeurs disponibles.  Avec un quantum de temps fixe, un thread ayant tout épuisé son quantum de temps serait  interrompu puis immédiatement ré exécuté. Les opérations de changements de contexte étant relativement coûteuse, cette façon de procéder diminuerait considérablement les performances.

Sous Mach, presque tout est objet et toute la communication est basée sur les ports et les messages.Ce système de ports et de messages permet d'assurer une transparence de la localisation des objets et une sécurité de communication. La communication sous Mach (c'est-à-dire l'échange de messages) se base sur deux caractéristiques qui sont la sécurité et la transparence. L' échange de messages se fait par le "Copy on write" : tout en préservant l'original des modifications cette technique est rapide. Pour assurer la sécurité de communication, des notions de droit  sur des ports pour les envoyeurs et les receveurs. En il faut avoirla capacité d'envoyer ou de recevoir sur un port. Il est intéressant de noter qu'une seule tâche a la capacité de recevoir sur un port.  Ce qui est très fort aussi concerne la possibilité de grouper plusieurs ports entre eux.

Gestion de la mémoire

Mach n'essai pas de réorganiser son espace d'adressage mémoire (il ne redéplace pas les blocs mémoire pour avoir la plus grande zone possible). Sa politique d'allocation et de récupération mémoire est gérée par un thread interne au noyau. L'algorithme utilisé pour sélectionner les pages à remplacer se base sur le FIFO avec seconde chance. Ensuite l'on se trouve à un autre niveau de gestion de mémoire car les pages venant d'être sélectionnées sont envoyé au gestionnaire approprié. Ce dernier peut se situer au niveau utilisateur ce qui permet en implémentant un algorithme de pagination approprié d'être plus performant qu'avec le gestionnaire par défaut. Si le gestionnaire au niveau utilisateur ne réussit pas diminuer le nombre de pages, c'est le gestionnaire par défaut qui est utilisé. En effet il faut veiller au meilleur rendement possible. Lorsqu'un thread a besoin des données d'un objet mémoire (un objet situé sur disque), il utilise un appel système qui contient le port identifiant l'objet en question et le gestionnaire de mémoire utilisé.  L'objet doit alors indiquer qu'il est prêt recevoir des requètes. Si un défaut de page se produit lorsque le thread veut accéder à cet objet mémoire, ce thread est alors placé dans un état d'attente. Une fois que toutes les tâches ne veulent plus envoyer de données vers cet objet, le noyau libère le port associé à l'objet et donc libère la mémoire utilisée par l'objet.

L'utilisation de mémoire partagée permet en générale une communication interprocessus plus rapide ainsi qu'une gestion plus aisée du multiprocesseur et de la base de données. Il est bien sûr difficile pour des tâches situées sur des machines différentes de partager de la mémoire. Pour traiter ce problème, Mach utilise des gestionnaires de mémoires externes. Ainsi si des tâches veulent partager la même section de mémoire, ils devront utiliser le même gestionnaire.


Les serveurs de Hurd
S'exécutent dans l'espace utilisateur
Fournissent des services aux applications
Famille exec
    Comprendre l'exécutable et rendre possible son exécution
    Identification du type de binaire grâce au Binary File Descriptor
    Possibilité d'exécuter des binaires compilés pour d'autres OS ou même des autres machines (serveur d'émulation de CPU)
Afin de mieux comprendre les tâches des serveurs, voici une liste des principaux :

serveur de crash serveur magic serveur de terminal
serveur exec serveur new-fifo serveur ufs
serveur ext2fs serveur nfs serveur usermux
serveur fwd serveur null le traducteur fifo
serveur hostmux serveur pfinet le traducteur firmlink
serveur ifsock serveur pflocal le traducteur de système de fichiers ftp
serveur init serveur de processus le traducteur de lien symbolique
serveur de système de fichiers iso serveur de stockage serveur d'authentification

Les serveurs exec :

Sous les systèmes Unix classiques, l'exécution d'un programme est une suite d'étapes bien connue : l'OS réserve de la mémoire, charge l'image du binaire à partir du disque ainsi que les bibliothèques associées, procéde à une relocation du code puis lance l'exécution. Les choses se passent différemment sous Hurd. L'implantation de l'appel système execve est réparti sur plusieurs serveurs : le serveur de fichier détenant le fichier vérifie les permissions et procéde aux changements nécessaires (par exemple, si le bit setuid est posé). Un serveur exec se charge ensuite de créer une nouvelle tâche et charge l'image du programme pour lancer son exécution. En fait, plusieurs serveur exec peuvent exister sur le même système, chacun étant conçu pour supporter différents formats d'exécutables. Cela permet à Hurd d'accueillir et d'exécuter des programmes originellement développés sous d'autres systèmes voire pour d'autres machines (à la condition que le serveur exec soit capable d'émuler la machine). Les serveurs actuellement développés permettront d'exécuter des programmes pour Linux, FreeBSD, Solaris, SCO et MS-DOS.

Le serveur d'authentification :

Le serveur d'authentification permet l'authentification des utilisateurs pour les tâches désirant communiquer entre elles. Une tâche voulant vérifier l'identité d'une autre tâche se connecte sur un port du serveur d'authentification et utilise ses services. Ce serveur est donc au centre du mécanisme de sécurité de Hurd. Pour autant, il ne s'agit que d'un serveur comme les autres. Un utilisateur peut développer et exécuter son propre serveur. Les autres utilisateurs seront libres de l'utiliser s'ils lui font confiance ou de l'ignorer. Bien sûr, au démarrage, le serveur de sécurité est le seul habilité à autoriser une connexion d'un utilisateur.

Le serveur de processus :

Le serveur de processus se comporte essentiellement comme un pont entre le concept de processus Unix et le concept de tâches Mach. En effet, les tâches Mach ne fournissent pas toutes les fonctionnalités du concept POSIX des processus. Ces fonctionnalités manquantes sont fournies par le serveur de processus. Il fournit aussi des informations systèmes sur les processus. Une tâche peut ainsi s'enregistrer auprès du serveur de processus, et les autres tâches pourront obtenir des informations sur elles (cf. les commandes top et ps). Comme d'habitude, l'utilisation d'un serveur de processus est optionnelle, et un processus n'est pas obligé de s'enregistrer auprès de ce serveur. Dans ce cas, aucune information ne sera disponible à son sujet.

Le mécanisme des translators:

À la base de l'arborescence du système de fichiers se trouve la notion de translators. Il s'agit en fait d'un serveur particulier destiné à réaliser les opérations possibles sur un fichier (ouverture, lecture, écriture, ...). L'intérêt des translators est de dissocier la notion de fichiers de celle de données stockées sur un support. On peut donc, grâce à une commande nommée settrans, faire en sorte qu'un noeud quelconque de l'arborescence représente n'importe quoi. Imaginons une archive bz2 qui se comporterait comme un répertoire. Les programmes pourraient se déplacer dedans, effacer ou créer des fichiers. La compilation se ferait directement "dans" l'archive, sans que GCC ne s'aperçoive de rien. Il faut bien comprendre que l'archive n'est pas affichée comme  un répertoire mais est un répertoire.
Mais les noeuds de l'arborescence peuvent représenter bien d'autres choses : un SGBD ou même un processus. Il suffit alors de lire et d'écrire dans ce fichier pour communiquer avec la tâche, sans se préoccuper des mécanismes IPC.
Enfin, des translators destinés à gérer les protocoles Internet sont d'ores et déjà implantés. Le plus connu est le FTP transparent où un site FTP est projeté dans un répertoire. L'utilisateur n'a qu'à se déplacer à l'intérieur des sous-répertoires et à copier les fichiers, sans avoir à connaître la moindre commande FTP. Ce mécanisme est prévu pour d'autres protocoles tels que HTTP et SMTP. De tels translators utilisés avec une interface graphique telle que Motif ou GNOME permettront d'obtenir un système réellement intuitif et orienté utilisateur.
Enfin, il faut noter que, sauf interdiction explicite, n'importe quel utilisateur peut poser un translator sur un noeud de l'arborescence et bien sûr développer ses propres translators.


Conclusion