Forum Linux.noyau Pourquoi mount (le syscall) n'accepte pas un fichier ordinaire

Posté par  (site web personnel) . Licence CC By‑SA.
8
4
mar.
2022

Bonjour,

Je me demande simplement pourquoi l'appel système mount ne peut pas lire un fichier et a besoin d'un “block device”.
C'est un peu embêtant, ça m'oblige à en chercher un “block loopback", le réserver, l'associé au fichier et enfin je peux faire mon mount tranquille. Je sais le faire, c'est pas ça le problème. Je veux juste savoir pourquoi je le fais.

Je pense que le cœur de ma question c'est que je n'ai jamais compris la différence entre un “block device” et un fichier ordinaire, Les commandes cp ne semble pas voir de différence, cat non plus, dd pas plus que cp. Et par-contre l'appel système mount lui il peut pas travailler sur un fichier ? C'est quoi la différence du coup ? L'erreur associée est ENOTBLK et n'est pas très très claire.

“Block device required.” A file that isn’t a block special file was given in a situation that requires one.

Ce qui signifie qu'il y a des situations où mount accepte des fichiers normaux. Ce qui ajoute à ma confusion.

Le besoin que j'ai derrière est le montage automatique d'un ISO dans un programme embarqué. Le code est déjà fait, je veux juste comprendre ce que je fais.

