Forum Linux.noyau Déléguer une requête à un driver pré-existant

Posté par .
3
23
mar.
2012

Bonjour,
Je suis actuellement sur un projet portant sur une hybridation SSD/HDD. Nous avons choisi d'implémenter un driver qui se situerait "au-dessus" des deux drivers spécifiques à l'hdd et au ssd et qui leur déléguerait les requêtes reçues. Ceci pouvant être fait en attribuant la structure du périphérique à la requête pour que celle ci soit traitée par le driver associé.
Notre problème étant le fait de pouvoir récupérer la structure du périphérique décrite dans le driver. Nous sommes totalement coincé sur ce point.
On a beaucoup cherché, notamment dans le livre lld3 ("linux device driver" 3e édition), et sur des forums internet mais les deux solutions trouvées impliquaient le fait de modifier les sources des drivers spécifiques (sd.c par exemple) ce qui n'est pas souhaité par notre "client".
Y aurait-il quelqu'un qui puisse nous aider dans notre démarche ?

  • # FUSE

    Posté par . Évalué à 2.

    il me semble qui si tu ne peux pas toucher au noyau, il faut alors jouer avec FUSE.

    ton logiciel cause alors à Fuse, qui cause à ton logiciel, qui cause au driver du noyau.
    tu n'as alors plus qu'a savoir que /dev/sda c'est ton SSD, /dev/sdb c'est ton HDD

    ton logiciel fournit alors un /dev/mondisk et se charge de gerer le reste.

    • [^] # Re: FUSE

      Posté par . Évalué à 1.

      FUSE: Filesystem in Userspace

      Il parle plutôt d'un hack du driver de disque et non autour du vfs …

      • [^] # Re: FUSE

        Posté par . Évalué à 3.

        le fait de modifier les sources des drivers spécifiques […] n'est pas souhaité par notre "client".

        à defaut de pouvoir le faire dans l'espace noyau, il ne reste guere que l'espace utilisateur pour le faire, et c'est justement là que FUSE repond à sa contrainte

        • [^] # Re: FUSE

          Posté par . Évalué à 1.

          le fait de modifier les sources des drivers spécifiques […] n'est pas souhaité par notre "client".

          Ça ne veut pas dire que ce n'est pas faisable : l'interface des netdevice permet "d'étendre" leur définition avec des donnés (privées) qui sont spécifiques à chaque driver réseau. Je pense que c'est aussi faisable pour les disques.

          à defaut de pouvoir le faire dans l'espace noyau, il ne reste guere que l'espace utilisateur pour le faire, et c'est justement là que FUSE repond à sa contrainte.

          Pas terrible quand même : faire retransiter les données vers le userspace pour ensuite remonter vers le kernel puis vers les drivers disques va être quelque peu coûteux en recopie de buffer … Et si tu prétends le contraire, c'est juste de la mauvaise foi ;) .

    • [^] # Re: FUSE

      Posté par . Évalué à 8.

      Sans passer par FUSE, ça semble être un genre de multidisks qu'ils veulent faire, écrire un nouveau target pour le pilote MD du noyau ne serait pas la solution ?

      • [^] # Re: FUSE

        Posté par . Évalué à 1.

        Nous pouvons écrire au niveau du noyau mais le fait d'insérer des lignes de code dans d'autres drivers comme sd.c (pour utiliser la méthode de l'export symbol) n'est pas voulu par notre client car il devrait recompiler le module à chaque changement ou mise a jour.
        L'utilisation de FUSE est a mon avis trop haut niveau et cela serait trop couteux. Le but de ce projet est en fait d'avoir un hdd qui gererait le stockage de masse et entre le systeme et le hdd, le ssd simulerait une sorte de cache. Ainsi on pourrait bénéficier de la vitesse du ssd avec la capacité d'un hdd.
        On était plus parti sur le fait de réimplémenter une fonction make_request en utilisant une struct bio (relative à la requete qu'un driver reçoit) en lui spécifiant la structure du device (SSD ou HDD) afin qu'elle soit traitée par son driver spécifique.
        Mais c'est justement au niveau de la récupération de cette structure que ça bloque.

        • [^] # Re: FUSE

          Posté par . Évalué à 4.

          Nous pouvons écrire au niveau du noyau mais le fait d'insérer des lignes de code dans d'autres drivers comme sd.c (pour utiliser la méthode de l'export symbol) n'est pas voulu par notre client car il devrait recompiler le module à chaque changement ou mise a jour.

          pour palier à ca, sur les debian like, il y a DKMS qui permet de recompiler des modules au lancement s'ils n'existent pas encore.

          c'est utilisé par Nvidia, par Virtualbox…

          • [^] # Re: FUSE

            Posté par (page perso) . Évalué à 3.

            Et sur les pas Debian-like aussi…
            DKMS avait été écrit par Dell pour RH en 2003… Mandrake/Mandriva l'utilise depuis 2004 ou 2005, le support .deb est arrivé quelques années plus tard…

        • [^] # Re: FUSE

          Posté par . Évalué à 1.

          Si c'est vraiment un besoin de cache, pourquoi ne pas placer le swap sur ce SSD, et régler les paramètres de swap pour que les écritures ne se fassent qu'au bon moment ?

          • [^] # Re: FUSE

            Posté par . Évalué à 1.

            On a regardé ce que tu proposais. Peut-on utiliser le swap pour écrire les "données cache" sur un disque ? Dans notre projet, le ssd sert de cache mais non volatile. On doit le retrouver lorsque le système se rallume.
            N'y a-t-il pas un moyen de récupérer cette structure device ?

            • [^] # Re: FUSE

              Posté par . Évalué à 0.

              Le swap est la zone de stockage temporaire des données (car la mémoire a été saturée) ; il faut voir le swap comme de la mémoire vive : si le système a prévu d'enregistrer la donnée sur le disque, alors il va forcément le faire (au plus tard au moment de l'arrêt du système). Le passage par le swap est juste une commodité offerte au noyau lorsqu'il n'y a plus de mémoire vive disponible.

              Il est possible de paramétrer ce swap (et les règles d'écriture sur disque), et je serai étonné qu'il n'y ait pas des options sophistiquée ; par exemple autrefois il était possible de mettre deux swaps sur deux disques différents et ainsi profiter de la parallélisation.

              C'est juste une piste qui elle ne coûterait pas grand chose en ingéniérie.

          • [^] # bcache ≠ swap

            Posté par . Évalué à 0.

            Le swap linux utilise un bout de partition pour soulager la RAM, donc il ne va pas chercher à mettre en cache un fs qui est sur le même disque.
            Mais si on l'utilise avec un working set qui dépasse la RAM, au lieu de faire ramer la machine comme avec un swap normal, on va se retrouver avec une activité intensive qui va assez vite faire expirer le SSD.

            Pour donner une meilleure analogie, ce projet semble similaire au patch Bcache, au L2ARC / cache devices de zfs, à diverses solutions qui se branchent dans la couche ntfs de windows (intel smart response entre autres), et aux Momentus XT de Seagate (mais ces derniers voient la flash directement, pas au travers d'une émulation HDD).

      • [^] # Re: FUSE

        Posté par . Évalué à 2.

        Pour appuyer la chose, sans aller jusqu'au noyau cependant, il semble y avoir une solution purement userspace avec mdadm:

        (http://www.technotes.se/?p=1732)

        If performance is very important together with redundancy, it is possible to create a persistent RAM disk. Getting immense speed and keeping data after system reboot is the advantage. Linux has support for exposing a portion of the RAM memory by using the /dev/ram devices. This kind of block device can be used together with a regular disk partition (e.g. /dev/sdb1) when creating a RAID volume. The RAM disk gives the speed and the other disk gives persistence. What’s important is that the array’s primary device is the RAM disk, otherwise the speed boost isn’t achieved. The primary device is the device that at a given point in time defines what data the other disk should replicate (the first device specified to the mdadm tool below).

        The default RAM disk size in Linux is 4096 kB. That is too small so it needs to be changed in the kernel. I tested this with a 1000MB RAM disk (1024000 kB). The kernel option CONFIG_BLK_DEV_RAM_SIZE can be found here:
        Device Drivers —> Block devices —> Default RAM disk size (kbytes)

        Creating the persistent RAM disk (assuming /dev/ram0 and /dev/sdb1 have the same size):
        mdadm --create /dev/md1 --level=raid1 --raid-devices=2 /dev/ram0 /dev/sdb1

        After reboot the RAM disk is blank. This means that the array needs to be started with only a single member. Then when adding the RAM disk to the array the system restores its data. To get the order right (to get proper speed), the regular disk is removed making the RAM-disk the primary. Finally it is added back again and becomes a secondary device.

        The –run option to mdadm tells the tool to start the array even if only a single device is specified:
        $ mdadm --assemble --run /dev/md1 /dev/sdb1
        $ mdadm /dev/md1 --add /dev/ram0
        $ sleep 60 # wait for the RAM disk device to become active in the raid
        $ mdadm /dev/md1 --fail /dev/sdb1
        $ mdadm /dev/md1 --remove /dev/sdb1
        $ mdadm /dev/md1 --add /dev/sdb1

        • [^] # Re: FUSE

          Posté par . Évalué à 3.

          l'idée est interessante, mais il se passe quoi si je veux faire un disque raid de 500Go ?
          il me faut un /dev/ram0 de 500Go ?

          ou ca marche comme un buffer ?

          • [^] # Re: FUSE

            Posté par . Évalué à 1.

            si tu remplaces le /dev/ram0 par /dev/"ssd0" et tu as une solution à la requête initiale.
            Après, c'est vrai qu'avoir mon / monté RAID1 entre /dev/ram0 et /dev/"ssd0" m'a traversé furtivement l'esprit.

            • [^] # Raid 1

              Posté par . Évalué à 1.

              La manip est décrite ici, ça a l'air de bien marcher: http://www.tansi.org/hybrid/

              Le HDD est marqué comme write-mostly pour que les lectures soient faites par le SSD. C'est moins intéressant qu'un Bcache parce qu'on ne peut pas tirer parti de l'asymétrie des tailles; des données peu accédées sont répliquées, et le système de fichiers est limité à la taille du SSD.

  • # Mes 2 cts

    Posté par . Évalué à 3. Dernière modification le 26/03/12 à 11:07.

    Bonjour, désolé mais je n'ai pas vraiment de bonne solution à proposer. Si je comprend bien le projet est de faire en soft (à plus grande échelle ) ce que fais seagate dans sa gamme momentus (avec un hardware dédié).

    Le problème que vous rencontrez est qu'une structure qui vous est nécessaire n'est pas rendue "public" par les drivers actuel ssd/hdd.

    Dans ce cas la je ne vois que deux solutions
    1°/ Modifier le code existant (ce qui n'est pas acceptable dans votre cas)
    2°/ Demander (en le justifiant) la modification du driver actuel par son mainteneur pour que les prochaines versions du kernel intègre cette modification.

    Essayer de hacker le kernel pour recuperer quoi qu'il en coute un acces qui n'est pas autoriser a une variable ou une fonction c'est s'exposer a de grand soucis par la suite, je vous préviens tout de suite !!!!!
    Mais si jamais ca vous tente quand même c'est possible car en kernel-space tout les drivers sont dans le même espace d'adressage
    http://onebitbug.me/introducing-linux-kernel-symbols
    section "How to access non-exported symbol"
    je vous conseille de lire les régles de nomages du linker de gcc pour être à l'aise.

    • [^] # Re: Mes 2 cts

      Posté par . Évalué à 2.

      Merci encore pour ta réponse. Tu as exactement cerné le problème.
      Je ne pense pas que ta deuxième solution puisse être réalisable dans les temps (notre projet se termine en mai).
      Nous allons nous pencher sur ton lien.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.