Linux|系统管理|WEB开发

关注Linux,系统管理,WEB开发以及开源世界

unionfs-fuse,解决我的ISO难题

| Comments

用户级文件系统--FUSE一文中提到了用户空间级的好处,给并处了一个实际的例子--sshfs。 而评论中,pczou给出了另外一个有用的用户级文件系统unpackfs,不过,这个比较适合研发的大侠使用,于我这种属于玩玩Linux的人并没有特别的用处。

于是,我便软磨硬泡,搅乱pczou吃饭的时间,问问它有没有解决我的iso难题的问题,我的问题是: 我拿到了一个ISO文件,我想编辑它,但是我不喜欢使用mount && cp -rf &&,mkiso三部曲,那太费时间,而且也太占据我的空间。那有没有办法可以很方便的编辑这个iso文件。
pczou不愧是pczou,说unionfs能解决这个问题。虽然给我掩饰了一通,无聊脑子笨,没有太了解,特别是他在键盘上弹指如飞的时候,我没有明白怎么就可以了。于是边厚颜无耻的希望他在blog上稍微描述一番。呵呵,结果一袋烟的时间,他的blog上便多了这样一篇文章--FUSE+UNIONFS,下面的引用是他如何解决我的ISO问题的。

需求2: 作为 Linux 发行版 攒手,经常要做iso,有时候下一个iso,想做些小修改,重新生成一个iso。传统的做法是 mount -o loop, cp -rf, mkiso。有慢有耗硬盘,有没有更好的办法?

曾经尝试过unionfs,unionfs可以把两个文件系统合并成一个,这样可以把只读的iso镜像与一个可读写的目录进行合并。原理很简单,但真正操作起来有很多问题。比如我把iso的镜像目录/iso和一个空的可写目录/writable合并成/newiso,这是如果做

# cp /a.srpm /newiso/SRPMS/b.srpm

会报错,原因是/iso下没有/SRPMS/b.srpm文件,即使有的话也是只读的;而/writable下没有/SRPMS目录。这样unionfs就有些无所适从了。理想情况是unionfs在/writable下建立好SRPMS目录,然后把文件拷贝到那里。这并不是unionfs设计的初衷,需要对unionfs打补丁。可unionfs是个内核模块,本身还不太稳定,如果再加上这许多复杂功能,恐怕不是好的选择。

好在有FUSE。

FUSE开发很简单,不过我也不想从头来。根据创新第一定律:“你想到的东西很有可能别人也想到过”,到网上一搜,果然有人已经做了基于FUSE的unionfs,叫做unionfs-fuse: http://linux.softpedia.com/progDownload/unionfs-fuse-Download-9407.html

不顾廉耻地抓过来,可以用。不过是标准的unionfs实现,刚才说道unionfs不能满足要求,需要修改。这回是在用户空间,就不那么恐怖了。
做了一番quick and dirtry工作,总算基本满足要求了。
实现的原理是,unionfs-fuse是用findroot(path)函数寻找用户请求的路径path属于哪个部分,稍加修改,让findroot()做些额外工作,当读写分区中不存在要找的文件时,自行创建一个。
实现中更是使用了system()这个在用户空间都让人不耻的东西,充分发扬了FUSE的优点。

这里是结果:

[root@localhost pczou]# mount -o loop
/home/pczou/iso/RHEL4-U3-i386-AS-disc1.iso /mnt/iso/
[root@localhost pczou]# mkdir writable
[root@localhost pczou]# find writable/
writable/
[root@localhost pczou]# mkdir newiso
[root@localhost pczou]# unionfs writable:/mnt/iso newiso
[root@localhost pczou]# cp maemopad-1.5-1.src.rpm newiso/SRPMS/
[root@localhost pczou]# find newiso/SRPMS/
newiso/SRPMS/
newiso/SRPMS/maemopad-1.5-1.src.rpm
newiso/SRPMS/comps-4AS-0.20060303.src.rpm
newiso/SRPMS/TRANS.TBL
[root@localhost pczou]# find writable/
writable/
writable/SRPMS
writable/SRPMS/maemopad-1.5-1.src.rpm
[root@localhost pczou]# find /mnt/iso/SRPMS/
/mnt/iso/SRPMS/
/mnt/iso/SRPMS/comps-4AS-0.20060303.src.rpm
/mnt/iso/SRPMS/TRANS.TBL
[root@localhost pczou]#

可以看出,新文件都存放在writable目录中,所有中间路径(SRPMS)都自动建好。

这个办法可以工作,但还有不少问题,最大的问题是不支持只读目录的文件删除。不过实现起来也并不很困难。

同时他还提出了另外一个非常有用的功能

除了用于iso制作以外,这个扩展的unionfs 还可以用于“虚拟安装”。我经常需要装一些稀奇古怪的软件包,Linux和Windows一样,都有垃圾软件,如何保证这些垃圾软件不破坏我宝贵的根分区呢?虚拟机可以,可是太慢;做个根分区镜像也可以,不过太耗硬盘空间。这种情况下就可以发挥扩展unionfs的威力了:

 # unionfs /writable:/ /mnt/newroot
 # chroot /mnt/newroot
 # rpm -ivh ...

把根分区(只读)与一个可写分区结合起来,就可以在上面任意乱搞了。搞完后,用纸巾把/writable一擦了事,方便卫生。

不过上面的功能使用官方的unionfs-fuse包做不到,需要使用pczou做的补丁,我这里就直接给出大好补丁好的包吧。

unionfs-fuse-0.14

Comments