Clonage de processus en C

Gazette Linux n°51 — Mars 2000

Dominique Lazure

Adaptation française 

Frédéric Marchal

Correction du DocBook 

Article paru dans le n°51 de la Gazette Linux de mars 2000.

Cet article est publié selon les termes de la Open Publication License. La Linux Gazette n'est ni produite, ni sponsorisée, ni avalisée par notre hébergeur principal, SSC, Inc.


Table des matières

Introduction
Principe
Installation
Utilisation
Résumé
Références

Introduction

La mobilité logicielle peut signifier différentes choses suivant les personnes. Par exemple, l'informatique mobile est souvent assimilée à l'accès au courrier électronique sur un ordinateur portable, la migration de processus se rapporte à la redistribution automatique de la charge d'un réseau de stations, et un agent mobile décrit un processus en cours d'exécution, collectant les données avant de rapatrier un résultat complet sur un site destinataire. Le premier exemple est une extension du modèle client/serveur décrit depuis les années 1980, alors que les autres exemples, illustrant de la migration autonome de processus à travers un réseau de machines, sont des sujets de recherche pointus[1].

Les systèmes en grappes sont des ordinateurs parallèles, réseaux de stations qui présentent au client l'interface d'accès d'un unique serveur. De nombreux processus peuvent s'exécuter sur une grappe, parmi lesquels certains peuvent s'auto-dupliquer afin de répondre à un accroissement soudain du débit de requêtes des clients. Un système d'exploitation de grappes doit pouvoir inciter un ou plusieurs de ces processus à migrer vers d'autres nœuds du réseau, équilibrant ainsi la charge totale de la grappe.

Les agents autonomes sont de simples processus dont la plus efficace des descriptions est l'illustration. Considérons que vous vouliez assembler les composants les moins chers afin de construire votre ordinateur de rêves. Imaginez devoir appeler ou visiter tous les fournisseurs afin de comparer les prix des cartes mères, des disques, et des lecteurs de CD-Roms, etc. Maintenant, imaginez envoyer sur le web un agent logiciel intelligent qui se chargerait d'examiner tous les sites afin d'en rapporter la liste de tous les composants les moins chers, avec prix et URLs. Si vous lui confiez votre numéro de carte bancaire, tous ces composants pourraient arriver directement devant votre porte ! Voici l'idée.

Le tout premier problème à résoudre pour mettre en œuvre le système de migration est de définir la façon dont un processus dupliqué sera lancé à partir d'un processus actif. Ce n'est pas un simple fork distant car le nouveau processus doit pouvoir repartir au début de son exécution. Ce n'est pas un simple rsh car le code exécutable du processus n'existe par forcément sur le nœud distant. Quelles sont les techniques à utiliser ? Quelles sont les modifications à apporter au système de fichiers distant pour permettre la prise en compte d'une requête d'exécution d'une copie du processus actif ? Examinons ces questions qui définissent le clonage de processus.

Principe

L'approche consiste à développer un nouveau service et d'y associer une interface via une fonction. Le processus appèle cette fonction en précisant le nom de la machine distante. La fonction effectue la liaison via le démon d'interconnexion inetd sur un port prédéterminé de la machine distante afin de déclencher le service de clonage.

