diff options
Diffstat (limited to 'src/bitz-server.cpp')
| -rw-r--r-- | src/bitz-server.cpp | 100 | 
1 files changed, 59 insertions, 41 deletions
diff --git a/src/bitz-server.cpp b/src/bitz-server.cpp index d6257fd..e99078e 100644 --- a/src/bitz-server.cpp +++ b/src/bitz-server.cpp @@ -29,6 +29,8 @@  #include <sys/stat.h>  #include <sys/wait.h> +#include <spdlog/spdlog.h> +  #include <config.h>  #include "bitz-server.h" @@ -41,15 +43,12 @@ namespace bitz {  		void init() {  			// initialise defaults -			globals.pid_handle  = -1; +			globals.pid         = -1; +			globals.pidfd       = -1;  			globals.manager     = NULL;  			globals.terminating = 0;  			globals.daemon      = false; -			// logger (syslog) -			setlogmask( LOG_UPTO( LOG_INFO ) ); -			openlog( PACKAGE_NAME, LOG_CONS, LOG_USER ); -  			// signal handlers  			init_signal_handlers(); @@ -100,9 +99,10 @@ namespace bitz {  			pid_t worker_pid;  			int status; -			std::cout << "[" << getpid() << "] inside zombie deleter: "; +			auto logger = spdlog::get( "bitz-server" ); +			logger->trace( "[{}] inside zombie reaper", getpid() );  			while ( ( worker_pid = waitpid( WAIT_ANY, &status, WNOHANG ) ) > 0 ) { -				std::cout << "child " << worker_pid << " terminated with status " << status << std::endl; +				logger->trace( "[reaper] child {} terminated with status {}", worker_pid, status );  				if ( globals.manager != NULL ) {  					globals.manager->reap_worker( worker_pid ); @@ -134,7 +134,8 @@ namespace bitz {  		void sigterm_handler( int sig, siginfo_t *siginfo, void *context ) { -			std::cout << "[" << getpid() << "] inside SIGTERM handler" << std::endl; +			auto logger = spdlog::get( "bitz-server" ); +			logger->trace( "[{}] inside SIGTERM handler", getpid() );  			termination_handler( sig, siginfo, context );  		} @@ -162,7 +163,8 @@ namespace bitz {  		void sigquit_handler( int sig, siginfo_t *siginfo, void *context ) { -			std::cout << "[" << getpid() << "] inside SIGQUIT handler" << std::endl; +			auto logger = spdlog::get( "bitz-server" ); +			logger->trace( "[{}] inside SIGQUIT handler", getpid() );  			termination_handler( sig, siginfo, context );  		} @@ -190,7 +192,8 @@ namespace bitz {  		void sigint_handler(  int sig, siginfo_t *siginfo, void *context ) { -			std::cout << "[" << getpid() << "] inside SIGQINT handler" << std::endl; +			auto logger = spdlog::get( "bitz-server" ); +			logger->trace( "[{}] inside SIGQINT handler", getpid() );  			termination_handler( sig, siginfo, context );  		} @@ -198,20 +201,28 @@ namespace bitz {  		void daemonize( const char *rundir, const char *pidfile ) { -			pid_t pid, sid; +			pid_t pid;  			long i;  			char str[10]; -			// notify -			syslog( LOG_NOTICE, "starting daemon (version %s)", PACKAGE_VERSION ); +			/* fork daemon */ +			pid = fork(); +			if ( pid < 0 ) { +				exit( EXIT_FAILURE ); +			} -			// check parent process id value -			if ( getppid() == 1 ) { -				// we are already a daemon -				return; +			// exit the parent +			if ( pid > 0 ) { +				exit( EXIT_SUCCESS );  			} -			/* fork daemon */ +			// get a new process group +			if ( setsid() < 0 ) { +				exit(EXIT_FAILURE); +			} + + +			// 2nd fork (to make PID != SID)  			pid = fork();  			if ( pid < 0 ) {  				exit( EXIT_FAILURE ); @@ -224,63 +235,67 @@ namespace bitz {  			/* child (a.k.a daemon) continues */ -  			// set file permissions (750)  			umask( 027 ); -			// get a new process group -			sid = setsid(); -			if ( sid < 0 ) { -				exit(EXIT_FAILURE); +			// change running directory +			chdir( rundir ); + +			// close all open file descriptors +			for ( int fd = sysconf( _SC_OPEN_MAX ); fd > 0; fd-- ) { +				close( fd );  			} -			// route I/O connections -			close( STDIN_FILENO ); -			close( STDOUT_FILENO ); -			close( STDERR_FILENO ); -			// change running directory -			chdir( rundir ); +			// logger (syslog) +			setlogmask( LOG_UPTO( LOG_INFO ) ); +			openlog( PACKAGE_NAME, LOG_CONS, LOG_USER ); + +			// notify +			syslog( LOG_NOTICE, "starting daemon (version %s)", PACKAGE_VERSION );  			/* lock pid file to ensure we have only one copy */ -			globals.pid_handle = open( pidfile, O_RDWR | O_CREAT, 0600 ); -			if ( globals.pid_handle == -1 ) { +			globals.pidfd = open( pidfile, O_RDWR | O_CREAT, 0600 ); +			if ( globals.pidfd == -1 ) {  				syslog( LOG_ERR, "could not open pid lock file: %s", pidfile );  				exit( EXIT_FAILURE );  			} -			if ( lockf( globals.pid_handle, F_TLOCK, 0 ) == -1 ) { +			if ( lockf( globals.pidfd, F_TLOCK, 0 ) == -1 ) {  				syslog( LOG_ERR, "could not lock pid lock file: %s", pidfile);  				exit( EXIT_FAILURE );  			}  			// get and format pid -			sprintf( str, "%d\n", getpid() ); +			globals.pid = getpid(); +			sprintf( str, "%d\n", globals.pid );  			// write pid to lockfile -			write( globals.pid_handle, str, strlen( str ) ); +			write( globals.pidfd, str, strlen( str ) );  			// update status  			globals.daemon = true; -  		}  		void shutdown() {  			// notify -			if ( globals.daemon && ( getppid() == 1 ) ) { +			if ( globals.daemon && ( getpid() == globals.pid ) ) {  				syslog( LOG_NOTICE, "shutting down daemon (version %s)", PACKAGE_VERSION );  			}  			// close pid file -			if ( globals.pid_handle != -1 ) { -				close( globals.pid_handle ); +			if ( globals.pidfd != -1 ) { +				close( globals.pidfd );  			} +			// flush logs +			spdlog::get( "bitz-server" )->flush(); +  			// close logger (syslog)  			closelog(); @@ -289,12 +304,15 @@ namespace bitz {  		void termination_handler( int sig, siginfo_t * sig_info, void * context ) { -			std::cout << "[" << getpid() << "] inside termination handler" << std::endl; +			pid_t pid = getpid(); +			auto logger = spdlog::get( "bitz-server" ); +			logger->trace( "[{}] inside termination handler", pid );  			// exit by re-raising the signal if termination  			// already in progress  			if ( globals.terminating ) { -				std::cout << "[" << getpid() << "] already terminating" << std::endl; +				logger->warn( "[{}] already terminating", pid ); +  				raise( sig );  			} @@ -455,7 +473,7 @@ namespace bitz {  				sigprocmask( SIG_UNBLOCK, &mask, NULL );  				// manage workers -				globals.manager->manager_workers(); +				globals.manager->manage_workers();  				// block termination signals  				sigprocmask( SIG_BLOCK, &mask, &oldmask );  | 
