1

我想记录指定目录的每个系统调用,我找到了这个存储库https://github.com/rflament/loggedfs

它创建了一个带有 fuse 的虚拟文件系统并在其中记录所有内容,就像我想要的那样。

我试图将它移植到mac上,但它使用了一个在osx上不起作用的“技巧”。卡住10lstat秒并崩溃。

我想了解为什么?

这是我的代码的主要部分:

//  g++ -Wall main.cpp `pkg-config fuse --cflags --libs` -o hello

#define FUSE_USE_VERSION 26

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

static char *path;
static int  savefd;

static int getattr(const char *path, struct stat *stbuf)
{
    int res;
    char rPath[1024];

    strcpy(rPath, "."); strcat(rPath, path);

    res = lstat(rPath, stbuf); // Mac stuck here
    return (res == -1 ? -errno : 0); 
}

static void* loggedFS_init(struct fuse_conn_info* info)
{
     fchdir(savefd); close(savefd); return NULL;
}

int main(int argc, char *argv[])
{
    struct fuse_operations oper;

    bzero(&oper, sizeof(fuse_operations));
    oper.init       = loggedFS_init;
    oper.getattr    = getattr;

    path = strdup(argv[argc - 1]);
    printf("chdir to %s\n", path);
    chdir(path);
    savefd = open(".", 0); 

    return fuse_main(argc, argv, &oper, NULL);
}
4

1 回答 1

0

我非常仔细地查看了 LoggedFS 并使用pjdfstest对其进行了 POSIX 合规性测试,导致3 个问题(或问题组)。我最终在 Python 中重新实现了它,完全符合 POSIX 标准。我还没有在 OS X 上测试过,所以我很乐意收到一些反馈;)

您提到的“技巧”可能是您问题的根本原因,尽管我不完全确定。它通过向路径添加另一个字符导致一个基本问题,当长度path接近 PATH_MAX 时会导致问题。libfuse已经将带有前导的路径传递/给 FUSE 操作。额外.加上“误导” /(已安装文件系统的根目录,而不是“全局”根文件夹)是两个字符“太多”,有效地将最大允许路径长度减少到 PATH_MAX 减 2。我探索了更改 PATH_MAX 和通知的选项用户登陆软件关于较小的 PATH_MAX,结果证明是不可能的。

然而,有办法解决。不要关闭例程savefd中的文件描述符。init保持打开状态,而是在destroy例程中将其关闭,卸载文件系统时 FUSE 将调用该例程。您实际上可以savefd用于指定相对于它的路径。然后您可以使用fstatat( Linux , OS X/BSD ) 代替lstat. 它的原型是这样的:

int fstatat(int dirfd, const char *pathname, struct stat *buf,
        int flags);

在将其传递savefd给.dirfd/pathpathname

于 2018-01-19T19:41:45.410 回答