2017-01-30 35 views
1

我想记录的指定目录的每一个系统调用我发现这个仓库https://github.com/rflament/loggedfsloggedfs在Mac与osxfuse卡住

,它创建一个保险丝一个虚拟文件系统,并在其记录的一切,就像我想要的。

我试图在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); 
} 
+0

rPath是否包含装载驱动器的路径? 不知道我是否理解你的问题,但你不应该从驱动器的保险丝回调中做​​任何文件操作 - 它会导致死锁 – DoN1cK

回答

0

我在LoggedFS非常密切的外观和使用pjdfstest,导致3 issues (or groups of issues)测试了POSIX标准。我结束了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); 

你要通过savefddirfd并将其传递到pathname之前删除从path内容的领先/