reworking signal system

This commit is contained in:
Axel Kittenberger 2018-05-12 15:08:14 +02:00
parent a9e609d60c
commit 693a07e529
7 changed files with 140 additions and 67 deletions

View File

@ -91,6 +91,7 @@ add_custom_command( OUTPUT signames.lua
#
set( DEFAULT_CODE
${PROJECT_SOURCE_DIR}/default/default.lua
${PROJECT_SOURCE_DIR}/default/signal.lua
${PROJECT_SOURCE_DIR}/default/rsync.lua
${PROJECT_SOURCE_DIR}/default/rsyncssh.lua
${PROJECT_SOURCE_DIR}/default/direct.lua

View File

@ -773,8 +773,10 @@ mci_load_default(
// loads the default sync implementations
if( luaL_loadbuffer( L, default_out, default_size, "default" ) )
{
printlogf( L, "Error",
"loading default sync implementations: %s", lua_tostring( L, -1 ) );
printlogf(
L, "Error",
"loading default sync implementations: %s", lua_tostring( L, -1 )
);
exit( -1 );
}
@ -787,8 +789,10 @@ mci_load_default(
// prepares the default sync implementations
if( lua_pcall( L, 0, 0, 0 ) )
{
printlogf( L, "Error",
"preparing default sync implementations: %s", lua_tostring( L, -1 ) );
printlogf(
L, "Error",
"preparing default sync implementations: %s", lua_tostring( L, -1 )
);
exit( -1 );
}

View File

@ -60,16 +60,14 @@ volatile sig_atomic_t sigcode = 0;
/*
| signal handler
*/
/*
static void
signal_child( int sig )
{
// Nothing!
//
// This signal handler is just installed so the kernel
// keeps finished child processes as zombies waiting to be reaped.
// keeps finished sub-processes as zombies waiting to be reaped.
}
*/
/*
@ -132,6 +130,7 @@ l_onsignal(
int ok;
int h;
struct sigaction act;
bool have_sig_child = false;
// the block mask includes all signals that have registered handlers.
// it is used to block all signals outside the select() call
@ -158,7 +157,8 @@ l_onsignal(
int signum = lua_tointegerx( L, -1 , &ok );
if( !ok ) continue;
// unsets this signal from the handlers buffer
// marks this signal to be used again in the
// new signal handler table.
for( h = 0; h < handlers_len; h++ )
{
if( handlers[ h ] == signum )
@ -170,7 +170,8 @@ l_onsignal(
sigc++;
}
// resets no longer handlerd signals to default action
// resets no longer handled signals
// to their system default action
for( h = 0; h < handlers_len; h++ )
{
int signum = handlers[ h ];
@ -224,15 +225,23 @@ l_onsignal(
int signum = lua_tointegerx( L, -1 , &ok );
if( !ok ) continue;
if( signum == SIGCHLD ) have_sig_child = true;
// stores registered signal handlers
handlers[ handlers_len++ ] = signum;
sigaction( signum, &act, 0 );
}
// FIXME listen to SIGCHLD if not specified
// Listens to SIGCHLD, but blocks it until pselect( )
// opens the signal handler up.
// If there is no custom SIGCHLD handler add one
// that will do nothing. This is needed by the OS
// so the Lsyncd subprocesses are zombified and
// can be reaped.
if( !have_sig_child )
{
act.sa_handler = &signal_child;
sigaction( SIGCHLD, &act, 0 );
}
return 0;
}

62
default/signal.lua Normal file
View File

@ -0,0 +1,62 @@
--
-- signal.lua from Lsyncd -- the Live (Mirror) Syncing Demon
--
--
-- The default signal handles for HUP, INT and TERM.
--
--
-- License: GPLv2 (see COPYING) or any later version
-- Authors: Axel Kittenberger <axkibe@gmail.com>
--
if not default then error( 'default not loaded' ) end
default.signal = { }
local function sighup
( )
print( 'GOT A HUP SIGNAL' )
os.exit( 1 )
end
local function sigint
( )
print( 'GOT AN INT SIGNAL' )
os.exit( 1 )
end
local function sigterm
( )
print( 'GOT A TERM SIGNAL' )
os.exit( 1 )
end
--
-- Sets up the default HUP/INT/TERM signal handlers.
--
-- Called after user scripts finished
--
init =
function
( )
local hup = getsignal( 'HUP' )
local int = getsignal( 'INT' )
local term = getsignal( 'TERM' )
if hup ~= false then hup = sighup end
if int ~= false then int = sigint end
if term ~= false then term = sigterm end
onsignal(
'HUP', hup,
'INT', int,
'TERM', iterm
)
end

View File

@ -386,7 +386,7 @@ function mci.initialize
os.exit( -1 )
end
initSignalHandlers( firstTime )
if userENV.init then userENV.init( ) end
lastReportedWaiting = false
@ -496,7 +496,7 @@ end
--
function mci.getAlarm
( )
log( 'Function', 'getAlarm( )' )
log( 'Function', 'getAlarm( )', lsyncdStatus )
if lsyncdStatus ~= 'run' then return false end
@ -537,10 +537,7 @@ function mci.getAlarm
checkAlarm( s:getAlarm( ) )
end
else
log(
'Alarm',
'at global process limit.'
)
log( 'Alarm', 'at global process limit.' )
end
-- checks if a statusfile write has been delayed

View File

@ -38,90 +38,88 @@ local sigHandlerCount = 0
--
-- Prepares an onsignal handle.
-- It changes the mantle data, but does not yet tell the core about it.
-- transforms a signal name or number to
-- a valid number. 'false' is left be 'false'
--
-- To be used only internally to combine multiple changes into one.
-- In case of a invalid signal specifie an error is raised.
--
local function onsignalPrep
local function toSignum
(
signal, -- signal number or name
handler -- function to call
-- -- or nil to unload the handle
-- -- or false to disable default signal handlers
signal
)
local signum
if type( signal ) == 'number'
then
if signal < 0
or signal ~= signal
or signal - floor( signal ) ~= 0
then
error( 'signal ' .. signal .. ' is an invalid number.' , 2 )
error( 'signal ' .. signal .. ' is an invalid number.' , 3 )
end
signum = signal
return signal
elseif type( signal ) == 'string'
then
signum = signums[ signal ]
if signum == nil
then
error( 'signal "' .. signal .. '" unknown.' , 2 )
error( 'signal "' .. signal .. '" unknown.' , 3 )
end
else
error( 'signal of type ' .. type( signal ) .. ' invalid.', 2 )
end
sigHandlers[ signum ] = handler
return signum
elseif signal == false
then
return false
else
error( 'signal of type ' .. type( signal ) .. ' invalid.', 3 )
end
end
--
-- The onsignal( ) function exported to userEnv.
--
function onsignal
(
signal, -- signal number or name
handler -- function to call
-- -- or nil to unload the handle
-- -- or false to disable default signal handlers
...
--- signal1, -- signal number or name
--- handler1 -- function to call
-- -- or nil to unload the handle
-- -- or false to disable default signal handlers
-- signal2, handler2
-- signal3, handler3
-- and so on
)
onsignalPrep( signal, handler )
local n = select( '#', ... )
local arg = {...}
if n % 2 ~= 0
then
error( 'onsignal with uneven number of arguments called', 2 )
end
for a = 1, n, 2
do
local signal = arg[ a ]
local handler = arg[ a + 1 ]
local signum = toSignum( signal )
sigHandlers[ signum ] = handler
end
core.onsignal( sigHandlers )
end
--
-- Sets up the default HUP/INT/TERM signal handlers.
-- Returns signal handler registered for 'signum'
--
-- Called after user scripts finished
--
function initSignalHandlers
function getsignal
(
firstTime --- TODO check if needed
signum
)
onsignalPrep(
'HUP',
function( )
print( 'GOT A HUP SIGNAL' )
end
)
onsignalPrep(
'INT',
function( )
print( 'GOT A INT SIGNAL' )
end
)
onsignalPrep(
'TERM',
function( )
print( 'GOT A TERM SIGNAL' )
end
)
core.onsignal( sigHandlers )
return sigHandlers[ signum ];
end

View File

@ -21,6 +21,7 @@ userENV =
dofile = dofile,
error = error,
getmetatable = getmetable,
getsignal = getsignal,
io = io,
ipairs = ipairs,
load = load,
@ -29,6 +30,7 @@ userENV =
math = math,
module = module,
next = next,
onsignal = onsignal,
os = os,
package = package,
pairs = pairs,