Le module du noyau Linux utilisé pour prendre en charge les systèmes de fichiers en espace utilisateur s'appelle FUSE. Le nom complet de fuse est "Filesystem in Userspace", qui signifie "système de fichiers de l'espace utilisateur" en chinois. Il fait référence à un système de fichiers entièrement implémenté en mode utilisateur. Il est utilisé pour monter certains espaces réseau sous Linux et constitue un composant important. d'un système d'exploitation général.
L'environnement d'exploitation de ce tutoriel : système linux7.3, ordinateur Dell G3.
Qu'est-ce que Linux Fuse
Le système de fichiers dans l'espace utilisateur fait référence à un système de fichiers entièrement implémenté en mode utilisateur. Il est utilisé sous Linux pour monter certains espaces réseau, tels que SSH, sur des fichiers locaux. Modules système, le contenu pertinent peut. être trouvé sur SourceForge.
Le module du noyau utilisé par Linux pour prendre en charge le système de fichiers de l'espace utilisateur est appelé FUSE. Le terme FUSE fait parfois référence spécifiquement au système de fichiers de l'espace utilisateur sous Linux. C'est une partie importante d'un système d'exploitation général. Les systèmes d'exploitation assurent traditionnellement la prise en charge des systèmes de fichiers au niveau du noyau. Généralement, le code en mode noyau est difficile à déboguer et a une faible productivité.
Le soi-disant « système de fichiers en mode utilisateur » signifie que les données et métadonnées d'un système de fichiers sont fournies par des processus en mode utilisateur (ce processus est appelé « daemon »). Pour les systèmes d'exploitation à micro-noyau, implémenter un système de fichiers en mode utilisateur n'est rien, mais pour le macro-noyau Linux, le sens est différent.
Bien qu'il soit appelé système de fichiers en mode utilisateur, cela ne signifie pas qu'il ne nécessite pas du tout la participation du noyau, car sous Linux, l'accès aux fichiers s'effectue uniformément via l'interface du noyau fournie par le VFS couche (telle que open/read). Par conséquent, lorsqu'un processus (appelé « utilisateur ») accède au système de fichiers implémenté par le démon, il doit toujours passer par VFS.
Lorsque VFS reçoit une demande d'accès au fichier du processus utilisateur et détermine que le fichier appartient à un système de fichiers en mode utilisateur (selon le type de montage), il transférera la demande vers un module du noyau nommé "fuse". Ensuite, "fuse" convertit la requête dans le format de protocole convenu avec le démon et la transmet au processus démon.
On constate que dans cette relation tripartite, le module noyau "fusible" joue un rôle de transfert. Il permet d'établir un canal de communication entre VFS (on peut aussi dire qu'il s'agit du processus utilisateur) et le. démon. En termes simples, pour parler franchement, son rôle est en fait celui d’un « agent ».
L'implémentation de ce framework complet sous Linux est FUSE (Filesystem in Userspace). Comme le montre la figure 1, la partie dans la case rouge est l'implémentation spécifique du système de fichiers de type FUSE, et c'est l'espace que les concepteurs de systèmes de fichiers en mode utilisateur peuvent jouer. Actuellement, il existe plus d'une centaine de systèmes de fichiers implémentés sur la base de FUSE (certains systèmes de fichiers basés sur le noyau peuvent également être portés dans des systèmes de fichiers en mode utilisateur, tels que ZFS et NTFS), et cet article utilisera un fusible prêt à l'emploi. sshfs pour la démonstration.
Installez d'abord le progiciel fuse-sshfs et utilisez la commande suivante pour monter le système de fichiers (montez le répertoire "remote-dir" de la machine distante dans le répertoire "local-dir" de la machine locale) :
sshfs:
Après cela, un dossier nommé "fuse" sera généré dans le répertoire "/sys/fs", et vous pourrez voir le Le module noyau "fuse" a été chargé (son périphérique correspondant est "/dev/fuse"), et le type du répertoire de montage local est devenu "fuse.sshfs":
Le but de la génération de nœuds de périphérique est-il est pratique pour le contrôle en mode utilisateur, mais pour les applications au niveau du système de fichiers, il est toujours difficile d'utiliser directement ioctl() pour accéder au périphérique car trop de détails sont présentés, donc libfuse est apparu comme une couche intermédiaire et le processus démon dans En fait, les fichiers des périphériques Fuse sont gérés via l'interface fournie par libfuse.
Ensuite, prenons l'exemple de la création d'un nouveau fichier via la commande "touch" dans le système de fichiers "fuse.sshfs" pour afficher le processus d'interaction spécifique entre le module du noyau fuse et le processus démon (c'est-à-dire "sshfs") (La partie code est basée sur la version 5.2.0 du noyau) :
[Premier tour]
Le début est la vérification des autorisations, mais la vérification ici n'est pas équivalente à la vérification des autorisations VFS. le but est d’empêcher d’autres utilisateurs d’accéder à leur système de fichiers de fusibles privé.
Ensuite, l'inode du fichier est trouvé en fonction du chemin du fichier. Puisqu'il s'agit d'un fichier nouvellement créé, l'inode n'est pas dans le cache d'inode du noyau, vous devez donc envoyer une requête de « recherche » au démon :
Ces requêtes seront mises dans une file d'attente en attente, en attente pour une réponse du processus démon. Le processus utilisateur se mettra en veille :
En tant que démon, le processus sshfs obtient les données en lisant le fichier de périphérique "/dev/fuse". tombera en attente de blocage :
Lorsque les demandes arriveront dans la file d'attente en attente, le processus démon sera réveillé et traitera ces demandes. La requête traitée sera déplacée dans la file d'attente de traitement Une fois que le processus démon aura répondu au module du noyau de fusible, le processus utilisateur sera réveillé et la requête correspondante sera supprimée de la file d'attente de traitement.
【Deuxième tour】
L'étape suivante concerne d'autres appels système déclenchés lors de l'exécution de la commande "touch". S'il s'agit de données/métadonnées qui ont déjà été consultées, elles sont susceptibles d'exister dans. le cache., lors de l'accès à cette partie des données/métadonnées, le module du noyau de fusible peut la résoudre par lui-même, sans avoir besoin d'un aller-retour vers l'espace utilisateur, sinon elle doit toujours être signalée au processus démon pour traitement.
Ici, get_fuse_conn() obtient l'instance de structure "fuse_conn" créée lorsque le système de fichiers de type fusible est monté. En tant que lien entre le processus démon et le noyau, la connexion existera toujours à moins que le processus démon ne meure ou que le système de fichiers fusible correspondant ne soit désinstallé.
Côté processus démon, il existe toujours des opérations similaires. Ce qu'il faut noter, c'est la différence entre fuse_write/read() et fuse_dev_write/read() Ces deux séries de fonctions, la première est une requête de lecture et d'écriture VFS lorsque le processus utilisateur accède aux fichiers sur le système de fichiers fuse. , qui est un fichier normal. Ce dernier est la lecture et l'écriture par le processus démon de "/dev/fuse", un périphérique représentant le module du noyau fuse, afin d'obtenir des requêtes et de donner des réponses.
【Troisième tour】
Le dernier cycle d'interaction entre le module du noyau fusible et le processus démon consiste à obtenir le numéro d'inode dans le superbloc représentant le système de fichiers fusible et à remplir les informations pertinentes de ces métadonnées .
Il n'est pas difficile de constater que dans le système de fichiers fuse, même si une opération "touch" relativement simple est effectuée, la commutation entre le mode utilisateur et le mode noyau impliqué est relativement fréquente, et est également accompagné de plusieurs copies de données. Par rapport aux systèmes de fichiers du noyau traditionnels, son débit global d’E/S est inférieur et sa latence est plus grande.
Alors pourquoi fuse occupe-t-il toujours une place dans les systèmes de fichiers pris en charge par le système d'exploitation ? A ce propos, développer en mode utilisateur présente de nombreux avantages. Premièrement, il est facile à déboguer et est particulièrement adapté à la vérification rapide d'un nouveau prototype de système de fichiers, il est donc très populaire dans le domaine de la recherche universitaire. Dans le noyau, vous ne pouvez utiliser que le langage C. En mode utilisateur, il n'y a pas beaucoup de restrictions. Diverses bibliothèques de fonctions et divers langages de programmation peuvent être utilisés.
Deuxièmement, les bugs du noyau provoquent souvent le crash de l'ensemble du système au moindre désaccord (ce qui est plus grave dans les applications virtualisées, car le crash de l'hôte fera planter toutes les machines virtuelles qui y tournent), et le mode utilisateur L'impact de le bug est relativement limité. Donc, le recto de la médaille est qu'il est pratique pour le développement, mais à quel point c'est pratique est un sentiment
subjectifaprès tout, tandis que l'autre côté est l'impact sur les performances, qui peut être vérifié avec objectif données expérimentales. Alors, quelle méthode faut-il utiliser pour mesurer la perte causée par le fusible de manière relativement précise ? Nous utilisons toujours le fuse-sshfs que nous utilisions auparavant, mais ici nous n'utilisons plus le montage à distance, mais utilisons le montage local (en supposant que le répertoire "dir-src" de la machine locale se trouve dans le système de fichiers ext4) :
sshfs localhost:Lorsque le processus démon reçoit la requête, il doit entrer à nouveau dans le noyau pour accéder au module du noyau ext4 (ce mode de système de fichiers est appelé " empilable " :écriture séquentielle
, par rapport au système de fichiers ext4 natif, le débit d'E/S est réduit de 27 % et l'écriture aléatoire est réduite de 44 %. Cependant, au cours des nombreuses années qui se sont écoulées depuis la naissance du système de fichiers Fuse, tout le monde a encore proposé de nombreuses mesures d'optimisation pour celui-ci. Par exemple, lors de la lecture et de l'écriture séquentielles, il peut être conçu pour envoyer des requêtes par lots au processus démon (mais la lecture et l'écriture aléatoires ne conviennent pas). Il existe également la technologie sans copie de
splicingLe mécanisme d'épissage fourni par le noyau Linux permet à l'espace utilisateur de transférer les données des tampons mémoire des deux noyaux. Il est donc particulièrement adapté au mode empilable. . Le module du noyau fuse transfère directement les données au module du noyau ext4 (mais l'épissage est généralement utilisé pour les requêtes dépassant 4K et n'est pas utilisé pour lire et écrire de petites quantités de données).
Après ces efforts, quel type de performances le système de fichiers Fuse peut-il atteindre ? Selon les résultats des tests répertoriés dans ce rapport, par rapport à l'ext4 natif, dans le meilleur des cas, la perte de performance du fusible peut être contrôlée à moins de 5 %, mais dans le pire des cas, elle est de 83 %. Dans le même temps, son utilisation des ressources CPU a également augmenté de 31 %.
Du démon sdcard qui existait entre Android v4.4 à v7.0, en passant par Ceph et GlusterFS ces dernières années, tous ont adopté ou adoptent actuellement des implémentations basées sur FUSE. FUSE a montré son utilité dans les applications de système de fichiers réseau et de virtualisation. Son émergence et son développement ne visent pas à remplacer le système de fichiers implémenté en mode noyau, mais à constituer un complément utile (théoriquement, FUSE peut également être utilisé pour implémenter le système de fichiers racine, mais ceci. n'est pas recommandé, « peut faire » et « devrait faire » sont deux choses différentes). Recommandations associées : "
Tutoriel vidéo Linux"
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!