【问题标题】:loggedfs on mac with osxfuse stuckosxfuse卡在mac上的loggedfs
【发布时间】:2017-06-15 22:45:21
【问题描述】:

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

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

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

我想知道为什么?

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

//  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);
}

【问题讨论】:

  • rPath 是否包含安装驱动器的路径?不确定我是否理解你的问题,但你不应该通过 fuse 回调在驱动器中执行任何文件操作 - 这会导致死锁

标签: c++ linux macos fuse osxfuse


【解决方案1】:

我非常仔细地查看了 LoggedFS,并使用pjdfstest 对其进行了 POSIX 合规性测试,结果为3 issues (or groups of issues)。我最终选择了re-implementing it in Python,完全符合 POSIX。我还没有在 OS X 上测试过,所以我很乐意收到一些反馈;)

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

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

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

您必须将savefd 传递给dirfd,并从path 的内容中删除前导/,然后再将其传递给pathname

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 1970-01-01
    • 2020-09-14
    • 2013-05-02
    • 2013-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多