From 99a9b5a45a524ffa41d0338ed729dfad9b2ca885 Mon Sep 17 00:00:00 2001 From: Giovanni Panozzo Date: Sun, 17 Mar 2019 10:56:07 +0100 Subject: FUSE cleanup --- src/remmina_exec.c | 4 ++++ src/remmina_fuse.c | 62 ++++++++++++++++++++++++++++++++++++++++-------------- src/remmina_fuse.h | 1 + 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/remmina_exec.c b/src/remmina_exec.c index f8e3802d3..0e4ab14a7 100644 --- a/src/remmina_exec.c +++ b/src/remmina_exec.c @@ -45,6 +45,7 @@ #include "remmina_pref_dialog.h" #include "remmina_file.h" #include "remmina_pref.h" +#include "remmina_fuse.h" #include "remmina_file_editor.h" #include "rcw.h" #include "remmina_about.h" @@ -84,6 +85,9 @@ const gchar* remmina_exec_get_build_config(void) void remmina_exec_exitremmina() { TRACE_CALL(__func__); + + /* deinitialize fuse */ + remmina_fuse_cleanup(); /* Save main window state/position */ remmina_main_save_before_destroy(); diff --git a/src/remmina_fuse.c b/src/remmina_fuse.c index 671d60737..ebffde406 100644 --- a/src/remmina_fuse.c +++ b/src/remmina_fuse.c @@ -56,12 +56,12 @@ static struct fuse_args args = { static const gchar fuse_subdir[] = "/remmina"; static pthread_t ft; +struct fuse_session *se; /* DEMO */ static const char *hello_str = "Hello World!\n"; static const char *hello_name = "hello"; - static int rfuse_stat(fuse_ino_t ino, struct stat *stbuf) { stbuf->st_ino = ino; @@ -83,7 +83,6 @@ static int rfuse_stat(fuse_ino_t ino, struct stat *stbuf) return 0; } - static void rfuse_lookup(fuse_req_t req, fuse_ino_t parent, const char *name) { struct fuse_entry_param e; @@ -200,23 +199,19 @@ static struct fuse_lowlevel_ops hello_ll_oper = { static void *fuse_thread_start(void *arg) { - struct fuse_session *se; - int err = -1; - - g_print("GIO: fuse thread!\n"); - se = fuse_lowlevel_new(&args, &hello_ll_oper, sizeof(hello_ll_oper), NULL); if (se != NULL) { + fuse_set_signal_handlers(se); fuse_session_add_chan(se, fuse_ch); - err = fuse_session_loop(se); + fuse_session_loop(se); fuse_session_remove_chan(fuse_ch); + fuse_session_destroy(se); + se = NULL; } - fuse_session_destroy(se); fuse_unmount(fuse_mountpoint, fuse_ch); - g_free(fuse_mountpoint); - fuse_initialized = FALSE; - - g_print("GIO: fuse thread ENDED, err=%d.\n",err); + rmdir(fuse_mountpoint); + g_free(fuse_mountpoint); + fuse_initialized = FALSE; return NULL; } @@ -234,6 +229,18 @@ void remmina_fuse_init() rtdir = g_get_user_runtime_dir(); fuse_remmina_topdir = g_strdup_printf("%s/%s", rtdir, fuse_subdir); + + /* Try to create fuse_remmina_topdir */ + if (!g_file_test(fuse_remmina_topdir, G_FILE_TEST_EXISTS)) { + mkdir(fuse_remmina_topdir, 0700); + } + if (!g_file_test(fuse_remmina_topdir, G_FILE_TEST_IS_DIR)) { + g_print("REMMINA WARNING: %s should be a directory, but it's not. Cannot initialize FUSE.\n", fuse_remmina_topdir); + g_free(fuse_remmina_topdir); + return; + } + + /* Try to delete all undeleted/old mountdirs */ d = opendir(fuse_remmina_topdir); if (d) { @@ -256,13 +263,15 @@ void remmina_fuse_init() } if (!g_file_test(fuse_mountpoint, G_FILE_TEST_IS_DIR)) { - g_print("REMMINA WARNING: %s should be a directory, but it's not.\n", fuse_mountpoint); + g_print("REMMINA WARNING: %s should be a directory, but it's not. Cannot initialize FUSE.\n", fuse_mountpoint); g_free(fuse_mountpoint); + return; } if (!(fuse_ch = fuse_mount(fuse_mountpoint, &args))) { - g_print("REMMINA WARNING: Unable to mount fuse directory on %s\n", fuse_mountpoint); + g_print("REMMINA WARNING: Unable to mount fuse directory on %s. Cannot initialize FUSE.\n", fuse_mountpoint); g_free(fuse_mountpoint); + return; } fuse_initialized = TRUE; @@ -271,12 +280,33 @@ void remmina_fuse_init() fuse_unmount(fuse_mountpoint, fuse_ch); g_free(fuse_mountpoint); fuse_initialized = FALSE; + return; } } void remmina_fuse_cleanup() { - + if (fuse_initialized) { + fuse_session_exit(se); + usleep(10000); + if (fuse_initialized) { + pthread_kill(ft, SIGINT); // Use SIGINT, captured with fuse_set_signal_handlers() + usleep(200000); // We need at least 40ms on a core i3 for a regular fuse_session_exit to complete + } + } + if (fuse_initialized) { + /* Fuse thread don't want to terminate. Try to hard terminate */ + g_print("REMMINA WARNING: hard terminating fuse thread.\n"); + pthread_cancel(ft); + if (se) { + fuse_session_destroy(se); + se = NULL; + } + fuse_unmount(fuse_mountpoint, fuse_ch); + rmdir(fuse_mountpoint); + g_free(fuse_mountpoint); + fuse_initialized = FALSE; + } } diff --git a/src/remmina_fuse.h b/src/remmina_fuse.h index 1ad2e8711..7ef422d5e 100644 --- a/src/remmina_fuse.h +++ b/src/remmina_fuse.h @@ -38,6 +38,7 @@ G_BEGIN_DECLS void remmina_fuse_init(void); +void remmina_fuse_cleanup(void); G_END_DECLS -- cgit v1.2.3