[gvfs/sam/fuse-shutdown-on-error] fuse: Shutdown cleanly if an error occurs in vfs_init()
- From: Sam Thursfield <sthursfield src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs/sam/fuse-shutdown-on-error] fuse: Shutdown cleanly if an error occurs in vfs_init()
- Date: Sun, 29 Sep 2019 12:25:27 +0000 (UTC)
commit 9ac6a512bdb19e56b4fce62221340b3286e0a6ec
Author: Sam Thursfield <sam afuera me uk>
Date: Sun Sep 29 14:12:36 2019 +0200
fuse: Shutdown cleanly if an error occurs in vfs_init()
I've been hitting the following problem:
* start a temporary DBus session
* run a program that calls into Gio
* gvfsd is autostarted, and gvfsd-fuse is started
* the program completes and the temporary bus shuts down
* gvfsd-fuse is still starting, and it encounters an error inside the
vfs_init() method like this:
** (process:6704): WARNING **: 12:55:27.957: Failed to connect to the D-BUS daemon: Could not
connect: Connection refused (g-io-error-quark, 39)
* gvfsd-fuse continues to the fuse main loop and never shuts down,
despite the error.
This leads to the temporary DBus session not shutting down as expected,
and leads to dangling 'gvfs' fuse mounts.
It seems like the problem is that the vfs_init() callback has no way
of signalling failure. So this commit moves the shutdown code into an
atexit() callback, which means we can safely call exit() from the
vfs_init() constructor
client/gvfsfusedaemon.c | 54 ++++++++++++++++++++++++++++++-------------------
1 file changed, 33 insertions(+), 21 deletions(-)
---
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c
index ff5641ae..bc9a6a2c 100644
--- a/client/gvfsfusedaemon.c
+++ b/client/gvfsfusedaemon.c
@@ -73,6 +73,9 @@ typedef struct {
goffset size;
} FileHandle;
+static char *mountpoint = NULL;
+static struct fuse *fuse = NULL;
+
static GThread *subthread = NULL;
static GMainLoop *subthread_main_loop = NULL;
static GVfs *gvfs = NULL;
@@ -2380,7 +2383,7 @@ register_fuse_cb (GVfsDBusMountTracker *proxy,
if (! gvfs_dbus_mount_tracker_call_register_fuse_finish (proxy, res, &error))
{
- g_printerr ("register_fuse_cb: Error sending a message: %s (%s, %d)\n",
+ g_printerr ("gvfsd-fuse: register_fuse_cb: Error sending a message: %s (%s, %d)\n",
error->message, g_quark_to_string (error->domain), error->code);
g_error_free (error);
}
@@ -2413,10 +2416,10 @@ vfs_init (struct fuse_conn_info *conn)
dbus_conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
if (! dbus_conn)
{
- g_warning ("Failed to connect to the D-BUS daemon: %s (%s, %d)",
- error->message, g_quark_to_string (error->domain), error->code);
+ g_printerr ("gvfsd-fuse: Failed to connect to the D-BUS daemon: %s (%s, %d)\n",
+ error->message, g_quark_to_string (error->domain), error->code);
g_error_free (error);
- return NULL;
+ exit (1);
}
g_dbus_connection_set_exit_on_close (dbus_conn, FALSE);
@@ -2430,10 +2433,10 @@ vfs_init (struct fuse_conn_info *conn)
&error);
if (proxy == NULL)
{
- g_printerr ("vfs_init(): Error creating proxy: %s (%s, %d)\n",
+ g_printerr ("gvfsd-fuse: vfs_init(): Error creating proxy: %s (%s, %d)\n",
error->message, g_quark_to_string (error->domain), error->code);
g_error_free (error);
- return NULL;
+ exit (1);
}
/* Allow the gvfs daemon autostart */
@@ -2544,13 +2547,31 @@ set_custom_signal_handlers (void (*handler)(int))
sigaction (SIGTERM, &sa, NULL);
}
+static void
+shutdown_fuse () {
+ struct fuse_chan *ch;
+ struct fuse_session *se;
+
+ if (fuse != NULL && mountpoint != NULL) {
+ /* Ignore new signals during exit procedure in order to terminate properly */
+ set_custom_signal_handlers (SIG_IGN);
+ fuse_remove_signal_handlers (se);
+
+ se = fuse_get_session (fuse);
+ ch = fuse_session_next_chan (se, NULL);
+
+ fuse_unmount (mountpoint, ch);
+ fuse_destroy (fuse);
+ free (mountpoint);
+
+ fuse = NULL;
+ mountpoint = NULL;
+ }
+}
+
gint
main (gint argc, gchar *argv [])
{
- struct fuse *fuse;
- struct fuse_chan *ch;
- struct fuse_session *se;
- char *mountpoint;
int multithreaded;
int res;
@@ -2559,22 +2580,13 @@ main (gint argc, gchar *argv [])
if (fuse == NULL)
return 1;
+ atexit (shutdown_fuse);
+
if (multithreaded)
res = fuse_loop_mt (fuse);
else
res = fuse_loop (fuse);
- se = fuse_get_session (fuse);
- ch = fuse_session_next_chan (se, NULL);
-
- /* Ignore new signals during exit procedure in order to terminate properly */
- set_custom_signal_handlers (SIG_IGN);
- fuse_remove_signal_handlers (se);
-
- fuse_unmount (mountpoint, ch);
- fuse_destroy (fuse);
- free (mountpoint);
-
if (res == -1)
return 1;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]