Les vieux systèmes Unix lançaient des démons pour chaque service à disposition des autres machines. Quand vous utilisiez telnet, par exemple, un démon dédié au telnet, nommé telnetd, attendait une connexion sur le port 23 de la machine distante. (Le port 23 est toujours utilisé par telnet. C'est un des nombreux ports pré-définis énumérés dans /etc/services). De par le nombre croissant de ces démons en attente de connexion, la mémoire virtuelle disponible et le nombre de processus utilisateurs devinrent limités.

Le super-démon résolvit ces problèmes en attendant une connexion sur un quelconque des ports parmi toute une liste pré-définie, et en lançant automatiquement le serveur associé au service effectivement accédé. Il suffit maintenant d'ajouter une ligne à deux fichiers pour enregistrer un nouveau service. Seul le super-utilisateur peux éditer ces fichiers et ré-initialiser inetd afin de relire ces fichiers[2].

Gardez à l'esprit que lorsque vous autorisez un processus d'une machine distante à lancer une copie de lui-même sur votre machine, vous acceptez un risque important que ce nouveau processus soit hostile. Toutes les machines de mon réseau étant sous mon contrôle, je ne suis pas concerné par ce risque. Ce problème ne sera plus discuté par la suite.

Installation

Le service doit être déclaré dans /etc/services. Ajoutez l'entrée comme suit :

clone    5050/tcp     # automatically starts cloned

clone est le nom du service, 5050 est le port pré-défini, et tcp est le protocole de transport. Nous avons choisi le port 5050 parce-qu'il est plus grand que le nombre de ports dédiés au système et qu'il était libre. (La connotation fifty-fifty de 50-50 le rendra plus facilement mémorisable).

Le service de clônage doit être défini dans /etc/inetd.conf comme suit :

clone      stream     tcp   nowait   root  /user/bin/cloned clone

clone est le nom du service précisé dans /etc/services. (Se reporter aux pages man d'inetd.conf pour la description des autres paramètres[2].) Notons que inetd ne prendra pas en compte ce nouveau service qu'au prochain reboot, ou lorsque vous lancerez une commande pour forcer la relecture de ce fichier de configuration. Pour cela, exécutez en tant que super-utilisateur la commande suivante

killall -HUP inetd

Utilisation

Votre programme fait appel à la fonction clone() avec le nom de la machine sur laquelle doit être exécutée la nouvelle copie du processus. La fonction clone() détermine le nom du processus actif en sélectionnant son propre pid dans le résultat d'une commande ps. Puis elle détermine le chemin vers l'exécutable avec la commande which.

Quand clone() se connecte sur le port 5050, inetd accepte la connexion et construit les liaisons nécessaires pour associer l'entrée standard du processus cloné au flux d'arrivée sur le port et sa sortie standard sur le flux de sortie. Le processus cloné est lancé à partir de inetd via les appels système fork() et execl()[3].

Quand le clone prend la main sur la machine distante, il lit le nom de l'exécutable qui lui est envoyé en premier. Le code exécutable reçu ensuite est écrit dans l'espace /tmp sous le même nom.

Résumé

L'application locale appelle clone() avec le nom de la machine distante. La fonction clone() se connecte au port du service de clonage, provoquant le lancement du clone sur la machine distante. Elle envoie ensuite une copie de l'exécutable vers la machine distante via le même port. La copie est déposée dans /tmp par le démon de clonage puis activée par un fork() et un execl().

Ce qui arrive ensuite est du ressort de l'application. Vous avez la possibilité d'établir une nouvelle connexion avec votre clone distant et de laisser ainsi les deux copies activées. Vous pouvez aussi mettre fin au processus local et effectuer ainsi de la migration d'agent. Vous pouvez même recopier sur une tierce machine une nouvelle version du processus à partir de la copie distante et obtenir ainsi une ribambelle de clones en réseau.

Le comportement final sera déterminé par votre application, mais le premier pas est d'arriver à rendre un processus actif sur une machine distante. Un programme test.c et le démon de clonage, cloned.c ainsi que sa fonction d'interface, clone.c sont inclus dans cet article. Tout est écrit en C et testé avec la distribution Linux RedHat version 4.2.

Références

[1] D. Milojicic. F. Douglis. R. Wheeler. Processes, Computers, and Agents, Association for Computing. Machinery Press. 1998.

[2] Voir les pages man d'Unix pour inetd et inetd.conf.

[3] W. R. Stevens. Unix Network Programming. Prentice-Hall. 1990.

Adaptation française de la Gazette Linux

L'adaptation française de ce document a été réalisée dans le cadre du Projet de traduction de la Gazette Linux.

Vous pourrez lire d'autres articles traduits et en apprendre plus sur ce projet en visitant notre site : http://www.traduc.org/Gazette_Linux.

Si vous souhaitez apporter votre contribution, n'hésitez pas à nous rejoindre, nous serons heureux de vous accueillir.