tfs 查看人员迁出文件_用户态文件系统框架FUSE的介绍及示例

029794235febb3b0b6a01b043fd878c3.png

了解Linux文件系统的同学都清楚,Linux的文件系统都是在内核态开发的。内核态开发最大的问题是涉及的内容比价多,调试不太方便。因此,很多应用都不太原因涉及内核态的开发。而fuse解决了文件系统必须在内核态的的难题。 它将文件系统的实现从内核态搬到了用户态,也就是我们可以在用户态实现一个文件系统。fuse有很多应用,比如与对象存储(例如S3等)结合,可以实现通过普通目录访问云对象存储的方式,简化应用访问对象存储的复杂性。本号将陆续推出3-5篇文章介绍fuse,今天是第一篇,将介绍fuse的基本原理,及给出一个非常简单的示例程序。多说无益,我们接下来实际操作一下fuse。
软件安装
要使用该库进行用户态文件系统的开发,必需先安装。包括软件包和开发用的头文件等内容。不同的平台安装方法略有不同,下面分别介绍一下。Ubuntu 16.04

sudo apt-get install libfuse2 libfuse-dev

CentOS 6

yum install fuse fuse-devel

本文安装的是fuse-devel-2.9.4-1.0.4.el6.x86_64版本的,后续示例程序也是该版本的,如果版本不一致在测试时可能略有不同。


fuse基本原理


简单的理解,fuse实现了一个对文件系统访问的回调。fuse分为内核态的模块和用户态的库两部分。其中用户态的库为程序开发提供接口,也是我们实际开发时用的接口,我们通过这些接口将请求处理功能注册到fuse中。内核态模块是具体的数据流程的功能实现,它截获文件的访问请求,然后调用用户态注册的函数进行处理。

ec97af3557ef9db02835571d573b32fa.png
图1 fuse处理流程

如图1所示,其中fuse_user是开发的用户态的文件系统程序,该程序启动的时候会将自己开发的接口注册到fuse中,比如读写文件的接口,遍历目录的接口等等。
同时,通过该程序在系统某个路径挂载fuse文件系统,比如/tmp/file_on_fuse_fs。此时如果在该目录中有相关操作时,请求会经过VFS到fuse的内核模块(上图中的步骤1),fuse内核模块根据请求类型,调用用户态应用注册的函数(上图中步骤2),然后将处理结果通过VFS返回给系统调用(步骤3)。


示例及说明


为了更好的理解如何使用fuse,我们这里实现一个具体的实例。该实例非常简单,这里并不是一个真正的文件系统,也不会访问磁盘,而是在该文件系统的根目录中显示一个固定的文件,也就是Hello-world文件。程序源代码

#define FUSE_USE_VERSION 26
#include <stdio.h>
#include <fuse.h>

/* 这里实现了一个遍历目录的功能,当用户在目录执行ls时,会回调到该函数,我们这里只是返回一个固定的文件Hello-world。 */
static int test_readdir(const char* path, void* buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* fi)
{
    printf( "tfs_readdir	 path : %s ", path);
 
    return filler(buf, "Hello-world", NULL, 0);
}

/* 显示文件属性 */
static int test_getattr(const char* path, struct stat *stbuf)
{
    printf("tfs_getattr	 path : %s ", path);
    if(strcmp(path, "/") == 0)
        stbuf->st_mode = 0755 | S_IFDIR;
    else
        stbuf->st_mode = 0644 | S_IFREG;
    return 0;
}

/*这里是回调函数集合,这里实现的很简单*/
static struct fuse_operations tfs_ops = {
   .readdir = test_readdir,
   .getattr = test_getattr,
};

int main(int argc, char *argv[])
{
     int ret = 0;
     ret = fuse_main(argc, argv, &tfs_ops, NULL);
     return ret;
}

编译运行
编译也是非常的简单,将上述内容复制到一个名为main.c文件中,然后执行如下命令:
gcc -o fuse_user main.c -D_FILE_OFFSET_BITS=64 -lfuse
假设在/tmp目录下面有一个file_on_fuse_fs目录,如果没有可以手动创建一个。然后执行如下命令可以在该目录挂载新的文件系统。

./fuse_user /tmp/file_on_fuse_fs

此时实际上已经有一个新的文件系统挂载在/tmp/file_on_fuse_fs目录下面,可以通过mount命令查看一下。
mount
可以看到输出内容中包含如下内容:
fuse_user on /tmp/file_on_fuse_fs type fuse.fuse_user (rw,nosuid,nodev)
也可以通过ls命令查看一下这个目录,比如:
ls -alh /tmp/file_on_fuse_fs
此时输出如下:

28db905d61a3d8728b8c39686cfd45fd.png


可以看出正式我们期望的内容,也就是只有一个名为Hello-world的文件。
至此,我们基本上了解了fuse的原理和如何基于fuse开发一个用户态的文件系统。由于fuse库对操作做了很多封装,因此实现起来并不复杂。后续我们再深入的介绍,包括fuse在内核中的实现和更为详细的用户态实现实例,以期我们对fuse有更加深入的理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值