Bläddra i källkod

chapters/linux_*: corrections

Alexandre Janniaux 6 år sedan
förälder
incheckning
d5889064f3
2 ändrade filer med 56 tillägg och 54 borttagningar
  1. 8 8
      chapters/linux_eventloop.tex
  2. 48 46
      chapters/linux_file_descriptor.tex

+ 8 - 8
chapters/linux_eventloop.tex

@@ -10,11 +10,11 @@ complexité.
 
 \subsection{poll, select}
 
-Parmis les solutions pour manipuler plusieurs descripteurs de fichier en même
+Parmi les solutions pour manipuler plusieurs descripteurs de fichier en même
 temps, les solutions classiques sont \inltype{poll} et \inltype{select}. Les
 deux fonctions marquent leur ancienneté par une mauvaise complexité
 algorithmique dans leur exploitation, c'est-à-dire un temps linéaire en le
-nombre de descripteur lors de l'attente d'un événement.
+nombre de descripteurs lors de l'attente d'un événement.
 
 Dans un premier temps, nous allons voir \inltype{poll}, à qui nous pouvons
 indiquer l'ensemble des événements à surveiller et qui nous signalera lorsque
@@ -26,7 +26,7 @@ notification n'est cependant pas précisé et il faut parcourir le tableau des
 int poll(struct pollfd *fds, nfds_t nfds, int délai);
 \end{code}
 
-Cette méthode est aujourd'hui relativement remplacée pour \inltype{epoll} et ne
+Cette méthode est aujourd'hui relativement remplacée par \inltype{epoll} et ne
 nous intéressera pas.
 
 Ensuite, \inltype{select} fournit le même mécanisme en indiquant par des
@@ -55,8 +55,8 @@ données reçues. Il faut néanmoins accepter la déception et voir que c'est
 parfois aussi coûteux que de faire la copie, particulièrement sur les
 transmissions de petite taille.
 
-L'API est implémenté en userland dans glibc, est relativement coûteuse et ne
-permet d'attendre la première opération qui aurait terminée comme le permettait
+L'API est implémentée en userland dans glibc, est relativement coûteuse et ne
+permet d'attendre la première opération qui aurait terminé comme le permettait
 les primitives précédentes. Ell est également difficile à utiliser car les
 notifications sont reçues sous forme de signal, de nouveau thread ou ne sont
 pas envoyées. Elle est donc inutilisable pour notre application mais vaut le
@@ -91,7 +91,7 @@ Linux fournit depuis assez récemment un mécanisme bien plus performant et avec
 une interface bien plus proche des autres API standards. Ce mécanisme, epoll, a
 longtemps été critiqué car bien qu'étant le dernier des mécanismes permettant ce
 genre de programmation sur événement, il reproduisait des problèmes d'interface
-qui avaient été résolu par les solutions précédentes sur les autres systèmes
+qui avaient été résolus par les solutions précédentes sur les autres systèmes
 depuis longtemps. C'est notamment des développeurs chez Nginx qui ont remonté
 des problèmes dans leur utilisation qui a abouti à l'ajout de
 \inltype{EPOLLEXCLUSIVE} dans le noyau Linux 4.5.
@@ -101,8 +101,8 @@ des descripteurs de fichiers, utilisable facilement pour construire notre
 implémentation du modèle par complétion.
 
 La complexité est en $O(1)$ et elle n'a pas de limitation sur le nombre de
-descripteur autre que la consommation mémoire. C'est aussi la méthode de
-remplacement privilégié pour \inltype{poll} et en concurrence directe avec les
+descripteurs autre que la consommation mémoire. C'est aussi la méthode de
+remplacement privilégiée pour \inltype{poll} et en concurrence directe avec les
 AIO de la sous-section précédente.
 
 \begin{code}{c}{API de epoll décrite dans man 2 epoll}

+ 48 - 46
chapters/linux_file_descriptor.tex

@@ -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.