lock pidfile, remove pidfile on INT or TERM

This commit is contained in:
Axel Kittenberger 2013-07-30 12:20:23 +02:00
parent 6f4613c53a
commit 25d2405906
3 changed files with 132 additions and 39 deletions

View File

@ -49,9 +49,11 @@
#define DEV_FSEVENTS "/dev/fsevents" #define DEV_FSEVENTS "/dev/fsevents"
/* buffer for reading from the device */ /* buffer for reading from the device */
#define FSEVENT_BUFSIZ 131072 #define FSEVENT_BUFSIZ 131072
/* limited by MAX_KFS_EVENTS */ /* limited by MAX_KFS_EVENTS */
#define EVENT_QUEUE_SIZE 4096 #define EVENT_QUEUE_SIZE 4096
#define KFS_NUM_ARGS FSE_MAX_ARGS #define KFS_NUM_ARGS FSE_MAX_ARGS
/* OS 10.5 structuce */ /* OS 10.5 structuce */
@ -175,8 +177,13 @@ handle_event(lua_State *L, struct kfs_event *event, ssize_t mlen)
logstring("Fsevents", "contains dropped events"); logstring("Fsevents", "contains dropped events");
}*/ }*/
} else { } else {
printlogf(L, "Error", "unknown event(%d) in fsevents.", printlogf(
atype); L,
"Error",
"unknown event(%d) in fsevents.",
atype
);
exit(-1); // ERRNO exit(-1); // ERRNO
} }

136
lsyncd.c
View File

