深度数据盘和FUSE文件系统

栏目: 后端 · 发布时间: 6年前

内容简介:说起FUSE,大概很早之前就知道了,但是写文件系统这种东西,大概一辈子也没几次机会会用到,所以当时也没怎么研究,直到最近遇到一个“扭曲”的需求……这个需求是这样的。在深度系统的安装器中,有一个全盘安装的功能,这个功能看起来非常简单:扔一块全新的或者老旧的硬盘给安装器,只需一杯咖啡的功夫,你的系统也就能优雅地躺在你的硬盘上了。然而,其中有一个处心积虑,哦不,深思熟虑的细节设定,就是假如你硬盘够大,安装器就会给你多分出一个分区:数据盘。据说数据盘的主要作用是让用户存放数据文件,也就是以前用Windows的时候D

说起FUSE,大概很早之前就知道了,但是写文件系统这种东西,大概一辈子也没几次机会会用到,所以当时也没怎么研究,直到最近遇到一个“扭曲”的需求……

这个需求是这样的。在深度系统的安装器中,有一个全盘安装的功能,这个功能看起来非常简单:扔一块全新的或者老旧的硬盘给安装器,只需一杯咖啡的功夫,你的系统也就能优雅地躺在你的硬盘上了。然而,其中有一个处心积虑,哦不,深思熟虑的细节设定,就是假如你硬盘够大,安装器就会给你多分出一个分区:数据盘。

据说数据盘的主要作用是让用户存放数据文件,也就是以前用Windows的时候D盘或者E盘等的作用,放点图片、下点片之类的。用户重装系统的时候,也可以方便的做数据迁移。不过鉴于之前我们的一些客户对文件权限的设计不太理解,经常莫名其妙就出权限文件,所以,这个数据盘大概隐含了两个阴性需求:

  1. 文件权限不要太严格;
  2. 文件权限不要太严格……

第一次尝试

收到需求的你肯定想,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::---

可以看到, groupgroup: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家族也不缺乏一些重量级的文件系统,像 ZFSNTFS 等也是基于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”,这是一个问题。要效率还是要性能,只能具体场景具体分析了。

(未完待续)


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning PHP, MySQL, and JavaScript

Learning PHP, MySQL, and JavaScript

Robin Nixon / O'Reilly Media / 2009-7-21 / USD 39.99

Learn how to create responsive, data-driven websites with PHP, MySQL, and JavaScript - whether or not you know how to program. This simple, streamlined guide explains how the powerful combination of P......一起来看看 《Learning PHP, MySQL, and JavaScript》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具