【小白课程】openKylin之Fuse的使用介绍
Fuse (Filesystem in Userspace) 是一个允许用户空间程序创建和管理文件系统的文件系统。用户可实现非管理员权限下将自定义的文件系统,挂载到操作系统中,供操作系统和其他应用程序使用。由于其主要实现代码位于用户空间中,而不需要重新编译内核,这给开发者带来了众多便利。
1.Fuse组成部分
Fuse包含以下主要部分:
内核模块fuse driver:即内核驱动,用来接收VFS(虚拟文件系统)传递下来的IO请求,并且把这个IO封装之后通过管道发送到用户态,负责处理所有文件系统相关的系统调用,并将其转发给用户空间的Fuse进程; 用户态库libfuse:解析内核态转发出来的协议包,拆解成常规的IO请求; 用户空间守护进程:运行在用户空间的程序,负责处理来自内核的请求并与底层存储系统进行交互。
注:由于内核模块是封装好的,我们只用关注用户态模块libfuse即可。
2.Fuse架构
Fuse在内核中实现了一个虚拟文件系统,相当于是黑盒子,在用户层面是感知不到的。它提供了一组接口,允许用户态程序为这个虚拟文件系统提供文件和目录的操作,通过用户空间与内核空间之间的交互,实现了对用户空间文件系统的支持。当用户态程序需要与Fuse交互时,它会通过Fuse库(libfuse)发送请求到内核,同时注册回调函数来处理这些请求。
从系统层面来讲,Fuse内核模块加载时被注册成Linux虚拟文件系统的一个Fuse文件系统驱动。此外,还注册了一个/dev/fuse的块设备。该块设备作为Fuse守护进程与内核通信的桥梁,/dev/fuse就是连接内核Fuse和用户态文件系统的纽带。Fuse守护进程通过/dev/fuse读取Fuse request,处理后将reply写入/dev/fuse。
如下图是Fuse的一个详细的架构,当一个Fuse文件系统被挂载时,Fuse守护进程会启动并等待内核的请求。当应用程序Applicantion对挂载的文件系统进行读写等操作时,VFS会将这些操作路由至Fuse driver,Fuse driver创建了一个Fuse request结构体,并把request保存在请求队列中。
图片摘自《To FUSE or Not to FUSE: Performance of User-Space File Systems》
此时,执行操作的进程会被阻塞,同时Fuse daemon通过读取/dev/fuse将request从内核队列中取出,并且提交操作到底层文件系统中(例如EXT4)。当处理完请求后,Fuse daemon会将reply写回/dev/fuse,Fuse driver此时把requset标记为completed,并将结果返回给内核,最终传递给应用程序。
注:VFS(虚拟文件系统)作为Linux内核中的一个软件层,用于给用户空间的程序提供文件系统接口,同时也提供了内核中的一个抽象功能,允许不同的文件系统很好地共存。对于用户来说,其不去关心不同文件系统的具体操作过程,而只是对一个虚拟的文件操作界面来进行操作,这个操作界面就是Linux的虚拟文件系统(VFS ) 。
以open一个图片操作为例,整个Fuse架构的调用的过程如下图(沿蓝色箭头,执行打开调用过程,黄色箭头为返回结果):
用户执行open操作时,即用户态app调用glibc open接口,通过syscall触发sys_open系统调用,发出open操作的请求。 open操作请求会经过VFS,确定操作类型,进而到Fuse的内核模块。 在Fuse内核模块中,open操作会生成一个request消息,并通过/dev/fuse发送到用户态libfuse。 用户空间的libfuse则读取/dev/fuse文件句柄,接受系统调用信息后,调用fuse_application用户自定义的open的方法,将返回值通过/dev/fuse通知给Fuse内核模块。 内核模块收到request消息的处理完成的唤醒,并将结果放回给VFS系统调用结果。 用户态app收到open的VFS系统调用返回结果,呈现给用户打开的内容。
3.Fuse用户层特性
可以由普通用户加载和挂载,对于用户倾向于自己挂载的文件系统很方便。 Fuse的用户可以根据自身的需求设计文件系统,也就是自定义属性。其自定义属性从Fuse的架构来看,其用户不需要关注内核层面的实现,只需要在libfuse的基础上,设计实现自身需求的文件系统。
以用简单Fuse文件系统代码为例,开发者可以在fuse_applicant_service中fuse_operations定义用户需要的文件系统的相关操作,接口如下:
static struct fuse_operations fuse_ops ={ .getattr = fuse_getattr,#实现获取文件相关属性 .readdir = fuse_readdir,#读取目录 .open = fuse_open,#打开操作 .create = fuse_create,#创建文件操作 .read = fuse_read,#读文件操作 .write = fuse_write,#写文件操作};
并对其中的各个接口用户做自定义实现,如对read做自定义:
static int fuse_read(const char* path, char* buffer, size_t size,off_t offset, struct fuse_file_info* fi){#按照用户(开发者)需求编写实现read的方式即可 return exfat_pread(&ef, get_node(fi), buffer, size, offset);}
由于Fuse是一种允许开发者在用户空间中实现自定义文件系统的框架,不依赖于操作系统内核,而是在用户空间中运行,并与操作系统通过标准的系统调用进行通信。因此Fuse文件系统的部分优点如下:
灵活性:Fuse提供了一个灵活的框架,使得开发者可以根据特定需求实现自定义的文件系统功能。无论是实现新型存储介质、网络文件系统还是虚拟文件系统,Fuse都能够提供适用的解决方案。 跨平台支持:Fuse可在多个操作系统上运行,包括Linux、macOS和FreeBSD等。这意味着开发者可以使用相同的代码库来构建跨平台的文件系统应用程序,而无需为每个平台单独编写和维护代码。 用户空间安全:由于Fuse运行在用户空间,使得文件系统驱动程序的错误或异常无法对操作系统内核造成直接影响。这提高了系统的稳定性和安全性,即使文件系统出现问题,也不会导致系统崩溃或数据丢失。 易于开发和调试:Fuse提供了API和工具集,使得开发和调试自定义文件系统变得更加便捷。开发者可以使用标准的编程语言(如C、C++和Python)来实现文件系统,并通过调试工具进行代码测试和排错。 共享数据:Fuse允许多个进程或用户共享相同的文件系统数据。这意味着不同的应用程序或用户可以同时访问和操作相同的文件,从而实现了更高的数据共享和协作效率。 扩展性:Fuse支持插件机制,使得开发者可以添加额外的功能模块,以满足特定需求。这种可扩展性使得Fuse适用于各种应用场景,无论是普通的文件系统、分布式存储系统还是加密文件系统等。
Fuse在openKylin系统上的应用可以为用户提供更加灵活和方便的文件系统访问方式。具体地,openKylin上基于Fuse的功能主要包括以下几个方面,以及相应的应用:
1. 自定义文件系统策略
openKylin上的Fuse可以允许用户自定义文件系统的策略。例如,用户可以设定特定目录下的文件只读,或者对文件进行加密、压缩等操作。通过自定义文件系统策略,用户可以根据实际需求来优化文件系统的行为,如:
EncFS:是一个开源的加密文件系统,它提供了对文件和目录的透明加密和解密功能。使用EncFS,可以将敏感数据保存在云存储或本地磁盘上,并确保只有授权的用户可以访问和查看这些数据。
EncFS使用两个主要组成部分来实现加密:加密层和文件系统层。加密层负责将原始数据加密为加密数据,而文件系统层则负责管理和操作这些加密数据。通过将这两个层结合起来,EncFS能够提供对数据进行实时加密和解密的功能。
EncFS具有以下特点:
透明性:对用户而言,EncFS提供了一个虚拟文件系统,能够像普通文件系统一样进行读写操作,无需额外的操作。 安全性:EncFS使用AES算法对数据进行加密,保护数据的机密性。同时,它还提供了针对文件系统攻击和加密数据完整性的额外保护措施。 灵活性:EncFS可以与各种存储介质和文件系统配合使用,使其适用于多种环境和场景。 跨平台支持:EncFS可在多个操作系统上运行,包括Linux、macOS和Windows等。
需要注意的是,EncFS不提供身份验证或访问控制功能,因此在使用EncFS时,您需要确保系统中只有授权的用户能够访问加密数据。此外,EncFS的安全性取决于密码的选择和管理,因此请谨慎选择密码并定期更换以提高数据的安全性。
Squashfuse:是一个开源项目,它提供了一种将SquashFS镜像文件挂载到Linux文件系统的方法。SquashFS是一种只读的压缩文件系统,常用于在嵌入式设备、Live CD、虚拟机镜像等环境中提供高效的文件系统映像。
Squashfuse允许用户在Linux系统中以只读的方式挂载SquashFS镜像,使得镜像中的文件和目录可以像普通文件系统一样被访问。这对于需要访问或者修改SquashFS镜像中的内容非常有用,而无需解压整个镜像。
Squashfuse通过Fuse(Filesystem in Userspace)技术实现了将SquashFS镜像挂载到用户空间的功能。这意味着用户可以在不需要特权的情况下挂载SquashFS镜像,并以普通用户的身份访问其中的文件。
Squashfuse提供了一组命令行工具和API,可以方便地使用和集成到自己的应用程序中。使用Squashfuse,您可以在Linux系统上轻松地处理SquashFS镜像,从而实现更高效的文件系统管理和访问。
2. 集成与扩展
openKylin上的Fuse可以方便地与其他应用程序进行集成,提供统一的文件系统接口供其他应用程序使用。同时,openKylin的插件机制也可以帮助开发者扩展Fuse的功能,满足不同场景下的需求,如:
gvfs-fuse:gvfs-fuse是GNOME桌面环境中的一个组件,它提供了在用户空间中挂载和访问各种文件系统的功能。gvfs-fuse使用Fuse作为后端,使用户能够通过文件管理器等应用程序访问远程、虚拟和特殊文件系统。
gvfs-fuse支持多种协议和文件系统,包括SMB/CIFS(Windows共享)、FTP、WebDAV等。通过gvfs-fuse,用户可以方便地浏览和操作这些文件系统,如在文件管理器中打开、复制、粘贴文件等。 gvfs的主要优势是支持文件系统高性能。从用户体验上来说,gvfs可以迅速启动,可以支持大文件系统,支持文件类型访问控制,并且支持基于Web的文件共享。gvfs 还支持文件加密,大大增强了文件安全性。 gvfs还支持更高层次的应用程序集成功能,包括文件系统监视功能和定制的文件系统显示。与此同时,它还支持多服务器功能,以实现更高的可用性和更快的文件传输速度。 gvfs最近还增加了文件压缩功能,可以有效减少文件系统中文件的大小,提高文件传输效率,节省存储空间。
3. 解决非原生支持的文件系统
在openKylin系统环境中,是不支持原生的某些文件系统,例如exfat、ntfs。为实现相关文件系统的应用操作,其提供实现原生文件系统的挂载和访问的解决方案,如:
exfat-fuse:exfat-fuse是一个基于Fuse实现的用于访问exFAT文件系统的工具。exFAT(Extended File Allocation Table)是一种专门用于闪存设备的文件系统,用于支持大容量文件和移动存储介质。
exfat-fuse允许Linux系统上的用户在用户空间中挂载和访问exFAT格式的存储设备,如USB闪存驱动器、SD卡等。通过exfat-fuse,用户可以读取和写入exFAT文件系统中的文件,并进行常规的文件操作。
需要注意的是,exfat-fuse并非原生支持exFAT文件系统而是通过Fuse将exFAT文件系统映射到用户空间。因此,在使用exfat-fuse时,需要先安装Fuse并加载Fuse内核模块,然后再使用exfat-fuse来挂载和访问exFAT文件系统。
ntfs-3g:是一个用于在Linux系统上访问和处理NTFS(New Technology File System)格式的工具。NTFS是Windows操作系统中常用的文件系统,而ntfs-3g提供了对NTFS分区读取和写入的能力。
ntfs-3g是基于Fuse(Filesystem in Userspace)实现的,它允许用户在用户空间中挂载和操作NTFS分区,而无需特权用户或管理员权限。通过ntfs-3g,Linux用户可以与NTFS格式的存储设备进行交互,并执行各种文件操作,如读取、写入、复制、删除等。
ntfs-3g具有以下特点和功能:
读写支持:ntfs-3g允许对NTFS分区进行读写操作,包括对文件和目录进行创建、修改和删除等。这使得Linux用户能够方便地与Windows系统共享和处理NTFS格式的数据。 文件权限支持:ntfs-3g支持在NTFS分区中保留和管理Linux文件权限和属性。这意味着在挂载NTFS分区时,可以为文件和目录设置权限、所有者和组等信息,以保持一致性和安全性。 高性能:ntfs-3g通过优化和缓存算法,提供了较高的读写性能和效率。这使得对NTFS分区的操作速度更快,并能够适应大容量和高负载的存储设备。 完整性保护:ntfs-3g通过事务和日志记录等机制,保护NTFS分区的完整性。这意味着在发生故障或异常情况时,可以避免数据损坏或丢失,并提供一致的文件系统状态。 国际化支持:ntfs-3g支持多语言环境,并能够正确处理各种字符集和文本编码。这使得用户能够与包含非ASCII字符的文件和目录进行交互。
在openKylin上基于Fuse,用户可以灵活地管理和操作系统中的文件和目录,提升工作效率和数据处理能力。Fuse的原理及优点使其成为构建自定义文件系统的有力工具,为openKylin的集成与扩展能力则提供了更多的可能性。