[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHn8xck=gL34Ht7nngiRJwOvRPz_pMCc5ySGYb_eCG073kzVpw@mail.gmail.com>
Date: Wed, 13 Jun 2012 12:20:48 +0300
From: Jussi Maki <joamaki@...il.com>
To: LinoSanfilippo@....de, eparis@...hat.com
Cc: linux-kernel@...r.kernel.org
Subject: fanotify hangs with multi-threaded programs
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@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists