目录
你来我往
硬币的两面
首页 运维 linux运维 linux fuse是什么意思

linux fuse是什么意思

Apr 18, 2023 am 11:20 AM
linux

Linux用于支持用户空间文件系统的内核模块名叫FUSE。fuse全称“Filesystem in Userspace”,中文意思为“用户空间文件系统”,指完全在用户态实现的文件系统,是Linux中用于挂载某些网络空间,是一个通用操作系统重要的组成部分。

linux fuse是什么意思

本教程操作环境:linux7.3系统、Dell G3电脑。

linux fuse是什么

用户空间文件系统(Filesystem in Userspace),指完全在用户态实现的文件系统,是Linux 中用于挂载某些网络空间,如SSH,到本地文件系统的模块,在SourceForge上可以找到相关内容。

Linux用于支持用户空间文件系统的内核模块名叫FUSE,FUSE一词有时特指Linux下的用户空间文件系统。是一个通用操作系统重要的组成部分。传统上操作系统在内核层面上对文件系统提供支持。而通常内核态的代码难以调试,生产率较低。

所谓“用户态文件系统”,是指一个文件系统的data和metadata都是由用户态的进程提供的(这种进程被称为"daemon")。对于micro-kernel的操作系统来说,在用户态实现文件系统不算什么,但对于macro-kernel的Linux来说,意义就有所不同。

虽然叫做用户态文件系统,但不代表其完全不需要内核的参与,因为在Linux中,对文件的访问都是统一通过VFS层提供的内核接口进行的(比如open/read),因此当一个进程(称为"user")访问由daemon实现的文件系统时,依然需要途径VFS。

当VFS接到user进程对文件的访问请求,并且判断出该文件是属于某个用户态文件系统(根据mount type),就会将这个请求转交给一个名为"fuse"的内核模块。而后,"fuse"将该请求转换为和daemon之间约定的协议格式,传送给daemon进程。

1.png

可见,在这个三方关系中,"fuse"这个内核模块起的是一个转接的作用,它帮助建立了VFS(也可以说是user进程)和daemon之间的交流通道,通俗点说,它的角色其实就是一个「代理」。

这一整套框架的实现在Linux中即为FUSE (Filesystem in Userspace)。如图1所示,红框的部分才是FUSE类型文件系统的具体实现,才是用户态文件系统的设计者可以发挥的空间。目前,已有不下百种基于FUSE实现的文件系统(一些基于内核的文件系统也可以porting成用户态文件系统,比如ZFS和NTFS),而本文将选用一个现成的fuse-sshfs来进行演示。

首先安装fuse-sshfs的软件包,使用如下的命令进行文件系统的mount(将远端机器的"remote-dir"目录挂载到本机的"local-dir"目录):

sshfs :

之后,在"/sys/fs"目录下,将生成一个名为"fuse"的文件夹,同时可以看到"fuse"内核模块已被加载(其对应的设备为"/dev/fuse"),并且本机的挂载目录的类型已成为"fuse.sshfs":

2.png

生成设备节点的目的是方便用户态的控制,但是对于文件系统这种级别的应用来说,直接使用 ioctl() 来访问设备还是显得麻烦,因为呈现了太多的细节,所以libfuse作为一个中间层应运而生,daemon进程实际都是通过libfuse提供的接口来操作fuse设备文件的。

你来我往

接下来,以在"fuse.sshfs"文件系统中通过"touch"命令新建一个文件为例,查看fuse内核模块和daemon进程(即"sshfs")具体的交互流程(代码部分基于内核5.2.0版本):

【第一轮】

最开始是permission的校验,不过这里的校验并不等同于VFS的权限校验,它的主要目的是为了避免其他user访问到了自己私有的fuse文件系统。

linux fuse是什么意思

然后就是根据文件路径查找文件的inode。由于是新建的文件,inode并不在内核的inode cache中,所以需要向daemon发送"lookup"的请求:

