|
@@ -7,13 +7,13 @@ utilisables.
|
|
|
\subsection{Les canaux unix}
|
|
|
|
|
|
Les canaux unix ou pipes unix permettent de réaliser une communication
|
|
|
-multi-processus unidirectionnel. D'un côté, un producteur écrit dans le tube,
|
|
|
+multi-processus unidirectionnelle. D'un côté, un producteur écrit dans le tube,
|
|
|
ou bloque jusqu'à ce qu'il puisse avoir la place d'écrire. De l'autre côté, un
|
|
|
-consommateur lit dans le tube ou bloque si aucune données n'est disponible. Les
|
|
|
-canaux unix ont l'avantage d'être très facile à manipuler et être globalement
|
|
|
-disponible sur toutes les plateformes importantes sans exception. Néanmoins, il
|
|
|
+consommateur lit dans le tube ou bloque si aucune donnée n'est disponible. Les
|
|
|
+canaux unix ont l'avantage d'être très faciles à manipuler et être globalement
|
|
|
+disponibles sur toutes les plateformes importantes sans exception. Néanmoins, il
|
|
|
ne s'agit que du transfert de données et il faut donc un mécanisme d'accès pour
|
|
|
-les ressources. Les canaux Unix peuvent être créés de façon anonymes avec la
|
|
|
+les ressources. Les canaux Unix peuvent être créés de façon anonyme avec la
|
|
|
fonction \inltype{pipe}, soit être nommés via la fonction \inltype{mknode} ou
|
|
|
\inltype{mkfifo}.
|
|
|
|
|
@@ -30,31 +30,31 @@ passerelle et un contrôle d'identité pour pouvoir l'utiliser dans notre cas.
|
|
|
\subsection{Les mémoires partagées}
|
|
|
|
|
|
Les mémoires partagés POSIX fournissent un moyen de communication extrêmement
|
|
|
-performants pour dialoguer. Elles ont besoin d'un mécanisme de synchronisation
|
|
|
-mais n'ont absolument pas besoin de passer par des appels systèmes hormi pour
|
|
|
-leur création. C'est donc un candidat de choix pour une communication entre
|
|
|
-deux processus. En revanche, elle demande l'introduction de beaucoup de
|
|
|
-contrôle autour pour éviter les bogues classiques en C, les dépassements, les
|
|
|
-écrasements et les ressources ne peuvent être transmises qu'à travers un autre
|
|
|
+performant pour dialoguer. Elles ont besoin d'un mécanisme de synchronisation
|
|
|
+mais n'ont absolument pas besoin de passer par des appels systèmes hormis lors
|
|
|
+de leur création. C'est donc un candidat de choix pour une communication entre
|
|
|
+deux processus. En revanche, elle demande l'introduction de beaucoup de contrôle
|
|
|
+autour pour éviter les bogues classiques en C (dépassements ou écrasements de
|
|
|
+mémoire) et les ressources ne peuvent être transmises qu'à travers un autre
|
|
|
mécanisme ou une redirection d'IO vers la mémoire partagée.
|
|
|
- %TODO: expliquer redirection au dessus en citant la partie général:
|
|
|
-%qqun fait les IO et redirige le résultat sur la shared memory
|
|
|
+ %TODO: expliquer redirection au dessus en citant la partie général: qqun
|
|
|
+%fait les IO et redirige le résultat sur la shared memory
|
|
|
|
|
|
\subsection{Les primitives Sys V}
|
|
|
|
|
|
-Les alternatives Sys V des méthodes citées ci-dessus. Malheureusement, les
|
|
|
-primitives de Sys V fonctionnent avec leur propre API et ne se rapproche pas de
|
|
|
-la philosophie unix du tout. Ces API fournissent un objet Sys V au lieu d'un
|
|
|
-descripteur de fichier et bien qu'étant compatible plus facilement avec
|
|
|
-d'autres systèmes de part son ancienneté, nous allons voir que les alternatives
|
|
|
-apportent bien plus d'avantages.
|
|
|
+Sys V fournit des alternatives pour chacune des méthodes citées ci-dessus.
|
|
|
+Malheureusement, les primitives de Sys V fonctionnent avec leur propre API et ne
|
|
|
+se rapprochent pas du tout de la philosophie unix. Ces API fournissent un objet
|
|
|
+Sys V au lieu d'un descripteur de fichier et bien qu'étant compatibles plus
|
|
|
+facilement avec d'autres systèmes grâce à son ancienneté, nous allons voir que
|
|
|
+les autres solutions apportent bien plus d'avantages.
|
|
|
|
|
|
\subsection{Les sockets unix}
|
|
|
|
|
|
Les sockets unix permettent d'envoyer des messages, soit de façon segmentée
|
|
|
avec les mécanismes de «end of record», soit par l'envoi de datagrammes. Les
|
|
|
performances en tant qu'IPC sont les mêmes que les deux premières méthodes,
|
|
|
-mais les sockets Unix disposent d'une caractéristique unique qui correspondent
|
|
|
+mais les sockets Unix disposent d'une caractéristique unique qui correspond
|
|
|
très exactement à notre problème. Ils disposent d'un moyen de transmettre des
|
|
|
descripteurs de fichiers d'un processus à l'autre, en y joignant le message qui
|
|
|
permet d'interpréter la ressource. Cette interface est néanmoins difficile à
|
|
@@ -62,21 +62,23 @@ manipuler comme on va le voir dans la suite.
|
|
|
|
|
|
\subsection{Choix de la solution}
|
|
|
|
|
|
-La solution qui s'applique le plus simplement à notre solution tout en
|
|
|
-conservant des performances correctes apparait clairement comme étant les
|
|
|
-sockets unix. Ils fournissent unes permettant d'apporter la gestion des accès.
|
|
|
-Ils fournissent également un moyen de transférer des descripteurs de fichiers
|
|
|
-entre processus.
|
|
|
+L'IPC qui s'applique le plus simplement à notre solution tout en conservant des
|
|
|
+performances correctes apparait clairement comme étant les sockets unix. Ils
|
|
|
+fournissent une interface de transfert plus intéressante et mieux contrôlable,
|
|
|
+mais surtout permettent de transférer des descripteurs de fichiers entre
|
|
|
+processus. Ce dernier point permet une gestion des accès et des ressources
|
|
|
+particulièrement fine et va être à la base de mon implémentation Linux.
|
|
|
|
|
|
\section{Partage de ressources entre processus}
|
|
|
\subsection{Objectifs}
|
|
|
|
|
|
-Ensuite, nous allons implémenter le transfert de descripteur de fichier
|
|
|
-entre processus. L'objectif derrière cette fonctionnalité est de pouvoir
|
|
|
-utiliser les descripteurs de fichier comme des jetons inforgeables qui apportent
|
|
|
-des accès aux ressources, soit par communication, soit par accès direct.
|
|
|
+Profitant de la caractéristique des sockets unix, nous allons implémenter le
|
|
|
+transfert de descripteur de fichier entre processus. L'objectif derrière cette
|
|
|
+fonctionnalité est de pouvoir utiliser les descripteurs de fichier comme des
|
|
|
+jetons inforgeables qui apportent des accès aux ressources, soit par
|
|
|
+communication, soit par accès direct.
|
|
|
|
|
|
-L'implémentation finale de ce système est fortement inspirée des techniques
|
|
|
+L'implémentation technique de ce système est fortement inspirée des méthodes
|
|
|
utilisées initialement par Nginx. Nginx est un serveur web et proxy inverse
|
|
|
programmé avec un paradigme asynchrone. Comme pour la sandbox, il fonctionne
|
|
|
avec un processus orchestrateur qui contrôle les processus serveurs, ou workers.
|
|
@@ -85,12 +87,11 @@ Chaque worker fonctionne en tant qu'utilisateur non privilégié.
|
|
|
Cette solution doit être compatible avec le bus de communication que l'on veut
|
|
|
mettre en place.
|
|
|
|
|
|
-Les sockets unix sont une solution de communication inter-processus
|
|
|
+Les sockets unix sont alors bien la solution de communication inter-processus
|
|
|
correspondant parfaitement au problème. Ils sont gérés efficacement, peuvent
|
|
|
-être anonyme et donc parfaitement contrôlés et sont représentés dans le
|
|
|
-programme par des descripteurs de fichiers. Nous allons également voir dans la
|
|
|
-suite qu'ils permettent également de transférer les descripteurs de fichier
|
|
|
-grâce à un mécanisme de données auxiliaires.
|
|
|
+être anonymes et donc parfaitement contrôlés et sont représentés dans le
|
|
|
+programme par des descripteurs de fichiers, permettant ainsi de les transmettre
|
|
|
+entre processus.
|
|
|
|
|
|
\subsection{Envoi de données}
|
|
|
|
|
@@ -116,17 +117,18 @@ struct msghdr {
|
|
|
Il y a en réalité deux types de buffers envoyés via cette structure. Le premier
|
|
|
type concerne \inltype{msg_iov} qui est en réalité un tableau de
|
|
|
\inltype{iovec}. Chaque \inltype{iovec} contient un pointeur vers un buffer et
|
|
|
-une taille. Ces \inltype{iovec} représentent les données qui seront envoyés à
|
|
|
+une taille. Ces \inltype{iovec} représentent les données qui seront envoyées à
|
|
|
travers le socket. Le fait que \inltype{msg_iov} soit un tableau de ces buffers
|
|
|
-vient du fait que le système va devoir faire des copies à travers les noyaux et
|
|
|
-donc qu'il est plus efficace de ne le faire qu'une fois si les données que l'on
|
|
|
-veut envoyer sont séparés de base.
|
|
|
+permet d'éviter de copier un paquet morcelé côté utilisateur avant de le
|
|
|
+recopier du côté du noyau.
|
|
|
|
|
|
-L'autre buffer est en réalité dédié à la pile logicielle manipulant le socket
|
|
|
-dans le noyau. Il s'agit d'un buffer de configuration, ou pour reprendre le
|
|
|
-vocabulaire utilisé dans la structure, un buffer de contrôle de l'interface bas
|
|
|
-niveau. Il peut être utilisé pour donner des paramètres dépendant de chaque type
|
|
|
-de socket.
|
|
|
+L'autre tampon mémoire est en réalité dédié à la pile logicielle manipulant le
|
|
|
+socket dans le noyau. Il s'agit d'un buffer de configuration, ou pour reprendre
|
|
|
+le vocabulaire utilisé dans la structure, un buffer de contrôle de l'interface
|
|
|
+bas niveau. Il peut être utilisé pour donner des paramètres dépendants de chaque
|
|
|
+type de socket. Pour les sockets unix, cela va permettre de manipuler
|
|
|
+l'interface SCM (socket control message) qui est capable de copier les
|
|
|
+descripteurs de fichier.
|
|
|
|
|
|
\begin{code}{c}{Structure \inltype{cmsghdr} représentant un élément auxiliaire}
|
|
|
/* from man 3 cmsg */
|
|
@@ -166,10 +168,10 @@ macros suivantes pour manipuler ce buffer.
|
|
|
données.
|
|
|
\end{itemize}
|
|
|
|
|
|
-Deux problématiques ont due être prise en compte lors de l'utilisation de cette
|
|
|
+Deux problématiques ont dû être prises en compte lors de l'utilisation de cette
|
|
|
API. D'un côté, il faut faire attention aux accès non alignés. De l'autre, il
|
|
|
faut respecter les règles de strict aliasing, c'est-à-dire qu'il ne doit pas
|
|
|
-exister deux pointeurs de type incompatible vers le même espace mémoire. Tout
|
|
|
+exister deux pointeurs de types incompatibles vers le même espace mémoire. Tout
|
|
|
cela va se résumer à correctement suivre les recommandations de l'API tout en
|
|
|
utilisant \inltype{memcpy} pour copier les données depuis et vers le tampon
|
|
|
mémoire.
|