一、libfuse3
libfuse3是一個用戶空間的文件系統框架,它允許開發人員在Linux上實現不同的虛擬文件系統。它是libfuse的升級版本,相比之下有更好的性能和更好的穩定性,並提供新的功能和API。
#include <fuse3/fuse.h>
static int hello_getattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi)
{
int res = 0;
memset(stbuf, 0, sizeof(struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else if (strcmp(path, "/hello") == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(hello_str);
} else
res = -ENOENT;
return res;
}
static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi, enum fuse_readdir_flags flags)
{
if (strcmp(path, "/") != 0)
return -ENOENT;
filler(buf, ".", NULL, 0, FUSE_FILL_DIR_PLUS);
filler(buf, "..", NULL, 0, FUSE_FILL_DIR_PLUS);
filler(buf, "hello", NULL, 0, FUSE_FILL_DIR_PLUS);
return 0;
}
static int hello_open(const char *path, struct fuse_file_info *fi)
{
if (strcmp(path, "/hello") != 0)
return -ENOENT;
if ((fi->flags & 3) != O_RDONLY)
return -EACCES;
return 0;
}
static int hello_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
size_t len;
(void) fi;
if(strcmp(path,"/hello") != 0)
return -ENOENT;
len = strlen(hello_str);
if (offset len)
size = len - offset;
memcpy(buf, hello_str + offset, size);
} else
size = 0;
return size;
}
static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};
int main(int argc, char *argv[])
{
return fuse_main(argc, argv, &hello_oper, NULL);
}二、libfuse.so.2 is needed by
如果編譯時出現類似”libfuse.so.2 is needed by”的錯誤,則需要安裝fuse-devel(如CentOS)或libfuse-dev(如Ubuntu)。
三、libfuse.so
如果編譯時出現類似”libfuse.so: undefined reference to”的錯誤信息,可能是由於鏈接器無法找到正確版本的libfuse庫(.so文件)。可以通過將包含libfuse庫的目錄添加到LD_LIBRARY_PATH環境變量中,或者使用-L選項指定libfuse庫所在的目錄。
四、libfuse使用
使用libfuse開發用戶空間文件系統需要實現一組回調函數,這些回調函數將負責實現用戶空間文件系統的行為,如獲取文件屬性、讀寫文件和目錄遍歷等等。libfuse將這些回調函數打包到一個結構體中,然後在mount操作中註冊這個結構體,以將用戶空間的文件系統掛載到Linux文件系統中。
以下是使用libfuse實現簡單用戶空間文件系統的示例:
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
static const char *hello_str = "Hello World!\n";
static const char *hello_path = "/hello";
static int hello_getattr(const char *path, struct stat *stbuf)
{
int res = 0;
memset(stbuf, 0, sizeof(struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else if (strcmp(path, hello_path) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(hello_str);
} else
res = -ENOENT;
return res;
}
static int hello_open(const char *path, struct fuse_file_info *fi)
{
if (strcmp(path, hello_path) != 0)
return -ENOENT;
if ((fi->flags & 3) != O_RDONLY)
return -EACCES;
return 0;
}
static int hello_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
{
size_t len;
(void) fi;
if(strcmp(path,hello_path) != 0)
return -ENOENT;
len = strlen(hello_str);
if (offset len)
size = len - offset;
memcpy(buf, hello_str + offset, size);
} else
size = 0;
return size;
}
static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.open = hello_open,
.read = hello_read,
};
int main(int argc, char *argv[])
{
return fuse_main(argc, argv, &hello_oper, NULL);
}五、libfuse寫優化 拷貝內存
在使用libfuse編寫用戶空間文件系統時,需要注意減少拷貝內存的次數。為了儘可能減少數據拷貝,可以使用Linux的sendfile系統調用和splice系統調用來減少進程間數據移動(例如從網絡套接字到用戶空間緩衝區)。而應使用read和write系統調用,不應使用fread和fwrite等高級I / O函數。
六、libfuse arm linux
libfuse可用於嵌入式Linux ARM平台。開發人員需要確保ARM編譯器和libfuse庫都可用,並且需要導出以下環境變量才能正確引用庫:
export PKG_CONFIG_SYSROOT_DIR=path/to/sysroot
export PKG_CONFIG_PATH=path/to/pkgconfig/folder
export ACLOCAL_PATH=path/to/aclocal/folder七、libfuse-dev 找不到
如果在使用Ubuntu時嘗試安裝libfuse-dev並出現”無法找到libfuse-dev”的錯誤消息,您可以安裝libfuse-dev包的替代方法是使用pkg-config工具和fuse.pc文件安裝libfuse的開發。可以使用以下命令來安裝:
sudo apt-get install pkg-config
pkg-config --list-all | grep fuse
sudo apt-get install libfuse3-dev原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/151060.html
微信掃一掃
支付寶掃一掃