3.png

这些请求会被放入一个pending queue中,等待daemon进程的回复,而user进程将陷入睡眠:

4.png

作为daemon,sshfs进程通过读取"/dev/fuse"设备文件来获得数据,如果pending queue为空,它将陷入阻塞等待:

5.png

当pending queue上有请求到来时,daemon进程将被唤醒并处理这些请求。被处理的请求会被移入processing queue,待daemon进程向fuse内核模块做出reply之后,user进程将被唤醒,对应的request将从processing queue移除。

linux fuse是什么意思

【第二轮

接下来就是执行"touch"命令时所触发的其他系统调用,如果是之前访问过的data/metadata,那很可能存在于cache中,再次访问这部分data/metadata的时候,fuse内核模块就可以自行解决,不需要去用户空间往返一趟,否则还是需要上报daemon进程进行处理。

这里 get_fuse_conn() 获取的是在fuse类型的文件系统被mount时创建的"fuse_conn"结构体实例。作为daemon进程和kernel联系的纽带,除非daemon进程消亡,或者对应的fuse文件系统被卸载,否则该connection将一直存在。

6.png

在daemon进程这一端,还是类似的操作。需要注意的是区别 fuse_write/read() fuse_dev_write/read() 这两个系列的函数,前者是user进程在访问fuse文件系统上的文件时的VFS读写请求,属于对常规文件的操作,而后者是daemon进程对"/dev/fuse"这个代表fuse内核模块的设备的读写,目的是为了获取request和给出reply。

7.png

【第三轮

fuse内核模块和daemon进程的最后一轮交互是在代表fuse文件系统的superblock中获取inode号,并填写这个metadata的相关信息。

8.png

硬币的两面

不难发现,在fuse文件系统中,即便执行一个相对简单的"touch"操作,所涉及的用户态和内核态的切换都是比较频繁的,并且还伴随着多次的数据拷贝。相比于传统的内核文件系统,它整体的I/O吞吐量更低,而延迟也更大。

那为什么fuse在操作系统支持的文件系统里面依然占据一席之地呢?说起来,在用户态开发是有很多优势的。一是便于调试,特别适合做一个新型文件系统prototype的快速验证,因此在学术研究领域颇受青睐。在内核里面,你只能用C语言吧,到了用户态,就没那么多限制了,各种函数库,各种编程语言,都可以上。

二是内核的bug往往一言不合就导致整个系统crash(在虚拟化的应用中更为严重,因为宿主机的crash会导致其上面运行的所有虚拟机crash),而用户态的bug所造成的影响相对有限一些。

所以,硬币的正面是便于开发,不过到底有多方便,这毕竟是一种主观的感受,而反面则是性能的影响,这可是能够用客观的实验数据来验证的。那应该用什么方法才能相对准确地衡量fuse所带来的损耗呢?

还是用前面用过的这个fuse-sshfs,不过这里我们不再使用远端挂载,而是采用本地挂载的方式(假设本机的"dir-src"目录位于ext4文件系统):

sshfs localhost:

当daemon进程收到请求后,它需要再次进入内核,去访问ext4的内核模块(这种文件系统模式被称为"stackable"的):

9.png

以user进程向fuse文件系统发出 write() 请求为例,右边红框部分是一次原生的ext4调用路径,而左边多出来的就是因为引入fuse后增加的路径:

10.png

根据这篇文档给出的数据,在这一系统调用中使用到的"getxattr"所形成的request,需要2倍的"user-kernel"交互量。对于顺序写,相比起原生的ext4文件系统,I/O吞吐量降低27%,随机写则降低44%。

不过,在fuse文件系统诞生的这么多年里,大家还是为它想出了很多的优化举措。比如,顺序读写的时候,可以设计为向daemon进程批量发送request的形式(但随机读写不适合)。

