summaryrefslogtreecommitdiffstats
path: root/src/fuse
diff options
context:
space:
mode:
authorSimon Rettberg2020-07-24 11:24:42 +0200
committerSimon Rettberg2020-07-24 11:24:42 +0200
commitdf2887b3f9261373dd462c59b15c9e6f40c3afa5 (patch)
treef4dfca4bfc7c9bfcea81ec42229ccdce50aebc25 /src/fuse
parent[FUSE] Fix inode numbers (diff)
downloaddnbd3-df2887b3f9261373dd462c59b15c9e6f40c3afa5.tar.gz
dnbd3-df2887b3f9261373dd462c59b15c9e6f40c3afa5.tar.xz
dnbd3-df2887b3f9261373dd462c59b15c9e6f40c3afa5.zip
[FUSE] Refactor signal handling on termination again
Diffstat (limited to 'src/fuse')
-rw-r--r--src/fuse/connection.c30
-rw-r--r--src/fuse/connection.h2
-rw-r--r--src/fuse/main.c83
3 files changed, 55 insertions, 60 deletions
diff --git a/src/fuse/connection.c b/src/fuse/connection.c
index e7787e7..beb4a31 100644
--- a/src/fuse/connection.c
+++ b/src/fuse/connection.c
@@ -267,30 +267,27 @@ bool connection_read( dnbd3_async_t *request )
void connection_close()
{
+ static bool signalled = false;
if ( true ) {
logadd( LOG_INFO, "Tearing down dnbd3 connections and workers" );
}
pthread_mutex_lock( &mutexInit );
keepRunning = false;
+ if ( threadInitDone && !signalled ) {
+ signalled = true;
+ pthread_kill( tidReceiver, SIGHUP );
+ pthread_kill( tidBackground, SIGHUP );
+ }
+ pthread_mutex_unlock( &mutexInit );
if ( !connectionInitDone ) {
- pthread_mutex_unlock( &mutexInit );
return;
}
- pthread_mutex_unlock( &mutexInit );
pthread_mutex_lock( &connection.sendMutex );
if ( connection.sockFd != -1 ) {
+ logadd( LOG_DEBUG1, "Shutting down socket..." );
shutdown( connection.sockFd, SHUT_RDWR );
}
pthread_mutex_unlock( &connection.sendMutex );
- logadd( LOG_DEBUG1, "Connection closed." );
-}
-
-void connection_signalShutdown()
-{
- if ( !threadInitDone )
- return;
- pthread_kill( tidReceiver, SIGHUP );
- pthread_kill( tidBackground, SIGHUP );
}
void connection_join()
@@ -962,12 +959,17 @@ static dnbd3_async_t* removeRequest( dnbd3_async_t *request )
static void blockSignals()
{
sigset_t sigmask;
- sigemptyset( &sigmask );
+ if ( pthread_sigmask( 0, NULL, &sigmask ) == -1 ) {
+ logadd( LOG_WARNING, "Cannot get current sigmask of thread" );
+ sigemptyset( &sigmask );
+ }
sigaddset( &sigmask, SIGUSR1 );
sigaddset( &sigmask, SIGUSR2 );
sigaddset( &sigmask, SIGPIPE );
sigaddset( &sigmask, SIGINT );
sigaddset( &sigmask, SIGTERM );
- pthread_sigmask( SIG_SETMASK, &sigmask, NULL );
-
+ sigdelset( &sigmask, SIGHUP );
+ if ( pthread_sigmask( SIG_SETMASK, &sigmask, NULL ) == -1 ) {
+ logadd( LOG_WARNING, "Cannot set sigmask of thread" );
+ }
}
diff --git a/src/fuse/connection.h b/src/fuse/connection.h
index 04d8894..58017dd 100644
--- a/src/fuse/connection.h
+++ b/src/fuse/connection.h
@@ -33,8 +33,6 @@ bool connection_read( dnbd3_async_t *request );
void connection_close();
-void connection_signalShutdown();
-
void connection_join();
size_t connection_printStats( char *buffer, const size_t len );
diff --git a/src/fuse/main.c b/src/fuse/main.c
index 528d86f..70181ad 100644
--- a/src/fuse/main.c
+++ b/src/fuse/main.c
@@ -40,14 +40,14 @@
static const char *IMAGE_NAME = "img";
static const char *STATS_NAME = "status";
+static struct fuse_session *_fuseSession = NULL;
+
static uint64_t imageSize;
/* Debug/Benchmark variables */
static bool useDebug = false;
static log_info logInfo;
static struct timespec startupTime;
static uid_t owner;
-static void ( *fuse_sigIntHandler )(int) = NULL;
-static void ( *fuse_sigTermHandler )(int) = NULL;
static int reply_buf_limited( fuse_req_t req, const char *buf, size_t bufsize, off_t off, size_t maxsize );
static void fillStatsFile( fuse_req_t req, size_t size, off_t offset );
@@ -236,19 +236,9 @@ static void image_ll_read( fuse_req_t req, fuse_ino_t ino, size_t size, off_t of
}
}
-static void image_sigHandler( int signum )
+static void noopSigHandler( int signum )
{
- int temp_errno = errno; // Threadsanitizer: don't spoil errno
- keepRunning = false;
- if ( signum == SIGINT && fuse_sigIntHandler != NULL ) {
- fuse_sigIntHandler( signum );
- connection_signalShutdown();
- }
- if ( signum == SIGTERM && fuse_sigTermHandler != NULL ) {
- fuse_sigTermHandler( signum );
- connection_signalShutdown();
- }
- errno = temp_errno;
+ (void)signum;
}
static void image_ll_init( void *userdata, struct fuse_conn_info *conn )
@@ -257,22 +247,10 @@ static void image_ll_init( void *userdata, struct fuse_conn_info *conn )
( void ) conn;
if ( !connection_initThreads() ) {
logadd( LOG_ERROR, "Could not initialize threads for dnbd3 connection, exiting..." );
- exit( EXIT_FAILURE );
+ if ( _fuseSession != NULL ) {
+ fuse_session_exit( _fuseSession );
+ }
}
-
- // Prepare our handler
- struct sigaction newHandler;
- memset( &newHandler, 0, sizeof( newHandler ) );
- newHandler.sa_handler = &image_sigHandler;
- sigemptyset( &newHandler.sa_mask );
- struct sigaction oldHandler;
- // Retrieve old handlers when setting
- sigaction( SIGINT, &newHandler, &oldHandler );
- fuse_sigIntHandler = oldHandler.sa_handler;
- logadd( LOG_DEBUG1, "Previous SIGINT handler was %p", ( void* )(uintptr_t)fuse_sigIntHandler );
- sigaction( SIGTERM, &newHandler, &oldHandler );
- fuse_sigTermHandler = oldHandler.sa_handler;
- logadd( LOG_DEBUG1, "Previous SIGTERM handler was %p", ( void* )(uintptr_t)fuse_sigIntHandler );
}
/* close the connection */
@@ -282,7 +260,6 @@ static void image_destroy( void *private_data UNUSED )
printLog( &logInfo );
}
connection_close();
- return;
}
/* map the implemented fuse operations */
@@ -414,7 +391,7 @@ int main( int argc, char *argv[] )
learnNewServers = false;
break;
case 'f':
- newArgv[newArgc++] = "-f";
+ foreground = 1;
break;
default:
printUsage( argv[0], EXIT_FAILURE );
@@ -435,6 +412,17 @@ int main( int argc, char *argv[] )
}
}
+ // Prepare our handler
+ struct sigaction newHandler;
+ memset( &newHandler, 0, sizeof( newHandler ) );
+ newHandler.sa_handler = &noopSigHandler;
+ sigemptyset( &newHandler.sa_mask );
+ sigaction( SIGHUP, &newHandler, NULL );
+ sigset_t sigmask;
+ sigemptyset( &sigmask );
+ sigaddset( &sigmask, SIGHUP );
+ pthread_sigmask( SIG_BLOCK, &sigmask, NULL );
+
if ( !connection_init( server_address, image_Name, rid, learnNewServers ) ) {
logadd( LOG_ERROR, "Could not connect to any server. Bye.\n" );
return EXIT_FAILURE;
@@ -468,29 +456,36 @@ int main( int argc, char *argv[] )
// Fuse lowlevel loop
struct fuse_args args = FUSE_ARGS_INIT( newArgc, newArgv );
int fuse_err = 1;
- if ( fuse_parse_cmdline( &args, &mountpoint, NULL, NULL ) != -1 && ( ch = fuse_mount( mountpoint, &args ) ) != NULL ) {
- struct fuse_session *se;
-
- se = fuse_lowlevel_new( &args, &image_oper, sizeof( image_oper ), NULL );
- if ( se != NULL ) {
- if ( fuse_set_signal_handlers( se ) != -1 ) {
- fuse_session_add_chan( se, ch );
- //fuse_daemonize(foreground);
+ if ( fuse_parse_cmdline( &args, &mountpoint, NULL, NULL ) == -1 ) {
+ logadd( LOG_ERROR, "FUSE: Parsing command line failed" );
+ } else if ( ( ch = fuse_mount( mountpoint, &args ) ) == NULL ) {
+ logadd( LOG_ERROR, "Mounting file system failed" );
+ } else {
+ _fuseSession = fuse_lowlevel_new( &args, &image_oper, sizeof( image_oper ), NULL );
+ if ( _fuseSession == NULL ) {
+ logadd( LOG_ERROR, "Could not initialize fuse session" );
+ } else {
+ if ( fuse_set_signal_handlers( _fuseSession ) == -1 ) {
+ logadd( LOG_ERROR, "Could not install fuse signal handlers" );
+ } else {
+ fuse_session_add_chan( _fuseSession, ch );
+ fuse_daemonize( foreground );
if ( single_thread ) {
- fuse_err = fuse_session_loop( se );
+ fuse_err = fuse_session_loop( _fuseSession );
} else {
- fuse_err = fuse_session_loop_mt( se ); //MT produces errors (race conditions) in libfuse and didnt improve speed at all
+ fuse_err = fuse_session_loop_mt( _fuseSession ); //MT produces errors (race conditions) in libfuse and didnt improve speed at all
}
- fuse_remove_signal_handlers( se );
+ fuse_remove_signal_handlers( _fuseSession );
fuse_session_remove_chan( ch );
}
- fuse_session_destroy( se );
+ fuse_session_destroy( _fuseSession );
+ _fuseSession = NULL;
}
fuse_unmount( mountpoint, ch );
}
fuse_opt_free_args( &args );
free( newArgv );
- logadd( LOG_DEBUG1, "Terminating. FUSE REPLIED: %d\n", fuse_err );
connection_join();
+ logadd( LOG_DEBUG1, "Terminating. FUSE REPLIED: %d\n", fuse_err );
return fuse_err;
}