内容简介:说起FUSE,大概很早之前就知道了,但是写文件系统这种东西,大概一辈子也没几次机会会用到,所以当时也没怎么研究,直到最近遇到一个“扭曲”的需求……这个需求是这样的。在深度系统的安装器中,有一个全盘安装的功能,这个功能看起来非常简单:扔一块全新的或者老旧的硬盘给安装器,只需一杯咖啡的功夫,你的系统也就能优雅地躺在你的硬盘上了。然而,其中有一个处心积虑,哦不,深思熟虑的细节设定,就是假如你硬盘够大,安装器就会给你多分出一个分区:数据盘。据说数据盘的主要作用是让用户存放数据文件,也就是以前用Windows的时候D
说起FUSE,大概很早之前就知道了,但是写文件系统这种东西,大概一辈子也没几次机会会用到,所以当时也没怎么研究,直到最近遇到一个“扭曲”的需求……
这个需求是这样的。在深度系统的安装器中,有一个全盘安装的功能,这个功能看起来非常简单:扔一块全新的或者老旧的硬盘给安装器,只需一杯咖啡的功夫,你的系统也就能优雅地躺在你的硬盘上了。然而,其中有一个处心积虑,哦不,深思熟虑的细节设定,就是假如你硬盘够大,安装器就会给你多分出一个分区:数据盘。
据说数据盘的主要作用是让用户存放数据文件,也就是以前用Windows的时候D盘或者E盘等的作用,放点图片、下点片之类的。用户重装系统的时候,也可以方便的做数据迁移。不过鉴于之前我们的一些客户对文件权限的设计不太理解,经常莫名其妙就出权限文件,所以,这个数据盘大概隐含了两个阴性需求:
- 文件权限不要太严格;
- 文件权限不要太严格……
第一次尝试
收到需求的你肯定想,Linux(类Unix)把用户权限、文件权限划分地这么好,虽然也不算天衣无缝吧,但是回到上古时代的没有文件权限这种事,简直就是历史的倒退么……然而作为一名优秀的程序员,怎么能不理解这种为了用户使用方便,宁愿自己背负骂名的行为呢,所以我们选择了不抵抗。另外,为了这个盘可以被双系统的Windows读到,当时我们毅然选择了 NTFS
作为数据盘的分区格式。
然而,过了一段时间。
社区用户:我的硬盘发热好厉害呀,是不是这个NTFS分区…… 商业伙伴:这个NTFS文件系统的有点不清真啊……
这显然没有达到我们预期的目的嘛,必须想办法搞定啊。数据盘这个需求就开始了它的扭曲之旅。
第二次尝试
如果不使用 NTFS
,那就在 ext4
上面做文章咯?在网络上搜索了半天,也没有发现什么好的方式,要么就是 chmod -R xxx
这种,要么就是 chown
……然后突然想到之前同事提到过的ACL(限于篇幅和主题,就不展开了),就研究了一下,果然还就能解决问题,两条命令:
$ setfacl -d -m "g:sudo:rwx" /xxx $ setfacl -m "g:sudo:rwx" /xxx
其中的 /xxx
就是数据盘的挂载点,第一行命令设定了挂载点目录的默认ACL规则是:所有 sudo
组的用户可以对文件有 rwx
操作权限,第二句是设定了挂载点目录的ACL规则是:所有 sudo
组的用户可以对文件有 rwx
操作权限,好像看起来没有什么区别,其实不同的地方在于第一行命令设定的是目录的默认ACL规则,而第二行命令设定的是目录本身的ACL规则。设定了默认规则以后目录里面新创建的文件或者文件夹就会继承这个规则,如果只设置目录的ACL规则,则新文件和子目录不会继承这些ACL规则;如果只设置目录的默认ACL规则,而不设置目录本身的ACL规则,则目录本身没有ACL规则生效。
虽然这个设定感觉有点让人发晕,但是好歹功能都实现了呀,一切都看似那么美好。
然而 程序员 的所有美好都怕测试这种物种,测试有一天突然发现:“咦?系统里面的A用户放在数据盘里面的文件怎么B用户无法访问?”程序员就多了个BUG……
经过调试,发现一种神奇的现象:Linux(可能其他系统也是)对ACL的处理有点奇怪,假如在拥有ACL规则的对象(文件或者目录)上进行 chmod
操作,那么 chmod
会对对象的ACL规则造成影响,影响的结果就是对象虽然有ACL规则,但是ACL的有效值会变成 chmod
要达成的效果。举个例子,假如文件原来的ACL规则如下:
$ getfacl testacl # file: testacl # owner: hualet # group: hualet user::rw- group::r-- group:sudo:rwx mask::rwx other::r--
文件的权限是 644
,但是 sudo
组的用户有 rwx
权限。这时候如果我们使用 chmod 700 testacl
修改一下文件的权限,再次查看文件的ACL会变成:
$ getfacl testacl # file: testacl # owner: hualet # group: hualet user::rwx group::r-- #effective:--- group:sudo:rwx #effective:--- mask::--- other::---
可以看到, group
和 group:sudo
后面的有效值是 ---
,即 rwx
权限全无, other
也从原来的 r--
变成了 ---
。
这种处理看似很奇特,但是实际上也有深思熟虑在里面,这样设定的好处就是知道ACL存在的人可以使用ACL,而不知道ACL存在的人使用 chmod
的功能也能保证是正常的,这对于提升系统的兼容性还是有必要的。
回到上面的解谜题,A用户拷贝文件到数据盘的时候,文件管理器(cp也一样)会优先考虑保留文件的权限,这个操作类似创建文件后执行 chmod
操作,所以也就出现了测试报的那种问题。
这就是数据盘需求第二次扭曲的过程。
FUSE
所以又有大神提出了FUSE。
经过了两三轮扭曲,感觉数据盘这个需求已经有点”物是人非“了,但是本着“技术多尝试一点,以后肯定能用到”的想法,我还是借着这个机会“把玩“了一下很久之前就想玩玩儿的FUSE。
先给不知道FUSE的同学科普一下,FUSE(Filesystem in Userspace)就是用户空间的文件系统,它的出现让非内核开发者开发自己的文件系统成为可能,非特权用户不需要获取特权就可以挂载自己的文件系统。对于开发者来说,FUSE更多是一个开发框架,用来开发和实现用户空间系统,这个框架主要分为三个部分:内核模块、libfuse和文件系统守护进程,它们之间的关系如下图所示:
图中的 ./hello
就是文件系统守护进程, /tmp/fuse
则是这个文件系统的挂载点。文件系统工作在用户空间,通过libfuse跟内核中的FUSE模块进程通信,代理所有用户对挂载点内文件的访问请求,从而实现特殊的文件系统功能需求。
举个例子, sshfs
就是一种用户空间文件系统,用来将ssh服务器上的一个目录挂载到本地使用。它的使用方式特别简单,只需执行命令: sshfs [user@]host:[dir] mountpoint
,这样你在 mountpoint
下看到的文件的文件就是你ssh服务器上相应目录的文件,你再本地做得修改也都会在你的ssh服务器上体现出来。
因为libfuse使用起来非常方便,所以有不少有意思的文件系统都是基于FUSE完成的(见 FUSE Filesystems )。类似上面的 sshfs
可能更像是开发者的一个玩具,但是FUSE家族也不缺乏一些重量级的文件系统,像 ZFS
和 NTFS
等也是基于FUSE实现的。这么说并不是在FUSE完美无瑕,实际上很多人批评FUSE的性能比较差,据 To FUSE or Not to FUSE: Performance of User-Space File Systems 这篇论文测算,FUSE文件系统在吞吐量上比原生的文件系统要低83%,而CPU占用则要高31%。
“To FUSE or Not to FUSE”,这是一个问题。要效率还是要性能,只能具体场景具体分析了。
(未完待续)
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- [译] Linux 文件系统深度讨论
- Java虚拟机,类文件结构深度解析
- 深度文件管理器 V1.6 正式发布
- 干货分享丨jvm系列:dump文件深度分析
- [译] 深度:Linux kernel 支持 UTF-8 文件名
- 一文了解文件上传全过程(1.8w 字深度解析,进阶必备)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。