还有就是使用splicing这种zero-copy技术,由Linux内核提供的splicing机制允许用户空间在转移两个内核的内存buffer的数据时,不需要拷贝,因此尤其适合stackable模式下,从fuse内核模块直接向ext4内核模块传递数据(但splicing通常用于超过4K的请求,小数据量的读写用不上)。

经过这些努力,fuse文件系统的性能可以达到什么样的一种程度呢?根据这篇报告列出的测试结果,相比起原生的ext4,在最理想的情况下,fuse的性能损耗可以控制到5%以内,但最差的情况则是83%。同时,其对CPU的资源占用也增加了31%。

从Android v4.4到v7.0之间存在的sdcard daemon,到最近几年的Ceph和GlusterFS,都曾经采用过或正在采用基于FUSE的实现。FUSE在network filesystem和虚拟化应用中都展现了自己的用武之地,它的出现和发展,并不是要取代在内核态实现的文件系统,而是作为一个有益的补充(理论上,FUSE还可以用于实现根文件系统,但是不建议这么做,"can do"和"should do"是两回事)。

相关推荐:《Linux视频教程

以上是linux fuse是什么意思的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1677
14
CakePHP 教程
1431
52
Laravel 教程
1334
25
PHP教程
1280
29
C# 教程
1257
24
Linux体系结构:揭示5个基本组件 Linux体系结构:揭示5个基本组件 Apr 20, 2025 am 12:04 AM

Linux系统的五个基本组件是:1.内核,2.系统库,3.系统实用程序,4.图形用户界面,5.应用程序。内核管理硬件资源,系统库提供预编译函数,系统实用程序用于系统管理,GUI提供可视化交互,应用程序利用这些组件实现功能。

git怎么查看仓库地址 git怎么查看仓库地址 Apr 17, 2025 pm 01:54 PM

要查看 Git 仓库地址,请执行以下步骤:1. 打开命令行并导航到仓库目录;2. 运行 "git remote -v" 命令;3. 查看输出中的仓库名称及其相应的地址。

notepad怎么运行java代码 notepad怎么运行java代码 Apr 16, 2025 pm 07:39 PM

虽然 Notepad 无法直接运行 Java 代码,但可以通过借助其他工具实现:使用命令行编译器 (javac) 编译代码,生成字节码文件 (filename.class)。使用 Java 解释器 (java) 解释字节码,执行代码并输出结果。

sublime写好代码后如何运行 sublime写好代码后如何运行 Apr 16, 2025 am 08:51 AM

在 Sublime 中运行代码的方法有六种:通过热键、菜单、构建系统、命令行、设置默认构建系统和自定义构建命令,并可通过右键单击项目/文件运行单个文件/项目,构建系统可用性取决于 Sublime Text 的安装情况。

Linux的主要目的是什么? Linux的主要目的是什么? Apr 16, 2025 am 12:19 AM

Linux的主要用途包括:1.服务器操作系统,2.嵌入式系统,3.桌面操作系统,4.开发和测试环境。Linux在这些领域表现出色,提供了稳定性、安全性和高效的开发工具。

git软件安装 git软件安装 Apr 17, 2025 am 11:57 AM

安装 Git 软件包括以下步骤:下载安装包运行安装包验证安装配置 Git安装 Git Bash(仅限 Windows)

laravel安装代码 laravel安装代码 Apr 18, 2025 pm 12:30 PM

要安装 Laravel,需依序进行以下步骤:安装 Composer(适用于 macOS/Linux 和 Windows)安装 Laravel 安装器创建新项目启动服务访问应用程序(网址:http://127.0.0.1:8000)设置数据库连接(如果需要)

如何设置重要的 Git 配置全局属性 如何设置重要的 Git 配置全局属性 Apr 17, 2025 pm 12:21 PM

自定义开发环境的方法有很多种,但全局 Git 配置文件是最有可能用于自定义设置(例如用户名、电子邮件、首选文本编辑器和远程分支)的一种。以下是您需要了解的有关全局 Git 配置文件的关键事项。

See all articles