如何在不使用libfuse的情况下使用FUSE创建用户空间文件系统?

时间:2015-07-24 02:33:44

标签: linux fuse

我发现FUSE用户空间库和内核接口已经从Linux开始,移植到许多其他系统,并提供了一个相对稳定的API,具有可能的小表面积。如果我想在用户空间中创建一个文件系统,而我没有参加Plan 9或Hurd,我会认为FUSE是我的最佳选择。

但是,我不打算使用libfuse。这部分是因为实用主义;使用C很难用我选择的语言(Monte)。这也是因为我对编写C支持代码完全不感兴趣,并且libfuse的推荐用法与Monte哲学不兼容。这应该不是问题,因为C不是神奇的,可以使用标准系统调用打开/ dev / fuse。

但是,我找不到文件。我没有找到/ dev / fuse ABI / API的文档,也没有其他人使用相同的非C-bound路由的故事。令人沮丧。

是否有任何类型的文档存在如何与语言无关的方式与/ dev / fuse和内核的FUSE子系统进行交互?如果是这样,你能指点我吗?谢谢!

更新:存在go-fuse,它在Go中,是一种比C更易读的语言。但是,它也不包含任何ABI / API文档。

更新:我注意到人们投票决定关闭此事。别担心,没有必要这样做。我对自己所希望的文档尚不存在感到满意。我将自己编写文档,发布它,然后在接受的答案中链接到它。希望下一个搜索此文档的人不会失望。

1 个答案:

答案 0 :(得分:13)

(我不接受这个,直到它完成。在此期间,欢迎编辑!)

FUSE会话的基本概要:

    open()上调用
  • /dev/fuse。我将调用生成的FD control FD
  • mount()使用目标安装点调用,文件系统类型为“fuse”,用​​于正常模式,“fuseblk”用于块设备模式,选项包括“fd = X”,其中X是控制FD。 / LI>
  • FUSE特定结构重复传输到控制FD上。通信的一般模式遵循请求 - 响应模式,其中程序read()的文件系统命令来自控制FD,然后是write()的响应。
  • 使用目标安装点调用
  • umount()
  • 在控制FD上调用
  • close()

总而言之,人们应该注意一些并发症。首先,mount()几乎总是一个特权系统调用,因此您必须是root才能安装FUSE文件系统。但是,正如人们可能已经注意到的那样,FUSE程序通常可以作为非root用户启动!怎么样?

有一个帮手,/bin/fusermount,安装了setuid。用法完全没有记录,但这就是我在这里的用途。不要自己open() /dev/fuse,而是将fusermount作为子进程运行,将目标挂载点作为参数传递,使用-o传递任何额外的挂载选项,并且(至关重要) )导出环境变量_FUSE_COMMFD并设置为打开FD的ASCII字符串,我将其称为 comm FD 。您必须使用例如自己创建通信FD。 pipe()fusermount将为您调用open()mount(),并使用sendmsg()技巧共享FD,将来自通信FD的控制FD共享给您。使用recvmsg()将其读回来。

编辑:我真的不明白为什么这个结构太难了。 FD由子过程继承;在顶级流程open()控制FD并将其传递到fusermount会更加容易。确实,存在一些混乱的副危险,但fusermount已经安装并且已经安装并且很危险。

反正! fusermount会粗略地守护,并在您的主要流程退出后,致电umount()close()进行清理。

尚未涵盖的事项:

  • 如何处理对FUSE的非阻塞访问?控制FD能否被踢进非阻塞模式?它实际上是否阻止,或者它是否像普通文件一样,并在访问时秘密阻止?
  • 结构布局。这些可以或多或少地从C或Go源重新发现,但这不是借口。当我完成了足够的受虐狂时,我会更认真地记录它们。