Merci d'avance à vous et bonne fin de semaine !

  • # Philosophie Unix - exception ?

    Posté par  . Évalué à 3.

    Je n'ai pas la réponse à ta question car elle m'intéresse également, cela me semble être une sorte d'exception à la philosophie Unix "tous est fichier (normal ? )"

    Je me demande si ce n'est pas dû au fait que les loopback sont liées au fichiers de type ISO (genre image cd cdrom/dvdrom) et que cela serait lié au format même de l'iso ?

    Bref merci pour ta question dont j'attends également la réponse de manière impatiente

    • [^] # Re: Philosophie Unix - exception ?

      Posté par  (site web personnel) . Évalué à 9.

      Je n'ai pas la réponse à ta question car elle m'intéresse également, cela me semble être une sorte d'exception à la philosophie Unix "tous est fichier (normal ? )"

      Non, tout est dans la parenthèse, que tu as ajoutée de ton propre chef. Tout est fichier, tout court. Tout n'est pas fichier régulier.

      Je me demande si ce n'est pas dû au fait que les loopback sont liées au fichiers de type ISO (genre image cd cdrom/dvdrom) et que cela serait lié au format même de l'iso ?

      Pas tout à fait. La plupart des systèmes de fichiers sont censés être sur périphérique bloc, c'est le cas d'ISO 9660 et UDF, mais aussi d'Ext4, etc. En revanche, quelques systèmes de fichiers particuliers, comme les systèmes de fichier réseau, ou encore les tmpfs, ne demandent pas un périphérique bloc, mais quelque chose de très différent.

      Donc, en un sens, oui, c'est lieu au format ISO 9660 ou UDF, dans le sens où ce sont des systèmes de fichiers ordinaires, dont l'implémentation sous Linux nécessite un périphérique bloc, comme l'immense majorité des systèmes de fichiers.

    • [^] # Re: Philosophie Unix - exception ?

      Posté par  . Évalué à 6. Dernière modification le 04 mars 2022 à 17:07.

      la philosophie Unix "tout est fichier"

      C'est plutôt que tu peux accéder à tout en mode "fichier" via un descripteur de fichier, c'est à dire avec read() et write(), close(), parfois seek().

      Par contre l'étape de connexion à une socket réseau ou à un block device ne se fait pas tout à fait de la même façon qu'un fichier sur une partition.

      D'ailleurs, pour les sockets réseau, je ne crois pas qu'il y ait un fichier du genre /dev/net/192.168.1.2:8080 .

      Cette page l'explique un peu mieux, mais en Anglais.

  • # La commande mount l'accepte

    Posté par  (site web personnel) . Évalué à 10.

    Petite précision tout de même, si l'appel système mount(2) n'accepte pas les fichiers réguliers, la commande mount(8) les accepte, grâce à l'option -o loop, avec laquelle elle alloue automatiquement un périphérique boucle.

    Et par-contre l'appel système mount lui il peut pas travailler sur un fichier ?

    Si, mais pas sur un fichier régulier, seulement sur un fichier de type périphérique bloc. Un périphérique bloc est un fichier, d'un type particulier. Outre les fichiers réguliers, il y a plusieurs types de fichiers : répertoires, liens symboliques, tubes nommés, sockets unix, périphériques caractère, périphériques blocs, etc.

    La raison pour laquelle mount(2) a besoin d'un périphérique bloc, c'est qu'à mon avis le noyau doit vouloir accéder aux données du système de fichiers directement à des adresses mémoire. Un fichier régulier n'a rien de tel, à moins de le mapper en mémoire, et c'est justement ce que fait un périphérique boucle.

    Lorsque tu manipules des périphériques blocs avec des commandes comme cp, cat et compagnie, ces logiciels les utilisent en y faisant des appels systèmes d'ordinaire utilisés pour des fichiers réguliers, mais qui sont aussi implémentés pour les périphériques bloc, qui font en fait « plus » que des fichiers réguliers.

    • [^] # Re: La commande mount l'accepte

      Posté par  (site web personnel) . Évalué à 1.

      Petite précision tout de même, si l'appel système mount(2) n'accepte pas les fichiers réguliers, la commande mount(8) les accepte, grâce à l'option -o loop, avec laquelle elle alloue automatiquement un périphérique boucle.

      Oui j'avais remarqué ça, même sans l'option -o loop d'ailleurs. Là, j'essaye de comprendre ce que la commande mount(2) fait avec "loop/autoclear" car umount (l'appel système et la commande) ne semble pas avoir besoin de dés-associer le fichier loopback et le fichier régulier, la-dés association semble automatique.

      La raison pour laquelle mount(2) a besoin d'un périphérique bloc, c'est qu'à mon avis le noyau doit vouloir accéder aux données du système de fichiers directement à des adresses mémoire. Un fichier régulier n'a rien de tel, à moins de le mapper en mémoire, et c'est justement ce que fait un périphérique boucle.

      Humm, intéressant. Donc dans un fichier de type bloc, on a une abstraction (tête de lecture du lecteur ou micrologiciel du SSD) pour lire à une adresse précise alors que dans un fichier normal n'a pas ça.

      Que doit faire un fichier régulier pour lire à une adresse précise ? Dans mon programme, j'utilise fseek(3) (je ne connais pas le syscall associé) pour positionner le curseur au bon endroit sans avoir besoin de tout lire. Je pense que ce qui se passe lorsque je fais un fseek dépend du système de fichier mais qu'en règle général, il a pas besoin de lire séquentiellement tout le fichier, si1 ?

      À quoi correspond l'action de mapper ? Car manifestement, il ne met pas tout en mémoire. Seulement le nœud d'index peut-être ?


      1. Je pense qu'en ext4 il doit avoir un truc qui lui dit pour l'adresse XXX tu regardes seulement ici. Le nœud d'index a des champs pour ça qui permet un accès logarithmique aux données du fichier il me semble. 

  • # Tout n'est pas fichier

    Posté par  (site web personnel) . Évalué à 10.

    Je pense qu'il y a une confusion entre ce que dit unix "Tout est fichier" et ce que fait le kernel.

    "Tout est fichier" c'est pour l'user space. Le kernel doit représenter l'ensemble du système sous la forme de fichiers. Ça permet d'avoir un user space qui accède à tout, toujours de la même façons : Des fichiers dans une arborescence, j'ouvre les fichiers, j'ai un fd, ….

    Mais le kernel, en interne, ne suis pas cette convention (et encore heureux). Un disque dur se comporte fondamentalement différemment d'un clavier, d'un écran (carte graphique) ou d'un périphérique réseau. (Et c'est bien pour ça qu'on a différent sous-système/drivers dans le kernel).

    Quand tu fais un mount /dev/foo /tmp/mount, tu demandes au kernel de :
    - prendre le périphérique block /dev/foo (le fait que tu puisses l'identifier comme un fichier dans une arborescence est sympa mais est sans rapport ici et rajoute de la confusion)
    - trouver le bon système de fichier (FS)
    - associer le contenu du périphérique block (exploité par le FS) au dossier /tmp/mount.
    Ce qui est dans /tmp/mount est le "résultat" de FS(/dev/foo)

    Mais quand tu lui passes un fichier standard en entrée, c'est peut-être la même chose pour toi (c'est accessible par un path, ton iso contient effectivement un FS,…) mais pour le kernel c'est complètement différent. Il n'a "rien" à passer au driver/FS, ton fichier standard est le "résultat" d'un autre FS dans un point de montage. Tu dois donc créer un autre couche d'abstraction qui "crée" un truc block à partir d'un fichier standard, et là ça marche.

    cp, dd et cat fonctionne au niveau userspace, donc tout est fichier. Donc c'est effectivement transparent pour eux.

    Matthieu Gautier|irc:starmad

  • # De la doc !

    Posté par  (Mastodon) . Évalué à 10.

    La doc du kernel est une bonne source d'information générales :
    https://linux-kernel-labs.github.io/refs/heads/master/labs/block_device_drivers.html

    Rien que l'introduction donne une partie de la réponse :

    Block devices are characterized by random access to data organized in fixed-size blocks. Examples of such devices are hard drives, CD-ROM drives, RAM disks, etc. The speed of block devices is generally much higher than the speed of character devices, and their performance is also important. This is why the Linux kernel handles differently these 2 types of devices (it uses a specialized API).

    Working with block devices is therefore more complicated than working with character devices. Character devices have a single current position, while block devices must be able to move to any position in the device to provide random access to data. To simplify work with block devices, the Linux kernel provides an entire subsystem called the block I/O (or block layer) subsystem.

    En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

    • [^] # Re: De la doc !

      Posté par  (site web personnel) . Évalué à 1.

      Cool !
      Merci pour la doc, c'est vraiment plus claire comme ça.

      Enfin, j'ai des trucs à apprendre quoi.

Suivre le flux des commentaires

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