如何在mount(8)和fstab中注册FUSE文件系统类型?

39
我写了一个基于 FUSE 的小型文件系统,现在唯一缺失的是我想要在系统启动时通过 fstab(5) 注册它以实现自动挂载,或者可以使用 mount /srv/virtual-db 手动挂载。我该如何实现这一点?
我知道我可以从某个 init 脚本中运行 /usr/bin/vdbfs.py /srv/virtual-db,但那并不算优美。
很抱歉,这可能不完全是一个编程问题,但它与包装和部署高度相关,因为这仍然是程序员的工作。

好问题,但与编程无关,现在有serverfault.com。 - ypnos
3
如果只是行政问题(例如向某个文件添加条目),那么可能可以。但是,在内核中注册文件系统肯定是一个编程问题(唯一的管理部分是向modprobe.conf添加模块),至于FUSE我不确定...因此,我不知道这个问题真正属于哪个领域。 - drdaeman
8
这个应该放在 Stack Overflow 上,绝对没错! - Matt Joiner
5个回答

37
一般来说,通过创建可执行文件 mount.fstype 来注册新的挂载文件系统类型。
$ ln -s /usr/bin/vdbfs.py /usr/sbin/mount.vdbfs
如果 vdbfs.py 接受 mount 类似的参数(即 dev path [-o opts]),那么使用 mount -t vdbfs 命令并将 vdbfs 作为 fstab 中的第三个字段即可。如果不行,您可以创建一个包装器,使其接受这种形式的参数,并将它们映射到您的 vdbfs.py 所需的任何参数。
FUSE 还应该安装一个可执行文件 mount.fusemount.fuse 'vdbfs.py#dev' path -o opts 将调用 vdbfs.py dev path -o opts。在这种情况下,您可以使用 fuse 作为您的文件系统类型,并在设备名称前加上 vdbfs.py#

5
请注意,FUSE的作者Miklos Szeredi已经废弃在挂载源中编码真实文件系统类型的做法。引用自mount手册:程序 mount 和 umount 支持文件系统子类型。子类型由“.subtype”后缀定义。例如“fuse.sshfs”。建议使用子类型表示法而不是向挂载源添加任何前缀(例如,“sshfs#example.com”已被废弃)。 - patryk.beza

25

为了澄清ephemient的回答,有两种选项:

  1. 像这样编辑/etc/fstab

  2. # <file system>   <mount point>      <type>  <options>         <dump>  <pass>
    # ...
    vdbfs.py#<dev>    /srv/virtual-db    fuse    user,<other-opts>    0    0
    
  3. 或者,

  4. 创建一个以 "mount." 为前缀的可执行文件(确保它可以与类似于 mount 的选项一起使用):

  5. $ ln -s /usr/bin/vdbfs.py /usr/sbin/mount.vdbfs
    

    请像这样编辑/etc/fstab

    # <file system> <mount point> <type>    <options>         <dump>  <pass>
    # ...
    <dev>    /srv/virtual-db    vdbfs.py    user,<other-opts>    0    0
    
    关于自动挂载和使用mount手动挂载,选项usernoauto是相关且由fuse本身完全支持,因此您不必自己实现它们。选项user允许非特权用户(属于“fuse”组的成员)使用mount命令挂载您的文件系统,而noauto指示您的文件系统不自动在启动时挂载。如果您不指定noauto,它将自动挂载。

6
为了阐明@patryk.beza对已接受答案的评论,挂载FUSE文件系统的正确方式是通过将文件系统类型设置为fuse.<subtype>
例如,要挂载一个s3fs-fuse实现,它不提供特定的/sbin/mount.*包装器,并通常使用s3fs用户命令来挂载S3桶,可以使用以下命令作为root:
mount -t fuse.s3fs bucket-name /path/to/dir -o <some,options>

/etc/fstab文件中,或者说在这一行中:
bucket-name /path/to/dir fuse.s3fs <some,options> 0 0

针对这个 SystemD 挂载单元(例如,/etc/systemd/system/path-to-dir.mount),进行如下操作:
[Unit]
Description=S3 Storage
After=network.target

[Mount]
What=bucket-name
Where=/path/to/dir
Type=fuse.s3fs
Options=<some,options>

[Install]
WantedBy=multi-user.target

这是如何工作的:mount会在文件类型格式化时(即<type>.<subtype>)识别“文件系统子类型”的概念,因此格式为fuse.someimpl的类型被识别为FUSE挂载助手/sbin/mount.fuse的责任。然后,FUSE挂载助手会将someimpl部分解析为FUSE实现,就像原始答案中使用#格式一样(我认为这只是搜索名为<subtype>的程序的路径,但我不确定100%)。

1

您可以使用fuse文件系统类型。以下内容在我的系统上有效:

smbnetfs    /media/netbios    fuse    defaults,allow_other    0    0

另一个例子:

sshfs#user@example.com:/    /mnt    fuse    user,noauto    0    0

这引出了另一个问题:如何在FUSE中注册自定义应用程序作为文件系统提供者? - jpaugh
实际上,这仍然需要添加由ephemient提到的mount.type解决方案(https://dev59.com/5nI_5IYBdhLWcg3wDOZC#1555146)。 - jpaugh

0

经过大量研究,我找到了一种使用fstab条目挂载fuse文件系统的解决方案。我正在使用fuse将s3bucket挂载到本地Linux机器上。

  • .passwd-s3fs:包含访问您的AWS帐户的凭据1]秘密密钥和2]访问密钥。
  • uid:用户ID。您可以键入Linux命令id并获取uid

语法:

s3fs#<Bucket_Name> <Mounted_Direcotry_Path> fuse _netdev,allow_other,passwd_file=/home/ubuntu/.passwd-s3fs,use_cache=/tmp,umask=002,uid=<User_Id> 0 0

例子:

s3fs#myawsbucket /home/ubuntu/s3bucket/mys3bucket fuse _netdev,allow_other,passwd_file=/home/ubuntu/.passwd-s3fs,use_cache=/tmp,umask=002,uid=1000 0 0

要挂载,您需要运行以下命令。

mount -a

要检查您的存储桶是否已正确挂载,请使用以下命令检查所有已挂载点。

df -h

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接