BabelOS (was Re: [Kos-dev] developpement de babel... abstraction (suite))

d2 kos-dev@enix.org
12 Jul 2001 11:39:21 +0200


Bonjour,

>>>>> "Julien" == Julien Munier <munier@wanadoo.fr> writes:
    Julien> comme vient de le rappeler Fabrice :
    >> Je dirais plutot "Tout est un stream de bytes".
    Julien> Je pense qu'il faut s'appuyer sur ce 'postulat' de "flot
    Julien> de bits".

C'est pas faux. Mais ca nous avance pas beaucoup. Ca serait comme
dire : "tout est "particule", donc etablissons toutes les lois
macroscopiques de la physique sur la base de la physique des
particules". C'est satisfaisant pour les phenomenes microscopiques
(etude de la matiere) ou cosmologiques (etude de l'evolution de
l'univers). Mais c'est pas suffisamment efficace ni pratique pour
modeliser les phenomenes macroscopiques classiques (chute des corps,
thermodynamique, ...). Pour ces phenomenes ni trop fins, ni trop
grossiers, c'est plus pratique de recourir a une abstraction du monde
de plus haut niveau. Meme si, dans le cas de la physique, ca revient a
faire des approximations.

Je pense que c'est dans ce meme esprit qu'on a besoin de partir d'un
niveau d'abstraction plus precis, moins general. Essentiellement parce
que, au niveau du noyau, on n'a pas l'intention de gerer des "flux de
bits". Le noyau gere des ressources (cpu, memoire, disques,
peripheriques, ...). Le boulot de l'interface cpl3<->cpl0 est donc de
prorposer un moyen de representer et d'agir sur les ressources gerees
par le noyau.

Il faut partir sur cette base, et non pas chercher l'abstraction
ultime, celle qui sera peut-etre utile aux applications, mais /que/
aux applications entre elles (style CORBA, ...).

Bon, bref, vous l'aurez compris, c'est pas le terme "objet" tout a
fait general qui me gene. C'est de dire "tout est flux de
bits". Faudrait revoir la citation de Linus, mais il devait y avoir
des smileys ou du 2nd degre derriere. En general, Linus n'aime les
flux de bits *que* a la condition qu'ils ne soient pas "generaux",
mais bien formates, standardises, utilises dans des formes
normalisees. Dans ce sens la, j'admets.

Je veux bien qu'on definisse Babel, aka broker generique. Mais faut
penser a le specialiser *des maintenant* pour la gestion OS. "BabelOS"
dans la suite. Ca nous aidera a eviter de trop extrapoler sur la
genericite (non)souhaitee de Babel. J'explique dans la suite ce que
j'entends par BabelOS.

    Julien> si tout est un flot de bits, il est bien entendu qu'avec
    Julien> ca on ne va pas loin. il est necessaire de structurer ces
    Julien> flots pour en faire quelque chose de coherent et de
    Julien> comprehensible.

J'abonde.

    Julien> le concept d'objet me semble a ce titre particulierement
    Julien> interessant car il laisse au principe de flot sa
    Julien> liberte. j'entends pas la qu'un flot de bits peut
    Julien> representer n'importe quoi, mais qu'une structure trop
    Julien> rigide comme celle du tout fichier a la unix, prive les
    Julien> flots de cette polyvalence. au contraire le simple concept
    Julien> d'objet qui lui laisse toute sa liberte.

La, je suis pas franchement chaud. "Liberons l'objet", soit, mais pas
trop quand meme. Je comprends bien que tu veuilles une architecture
objet qui nous contraigne le moins possible. Mais il faut garder a
l'esprit que cette absence de contrainte ne doit pas etre
"absolue". Sinon, on va vite se retrouver tout perdu, a refaire sans
arret les memes wrappers. Il faut des maintenant penser a BabelOS. Ca
nous aidera a definir Babel plus precisement.

En fait, je percois que ce que tu veux derriere, c'est une classe
racine qui ne dispose que des methodes d'introspection et
d'identification, et pas de methodes pre-definies style
read/write. Si c'est ca, j'ai exactement la meme vision des choses
*pour Babel*.

