[Kos-dev] Progressions du WE

Thomas Petazzoni kos-dev@enix.org
Mon, 28 Apr 2003 11:54:35 +0200


This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enig295623B153F6254706C739B4
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit

Hello,

> On voit apparaitre 2 types de ures (ie une kres ouverte avec une
> interface donnee) : ures "interne au noyau", et ures au sens habituel
> (ie figurant dans la liste des ures ouvertes par le processus). De
> meme 2 scenarios d'ouverture de kres (et d'ures) : a partir d'un nom,
> ou a partir d'une ures "interne". Je vois une difficulte importante a
> prendre en compte : si 3 processus font l'open de l'exemple a Julien,
> il faut que les 2 ures internes (celles apres ouverture suivant block
> et celle apres ouverture suivant libblockcache) correspondent a 2 kres
> seulement, et non pas a 3x2 = 6 ures (sinon le cache risque de pas
> s'en sortir s'il a pas moyen de faire simplement un lookup pour voir
> si un block demande n'a pas deja ete charge) ! Ce qui est difficile
> puisque le cache de kres jusqu'a maintenant utilisait un lookup a
> partir du nom de la kres. Desormais, le nom ne suffit pas, il faut
> prendre en compte l'empilement d'interfaces.

Effectivement, une solution que j'avais proposée à Julien permettant
l'empilement, était de créer des "ures" internes au noyau. Nous allions
presque implémenter cette solution, lorsque nous nous sommes aperçus que
la multiplication des "ures" au niveau du noyau serait difficilement
gérable, sauf si les couches du dessus dégagent à la main les "ures"
nécessaires.

Finalement, Julien semble être parti dans une solution à trois niveaux,
qui *permettrait* de résoudre le problème. Notre divergence de points de
vue a clairement eu lieu sur la chose suivante : pour Julien l'ensemble
des pointeurs de fonctions implémentant chacune des interfaces est dans
la structure de données "translator", c'est à dire que toutes les
ressources gérées par un même driver supportent toutes les interfaces.
Tandis que chez moi, l'ensemble de pointeurs de fonctions implémentant
les interfaces est dans la structure de donnée "kres", c'est à dire
qu'un même driver peut gérer des ressources qui exportent des interfaces
différentes. Ex: le driver ext2 gère une ressource /home/thomas qui
exporte DIR mais pas FILE, et une ressource /home/thomas/pouet.c qui
exporte FILE mais pas DIR.

Il semblerait qu'a un moment de la discussion il ait admis que la
granularité doive se situer au niveau de la ressource, et proposait donc
(me semble-t-il) de mettre un bitmap dans chaque ressource (un peu comme
ce qui avait été fait dans kos-dev/syscall-test en C++ avec les VMT, cf
la classe Kernel_ressource).

<disclaimer>C'est ce que j'ai compris de ce que Julien a fait et de ce
dont nous avons discuté. C'est donc une interprétation
*subjective*</disclaimer.

> Sinon, concernant la proposition de Thomas, je pense l'avoir comprise,
> elle me semble plus directe. Si j'en reste aux mails que t'as envoyes
> (et pas au code, que je n'ai pas regarde), l'idee est de laisser au
> developpeur la responsabilite de superposer les couches directement
> dans le code du driver, plutot que de demander a l'utilisateur de s'en
> charger (en precisant l'empilement de ressources). Ca me semble etre
> en accord avec un principe de base, qui est que toute la cuisine pour
> le dialogue cpl3/cpl0 (aka interfaces) soit independante de la cuisine
> interne au noyau concernant la gestion de ressources (faudra qu'on me
> traduise "KARM" : KOS A*** Resource Manager ???).

Karm, je sais pas ce que ça veut dire, c'est Julien qui a choisi le nom
;-) Je suis une quiche pour choisir le nommage, donc je laisse Julien
choisir.

En ce qui concerne ma solution, elle laisse effectivement le programmeur
décider quelles interfaces il veut exporter. Pour que les drivers block
puissent exporter FILE, ils utiliseront une librairie commune. Si on
fait les gorets, on peut peut être imaginer une macro qui génère toutes
les fonctions et structures qui vont bien pour exporter l'interface FILE
à partir de BLOCK (en utilisant la libblockcache / libblockio /
libtrucbidulequifaitcequivabien).

[Barratin sur les problèmes d'appel vers le haut]

Effectivement, je n'avais pas du tout pensé à ce problème, et je pense
qu'il est assez complexe à gérer. On pourrait imaginer une solution
simpliste dans laquelle chaque niveau de la chaine peut exporter des
interfaces vers la couche du dessus, mais cela pose des problèmes : si
on imagine une chaine de la forme A -> B -> C, et que C veut dire
quelque chose à A, il doit passer par B : B doit donc réexporter vers C
toutes les interfaces exportées par A vers les couches du bas. Un sacré
merdier.

Personnellement, je suis bien séduit par une solution en empilement,
mais il faut y réfléchir, et parvenir à la résumer en quelques
structures de données simples, dont le rôle *précis* est bien défini, et
dans lequel chaque champ est *très* précisement défini.

> Voila mes premieres reflexions sur le sujet. Bien que vraiment seduit
> par l'idee de Julien, j'aimerais rappeler quand meme que "simple is
> beautiful", du moins dans un premier temps...

Oui, c'est la solution que j'ai adoptée, je pense qu'elle fonctionne,
même si elle n'est pas aussi souple. Je rappelerai quand même, que par
rapport à du Unix, la solution simple que j'ai choisie est quand même
déjà beaucoup plus souple. Je pense qu'elle permet d'implémenter à peu
prêt n'importe quoi, le tout est d'écrire les librairies de
factorisation de code correctement, mais ça c'est le boulot du programmeur.

Je poursuis ce soir en faisant en portant le module 'tty', qui pour
l'instant sera assez pourri parce qu'il se charge lui même d'écrire en
dur sur l'écran alors qu'il déporte la gestion du clavier à klavier.
Bref il faudrait un module chargé d'écrire sur l'écran, et un module
'tty' qui lui est complètement abstrait de la ou il lit et la ou il
ecrit. Donc, en fait à l'avenir j'aimerais bien pouvoir faire, dans
kos/wolfgang.c :

 struct ures *console = open("/dev/char/console",INTERFACE_CHAR_OUTPUT);
 struct ures *klavier = open("/dev/char/klavier",INTERFACE_CHAR_INPUT);

 tty_create_tty(0, console, klavier);
 tty_create_tty(1, console, klavier);
 tty_create_tty(2, console, klavier);

 struct ures *tty0 = open("/dev/char/tty0",INTERFACE_CHAR);
 struct ures *tty1 = open("/dev/char/tty1",INTERFACE_CHAR);
 struct ures *tty2 = open("/dev/char/tty2",INTERFACE_CHAR);

et ensuite créer une team par tty, initialisée de maniere a ce que les
FD 0, 1 et 2 soient corrects, puis lancer un shell utilisateur dans
chacune de ces teams.

Petite note concernant 2 interfaces :
 * Il y a maintenant une interface INTERFACE_MAPPING_ID, qui *DOIT* être
exportée par une ressource si elle veut pouvoir être mappée. Elle
contient une fonction map() et sync(). En fait, cette interface remplace
l'ancien "driver" de vmm : je préfère utiliser directement le mécanisme
des interfaces. Bien sûr, il faudra écrire une librairie de
factorisation de code, qui permet directement à partir de
l'implémentation d'une interface FILE, d'implémenter l'interface
MAPPING. Donc par exemple, dans le driver de disque, on génèrera une
implémentation de FILE à partir de BLOCK, puis une implémentation de
MAPPING à partir de FILE. J'anticipe l'éventuelle question : pourquoi on
fait pas un truc qui peut directement implémenter MAPPING à partir de
BLOCK ? Parce que ça, ça ne fonctionne que dans le cas particulier ou
BLOCK_SIZE <= PAGE_SIZE ;-)

 * Il y aura une interface INTERFACE_URES_INIT_ID, qui contiendra une
fonction init() et une fonction cleanup(). Ces fonctions seront
respectivement appelées lorsqu'une ures est crée à partir d'une kres, de
manière à ce que le driver puisse placer ses données privées (pointeur
void *ext) dans la ures. Encore ici, on aurait pu utiliser un mécanisme
externe, mais autant utiliser le système des interfaces ;)

Bonne journée,

Thomas
-- 
PETAZZONI Thomas - thomas.petazzoni@enix.org - UIN : 34937744
Web: http://www.enix.org/~thomas/
KOS: http://kos.enix.org/ - Lolut: http://lolut.utbm.info
Fingerprint : 0BE1 4CF3 CEA4 AC9D CC6E  1624 F653 CB30 98D3 F7A7

--------------enig295623B153F6254706C739B4
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQE+rPpb9lPLMJjT96cRAujRAJ0drFD9RTr1c2UIiEa10uZLpNtTxQCfWbMD
+j3LkxMq7L6WWH2VtDj+STQ=
=Hmis
-----END PGP SIGNATURE-----

--------------enig295623B153F6254706C739B4--