@ -126,6 +126,8 @@ static bool first_time = true;
*/ */
volatile sig_atomic_t hup = 0; volatile sig_atomic_t hup = 0;
volatile sig_atomic_t term = 0; volatile sig_atomic_t term = 0;
volatile sig_atomic_t sigcode = 0;
int pidfile_fd = 0;
/* /*
| The kernel's clock ticks per second. | The kernel's clock ticks per second.
@ -144,11 +146,19 @@ sig_child(int sig) {
* signal handler * signal handler
*/ */
void void
sig_handler(int sig) sig_handler( int sig )
{ {
switch (sig) { switch( sig )
case SIGTERM: term = 1; return; {
case SIGHUP: hup = 1; return; case SIGTERM:
case SIGINT:
term = 1;
sigcode = sig;
return;
case SIGHUP:
hup = 1;
return;
} }
} }
@ -655,23 +665,44 @@ non_block_fd( int fd )
| Writes a pid file. | Writes a pid file.
*/ */
static void static void
write_pidfile( lua_State *L, const char *pidfile ) write_pidfile(
lua_State *L,
const char *pidfile
)
{ {
FILE* f = fopen( pidfile, "w" ); pidfile_fd = open( pidfile, O_CREAT | O_RDWR | O_CLOEXEC, 0644 );
if( !f ) char buf[ 127 ];
if( pidfile_fd < 0 )
{ {
printlogf( printlogf(
L, "Error", L, "Error",
"Cannot write pidfile; '%s'", "Cannot create pidfile; '%s'",
pidfile pidfile
) );
;
exit( -1 ); exit( -1 );
} }
fprintf( f, "%i\n", getpid( ) ); int rc = lockf( pidfile_fd, F_TLOCK, 0 );
fclose( f );
if( rc < 0 )
{
printlogf(
L, "Error",
"Cannot lock pidfile; '%s'",
pidfile
);
exit( -1 );
}
snprintf( buf, sizeof( buf ), "%i\n", getpid( ) );
write( pidfile_fd, buf, strlen( buf ) );
//fclose( f );
} }
@ -871,7 +902,9 @@ user_obs_ready(
// calls the user function // calls the user function
if( lua_pcall( L, 1, 0, -3 ) ) if( lua_pcall( L, 1, 0, -3 ) )
{ exit( -1 ); } {
exit( -1 );
}
lua_pop( L, 2 ); lua_pop( L, 2 );
} }
@ -1545,18 +1578,24 @@ l_configure( lua_State *L )
const char * file = luaL_checkstring( L, 2 ); const char * file = luaL_checkstring( L, 2 );
if( settings.log_file ) if( settings.log_file )
{ free( settings.log_file ); } {
free( settings.log_file );
}
settings.log_file = s_strdup( file ); settings.log_file =
s_strdup( file );
} }
else if( !strcmp( command, "pidfile" ) ) else if( !strcmp( command, "pidfile" ) )
{ {
const char * file = luaL_checkstring( L, 2 ); const char * file = luaL_checkstring( L, 2 );
if( settings.pidfile ) if( settings.pidfile )
{ free( settings.pidfile ); } {
free( settings.pidfile );
}
settings.pidfile = s_strdup( file ); settings.pidfile =
s_strdup( file );
} }
else if( !strcmp( command, "logfacility" ) ) else if( !strcmp( command, "logfacility" ) )
{ {
@ -2167,7 +2206,9 @@ masterloop(lua_State *L)
// Checks for signals // Checks for signals
if( hup || term ) if( hup || term )
{ break; } {
break;
}
// a file descriptor became read-ready // a file descriptor became read-ready
if( obs->ready && FD_ISSET( obs->fd, &rfds ) ) if( obs->ready && FD_ISSET( obs->fd, &rfds ) )
@ -2176,8 +2217,10 @@ masterloop(lua_State *L)
} }
// Checks for signals, again, better safe than sorry // Checks for signals, again, better safe than sorry
if (hup || term) if ( hup || term )
{ break; } {
break;
}
// FIXME breaks on multiple nonobservances in one beat // FIXME breaks on multiple nonobservances in one beat
if( if(
@ -2200,7 +2243,7 @@ masterloop(lua_State *L)
// works through delayed nonobserve_fd() calls // works through delayed nonobserve_fd() calls
for (pi = 0; pi < nonobservances_len; pi++) for (pi = 0; pi < nonobservances_len; pi++)
{ {
nonobserve_fd(nonobservances[pi]); nonobserve_fd( nonobservances[ pi ] );
} }
nonobservances_len = 0; nonobservances_len = 0;
@ -2235,32 +2278,44 @@ masterloop(lua_State *L)
if( hup ) if( hup )
{ {
load_runner_func( L, "hup" ); load_runner_func( L, "hup" );
if( lua_pcall( L, 0, 0, -2 ) ) if( lua_pcall( L, 0, 0, -2 ) )
{ {
exit( -1 ); exit( -1 );
} }
lua_pop( L, 1 ); lua_pop( L, 1 );
hup = 0; hup = 0;
} }
// reacts on TERM signals // reacts on TERM and INT signals
if( term == 1 ) if( term == 1 )
{ {
load_runner_func( L, "term" ); load_runner_func( L, "term" );
if( lua_pcall( L, 0, 0, -2 ) )
lua_pushnumber( L, sigcode );
if( lua_pcall( L, 1, 0, -3 ) )
{ {
exit( -1 ); exit( -1 );
} }
lua_pop( L, 1 ); lua_pop( L, 1 );
term = 2; term = 2;
} }
// lets the runner do stuff every cycle, // lets the runner do stuff every cycle,
// like starting new processes, writing the statusfile etc. // like starting new processes, writing the statusfile etc.
load_runner_func( L, "cycle" ); load_runner_func( L, "cycle" );
l_now( L ); l_now( L );
if( lua_pcall( L, 1, 1, -3 ) ) if( lua_pcall( L, 1, 1, -3 ) )
{ exit( -1 ); } {
exit( -1 );
}
if( !lua_toboolean( L, -1 ) ) if( !lua_toboolean( L, -1 ) )
{ {
@ -2523,7 +2578,7 @@ main1( int argc, char *argv[] )
} }
// prepares the defaults // prepares the defaults
if (lua_pcall( L, 0, 0, 0 ) ) if( lua_pcall( L, 0, 0, 0 ) )
{ {
printlogf( printlogf(
L, "Error", L, "Error",
@ -2545,10 +2600,12 @@ main1( int argc, char *argv[] )
!strcmp( argv[ i ], "--help" ) !strcmp( argv[ i ], "--help" )
) )
{ {
load_runner_func(L, "help"); load_runner_func( L, "help" );
if (lua_pcall(L, 0, 0, -2)) if( lua_pcall( L, 0, 0, -2 ) )
{ exit( -1 ); } {
exit( -1 );
}
lua_pop( L, 1 ); lua_pop( L, 1 );
exit( 0 ); exit( 0 );
@ -2584,7 +2641,9 @@ main1( int argc, char *argv[] )
} }
if( lua_pcall( L, 2, 1, -4 ) ) if( lua_pcall( L, 2, 1, -4 ) )
{ exit( -1 ); } {
exit( -1 );
}
if( first_time ) if( first_time )
{ {
@ -2681,6 +2740,7 @@ main1( int argc, char *argv[] )
signal( SIGHUP, sig_handler ); signal( SIGHUP, sig_handler );
signal( SIGTERM, sig_handler ); signal( SIGTERM, sig_handler );
signal( SIGINT, sig_handler );
} }
// runs initializations from runner // runs initializations from runner
@ -2690,7 +2750,9 @@ main1( int argc, char *argv[] )
lua_pushboolean( L, first_time ); lua_pushboolean( L, first_time );
if( lua_pcall( L, 1, 0, -3 ) ) if( lua_pcall( L, 1, 0, -3 ) )
{ exit( -1 ); } {
exit( -1 );
}
lua_pop( L, 1 ); lua_pop( L, 1 );
} }
@ -2754,7 +2816,17 @@ main( int argc, char * argv[ ] )
main1( argc, argv ); main1( argc, argv );
} }
// exits with 143 since it got a kill signal if( pidfile_fd > 0 )
return 143; {
close( pidfile_fd );
}
if( settings.pidfile )
{
remove( settings.pidfile );
}
// exits with error code responding to the signal it died for
return 128 + sigcode;
} }

View File

@ -3459,7 +3459,7 @@ end
-- * an expired alarm. -- * an expired alarm.
-- * a returned child process. -- * a returned child process.
-- * received filesystem events. -- * received filesystem events.
-- * received a HUP or TERM signal. -- * received a HUP, TERM or INT signal.
-- --
function runner.cycle( function runner.cycle(
timestamp -- the current kernel time (in jiffies) timestamp -- the current kernel time (in jiffies)
@ -4133,11 +4133,25 @@ end
-- --
-- Called by core on a term signal. -- Called by core on a term signal.
-- --
function runner.term( ) function runner.term( sigcode )
local sigtexts = {
[ 2 ] =
'INT',
[ 15 ] =
'TERM'
};
local sigtext = sigtexts[ sigcode ];
if not sigtext then
sigtext = 'UNKNOWN'
end
log( log(
'Normal', 'Normal',
'--- TERM signal, fading ---' '--- ', sigtext, ' signal, fading ---'
) )
lsyncdStatus = 'fade' lsyncdStatus = 'fade'