uClibc + Fuse Deadlock problem progress!
Kevin Day
thekevinday at gmail.com
Sun Dec 16 15:39:39 PST 2007
For those who remember, I have been having nothing but trouble with
uClibc-0.9.29 when it comes to fuse and uClibc.
I finally identified the problem itself, but the cause is incredibly
confusing/evasive.
heres what I did:
- playing around with fuse mounted devices, I noticed that whenever I
told the fuse device to mount in the foreground, no deadlock would
occur, but every other case it would deadlock
- After walking through the fuse code, I came across the main
difference: when fuse is called in the foreground it skips calling the
function daemon(..).
- I already knew that this code worked in uClibc-0.9.28.3 without
deadlocking, but diffing between the two, there were no relevant
changes!
- I decided to grab the functions contents (as implemented in
uClibc-0.9.29) and directly replace the daemon(..) function call in
fuse with the contents of the function.
- I started with fork() and recompiled over again testing each
significant part of daemon(..) functions content.
As it turns out, every part of the daemon(..) code content worked
outside of the daemon(..) function call.
There is only one difference between the code: where I have
"/dev/null" the daeom(..) code has a macro.
Assuming the macro definition is valid, how exactly is identical code
NOT working inside the daemon(..) function, but is working outside of
it.
The only thing that comes to my mind is that something is optimizing
this function into a deadlock.
However, I distantly remember somebody talking about forking inside of
threaded code, perhaps this may be another case of such.
I am going to look over all of my other applications that were
deadlocking or otherwise crashing under 0.9.29 but not 0.9.28.3 to see
if they call daemon.
I am going to apply the same fix where daemon function calls are found
in hopes of producing a non-deadlocking, non-segfaulting program.
As you can see, the patch below uses almost the exact same code that
present in the daemon(..) function call:
--- fuse-2.7.1/lib/helper.c.orig 2007-12-16 10:48:34 -0600
+++ fuse-2.7.1/lib/helper.c 2007-12-16 10:48:49 -0600
@@ -175,13 +175,39 @@
int fuse_daemonize(int foreground)
{
int res;
+ int fd;
if (!foreground) {
- res = daemon(0, 0);
+ switch (res = fork()) {
+ case -1:
+ return(-1);
+ case 0:
+ break;
+ default:
+ _exit(0);
+ }
+
if (res == -1) {
perror("fuse: failed to daemonize program\n");
return -1;
}
+
+ res=setsid();
+
+ if (res == -1) {
+ perror("fuse: failed to daemonize program\n");
+ return -1;
+ }
+
+ chdir("/");
+
+ if (fd = open("/dev/null", O_RDWR, 0) != -1) {
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ if (fd > 2)
+ close(fd);
+ }
}
return 0;
}
--
Kevin Day
More information about the uClibc
mailing list