Ca, on l'a deja en partie (Babel). En tous cas, on a idee de ce a quoi
on veut que ca serve (repertoire d'interface, moyen d'identifier,
reste l'introspection et la verification des types). Maintenant, il
faut definir la methode d'action sur les ressources gerees par le
noyau en utilisant l'infrastructure Babel de base : BabelOS.

    Julien> je pense qu'il faut etre prudent, il ne faut definir une
    Julien> structure rigide du concept d'objet, il doit au contraire
    Julien> disposer d'une structure la plus flexible possible. en
    Julien> realite, il ne s'agit meme pas de definir la structure de
    Julien> l'objet mais d'en donner l'unite fondamentale qui permet
    Julien> de le reconnaitre en tant qu'objet.

C'est ce que j'appelais root_interface.

    Julien> a travers babel, il s'agit de mettre en forme ce concept,
    Julien> il faut trouver un moyen de structurer le flot sans
    Julien> l'empecher de representer n'importe quoi.

J'aime pas le "n'importe quoi" (dans le sens "flux de bits") : le
noyau va faire n'importe quoi si il doit gerer du "n'importe quoi". Le
n'importe quoi en question, faut garder a l'esprit que ce sera des
ressources physiques ou logiques sur lesquelles les applications sont
en concurrence d'acces. Je pense que c'est a ca que tu pensais.

Appelons ca BabelOS, constitue d'objets Babel (aka le "n'importe quoi"
en question). BabelOS se charge de la representation et de
l'identification des ressources *systeme*.

    Julien> La notion d'interface permet de determiner l'essence, la
    Julien> nature, elle constitue un artefact dont l'instance est la
    Julien> materialisation. l'interface permet donc de structurer
    Julien> l'objet qui n'existe qu'a travers l'instance.

Voui.

    Julien> il faut donc se concentrer sur l'interface, c'est le point
    Julien> faible de babel, car c'est l'interface qui limite la
    Julien> flexibilite et la richesse de la nature de l'instance.

Voui.

    Julien> l'interface se doit de respecter l'unite fondamentale dont
    Julien> je parlais plus haut qui permettra de reconnaitre
    Julien> l'instance comme ayant une telle nature d'objet.

Voui.

    Julien> il s'agit alors de definir les fonctionnalites qui compose
    Julien> cette unite fondamentale de tout objet (=instance) : les
    Julien> plus essentielles semblent avant tout l'identification et
    Julien> l'introspection. chaque objet doit pouvoir s'identifier et
    Julien> egalement permettre de definir ses fonctionnalites. ainsi
    Julien> il peut etre reconnu et exploite par la matrice ou il
    Julien> evolue (j'englobe la le noyau comme le niveau utilisateur,
    Julien> et bien sur de maniere locale ou distante).

Je pense comprendre et meme etre d'accord.

    Julien> un objet ou instance, associe donc a une interface, un
    Julien> bloc de donnees. l'interface a pour vocation de structurer
    Julien> le bloc de donnee et de fournir les primitives qui
    Julien> permettent de le manipuler c'est a dire de l'identifier et
    Julien> d'y appliquer les methodes que l'objet peut supporter.

L'interface Babel, c'est avant tout des methodes. Ca ne devrait etre
*que* des methodes. Des donnees privees peuvent etre associees a cette
interface. Ces donnees ne devraient etre accedees (et accessibles ?)
*que* par les methodes de l'interface. Les methodes, elles, sont
accessibles par tout le monde. Il est hors de question de mettre en
place des mecanismes de protection des methodes (private, protected),
ou alors il faut utiliser un langage adapte (C++).

    Julien> si on veut y voir une analogie des class C++ (bof! comme
    Julien> analogie), l'interface definit avant tout les methodes et
    Julien> les donnees privees de ce "type" d'objet tandis que
    Julien> l'instance ajoute a ces methodes, un bloc de donnees. mais
    Julien> pour etre exacte c'est le couple methode/donnees qu'il
    Julien> faut appeler l'instance.

interface Babel = { methodes publiques, variables privees d'interface }
// Aucune methode privee, aucune variable d'interface publique

instance Babel = { lien vers interface, variables privees d'instances }
// aucune variable d'instance publique

    Julien> d'abord il ne faudrait pas se meprendre : - objet =
    Julien> instance - service = methode d'une instance (defini par
    Julien> l'interface) enfin, je parle ici des definitions donnees
    Julien> pour babel.

Si on fait bien la difference entre Babel (broker generique) et
BabelOS (gestion de ressources systeme), j'insiste (en changeant un
peu ma terminologie), on devrait avoir :
  - L'identifiant de l'*interface*
  - L'identifiant de l'*instance* de l'interface
  - L'identification des *ressources* gerees par l'instance
Sachant que l'interface definit les methodes dispos pour agir sur la
ressource (read/write, ou up/down, ou map/unmap, ou...). L'instance
implante (specialise) les methodes de cette interface pour les
ressource qu'il gere.

Je sais que tu es tres attache aux termes interface/instance. C'est
valable pour l'architecture Babel = la gestion d'objets. Pour BabelOS,
on doit se situer a un niveau de specialisation "en dessous",
puisqu'on doit gerer des ressources /avec/ Babel. C'est la raison pour
laquelle je ne parle plus d'instance ni d'interface dans BabelOS : les
entites manipulees sont tous geres par Babel. On remarque un mapping
fort entre classe de service et interface, et entre service et instance.

Donc, dans BabelOS, on a :

La _classe de services_ (une Interface Babel) :
  - definit les methodes de manipulation des services
  - est capable d'identifier/lister les services dont elle
    dispose
Les services (des Instances Babel de l'interface "classe de services") :
  - implantent les methodes de manipulation definies dans la classe de
    services => jouent le role de "driver"
  - sont capables d'identifier/lister les ressources dont elles sont
    responsables
Arborescence des ressources (Instances d'une interface "ressource" de
Babel) :
  - C'est une arborescence
  - donnees/peripheriques/... (noeud terminal)
  - lien vers d'autres ressources
  - repertoires de ressources (noeud non terminal)
(pour ressources, voir plus loin)

Par exemple :
  :pci:host0:/04/0           ; methodes = { j_en_sais_rien, connais_pas_pci }
  :cpu:cpu0:/frequency       ; methodes = { set, get }
  :cpu:cpu0:/cpuid/vendor_id ; methodes = { set, get }

  :ipc:shm:uid=657/5677      ; methodes = { get, op, ctl }
  :ipc:sem:uid=657/98        ; methodes = { get, op, ctl }
Mais c'est trop proche de ioctl. Autre solution plus propre (et plus
vraie) :
  :ipc/shm:uid=657:5677      ; methodes = { get, release }
  :ipc/sem:uid=657:743       ; methodes = { get, release, up, down }
Sachant que 'ipc/shm' et 'ipc/sem' sont 2 classes de services
(interfaces) differentes.

Sans oublier :
  :fs:local:/home/mejj/foo.bar         ; methodes = { read/write/seek/select }
Se charge de traduire cette requete en requete vers la ressource precise :
  :blockfs:ext2:/scsi/host0/lun0/part0 ; methodes = { read/write/seek/sync }
Sachant que scsi/host0/lun0/part0 indique a ext2 qu'il doit s'appuyer
sur la ressource (lien sous-jacent) :
  :scsi:host0:/lun0/part0              ; methodes = { je_connais_pas_scsi }

Bref, je vois l'architecture BabelOS a 2 niveaux :
  + Babel : definition de mecanismes d'identification et
    d'introspections sur les Objets + gestionnaires
    d'interfaces/instances. Generique.
  + BabelOS : Interfaces+Instances Babel :
     + Classes de services / services
     + Arborescence de ressources

Soit 2 types Babel a definir dans BabelOS.

