I would like to log every syscall of a specified directory and I've found this repository https://github.com/rflament/loggedfs
It creates a virtual filesystem with fuse and log everything in it, just like I want.
I tried to port it on mac but it uses a "trick" that doesn't works on osx. The lstat
is stuck 10s and crash.
I would like to understand why ?
This is a main part of my code :
// 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);
}
I had a very close look at LoggedFS and tested it for POSIX compliance using pjdfstest, resulting in 3 issues (or groups of issues). I ended up re-implementing it in Python, fully POSIX compliant. I have not tested it on OS X yet, so I'd be happy to receive some feedback ;)
The "trick" you are mentioning could be the root cause of your issue, although I am not entirely sure. It causes a fundamental problem by adding another character to the path, which leads to issues when the length of
path
gets close to PATH_MAX.libfuse
already passes paths with a leading/
into FUSE operations. The additional.
plus the "misleading"/
(root of the mounted filesystem, not the "global" root folder) are two characters "too many", effectively reducing the maximum allowed path length to PATH_MAX minus 2. I explored options of altering PATH_MAX and informing user land software about a smaller PATH_MAX, which turned out to be impossible.There is a way around, however. Do not close the file descriptor
savefd
in theinit
routine. Keep it open and instead close it in thedestroy
routine, which will be called by FUSE when the filesystem is unmounted. You can actually usesavefd
for specifying paths relative to it. You can then usefstatat
(Linux, OS X / BSD) instead oflstat
. Its prototype looks like this:You have to pass
savefd
intodirfd
and remove the leading/
from the content ofpath
before passing it intopathname
.