fanotify hangs with multi-threaded programs

From: Jussi Maki
Date: Wed Jun 13 2012 - 05:20:53 EST


Hi,

Ran into a hang in open with a fanotify event listener which delegated the
processing via unix socket to a multi-threaded program that was opening
files from several threads. A patch for fixing this was posted in december
(http://marc.info/?l=linux-kernel&m=131822913806350&w=2), but it
wasn't merged.

Are there any plans for fixing this? This is a show stopper here as we can't
really use fanotify in production if there's a chance that multi-threaded
programs might hang any time they use open.

Here's test programs to reproduce this.

First one marks mount "/" for open perm events and returns
allow for everything and the second spawns 5 threads
which all loop opening a temporary file. If the first program
is running threads in the second will hang in
fanotify_get_response_from_access.

----
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

#include <linux/fanotify.h>

#define xperror(args...) { perror(args); exit(1); }

int main()
{
int fd = fanotify_init(FAN_CLASS_CONTENT, O_RDONLY);
if (fd < 0) {
xperror("init");
}

int ret = fanotify_mark(fd, FAN_MARK_ADD|FAN_MARK_MOUNT,
FAN_OPEN_PERM, AT_FDCWD, "/");
if (ret < 0) {
xperror("mark");
}

for(;;) {
struct fanotify_event_metadata event;
if (read(fd, &event, sizeof(event)) < 0) {
xperror("read");
}

struct fanotify_response resp = {
.fd = event.fd,
.response = FAN_ALLOW,
};

if (write(fd, &resp, sizeof(resp)) < 0) {
xperror("write");
}

close(event.fd);
}
}

----

#include <errno.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

static char *testfile;

void *thread(void *ctx)
{
char buf[512];
int fd;
for(;;) {
fd = open(testfile, O_RDONLY);
if (fd < 0) abort();
close(fd);
}
}

int main(int argc, char **argv)
{
int i = 0;
testfile = strdup("/tmp/fantest.XXXXXX");
int fd = mkstemp(testfile);
close(fd);

for(i = 0; i < 5; i++) {
pthread_t tid;
pthread_create(&tid, NULL, thread, NULL);
}
sleep(5);
unlink(testfile);
}

----

-- Jussi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/