    Julien> alors, je ne sais pas si je me trompe mais peut-etre qu'il
    Julien> y a ici un malentendu : peut-etre qu'il ne faut pas
    Julien> appeller foo.bar un objet, c'est a dire une instance. en
    Julien> effet, l'instance est /home/ la representation
    Julien> mejj/foo.bar est gere par le principe de systeme de
    Julien> fichier c'est a dire que ce classement est genere et gere
    Julien> par ext2_fs qui a pour vocation de presenter ainsi
    Julien> l'espace de donnee de l'instance /home, mais en realite
    Julien> mejj/foo.bar n'est qu'une representation, c'est en realite
    Julien> uniquement un identifiant d'un bloc de bits manipulable
    Julien> par l'instance et les primitives qui lui sont attribue par
    Julien> l'interface dont elle depend.

C'est exactement pour ca que j'ai distingue "service" et "ressource"
(ou, avec mon ancienne appellation : instance et objet).

Comme on l'a vu dans ce qui precede, je pense qu'on ne peut pas
simplement resoudre nos problemes d'OS avec un broker objet
generique. Il faut le specialiser en une petite serie (2) de types de
base, specialises pour l'OS : BabelOS. Dans ce cas, Babel nous permet
indirectement de resoudre nos problemes, via les 2 types introduits
dans BabelOS.

Le probleme dans Babel seul, c'est qu'il faut que l'arborescence des
ressources dans un service puisse contenir des liens vers des
ressources d'une autre classe de services (~ translators
hurd). L'ideal serait donc de pouvoir representer l'arborescence des
ressources de la meme facon pour tous les services, quelle que soit la
classe des services. Je vois pas de solution a ce probleme en
utilisant Babel seul. Comment avoir d'une part :
  - des services (aka drivers) qui ne sont pas franchement classes en
    arboresecence.
Et d'autres part :
  - des ressources gerees par des services qui, elles, definissent une
    arborescence
Le tout de facon uniforme (= 1 seul objet base), avec juste
specialisation (=implantation) de l'objet de base.

En clair, je ne vois pas d'exemple de sous-driver de driver. C'est la
raison des 2 classes de bases (classes de services/services +
arborescence de ressource) de BabelOS.

Pour resumer, BabelOS, ca repose sur Babel, et c'est constitue de :
  - classes de services
  - services
  - ressources sous forme d'arborescence avec 3 types de noeuds
      + noeuds terminaux ("vraies" ressources)
      + noeuds non terminaux ("repertoires")
      + renvois ("liens" ~ translators hurd)

Pour que les classes de services soient manipulables simplement, il
faut qu'on ait dans Babel la propriete "une classe est un objet". A la
maniere de Java. Sinon, on va etre oblige de definir une classe de
services comme etant une instance d'une interface "classe de
services". Or, le but ultime serait d'avoir la propriete "service est
une instance de classe de services". Ce qui n'est pas possible avec
l'infrastructure Babel de base : une instance ne peut pas etre
l'instance d'une autre instance. Il va falloir reflechir a ca pour
Babel.

    Julien> mais a proporement parler htdocs/index.html n'est qu'une
    Julien> representation d'un bloc de donnees, le fichier index.html
    Julien> n'est pas un objet qui peut spontanement invoque la
    Julien> primitive GET du protocole html.

htdocs/index.html est un objet *sur lequel* on peut invoquer la
methode GET : c'est une _ressource_ sur laquelle la *methode* GET,
*implantee* dans le _service_ 'http' et *definie* dans la
_classe de service_ 'web', peut etre invoquee.

    Julien> donc on a des instances a deux niveaux :
    Julien> une a un niveau que j'appellerai physique :
    Julien> /dev/scsi/host0/bus0/target0/lun0/part5 car il s'agit de
    Julien> l'ecriture physique des blocs de bits et une autre
    Julien> instance a un niveau plutot logique : qui associe cette
    Julien> instance 'physique' a un niveau logique : le systeme de
    Julien> fichier ext2

Je pense qu'il est necessaire de s'orienter vers BabelOS :
  - Babel + propriete "une interface est une instance de qqch"
  - BabelOS : 2 types : classes de services/services + arborescence de
    ressources

Bonne journee,

-- 
d2