mirror of https://github.com/octoleo/lsyncd.git
This commit is contained in:
parent
40bf417cb4
commit
1c1c0ee542
|
@ -14,8 +14,10 @@ print(bla)
|
||||||
------
|
------
|
||||||
-- for testing purposes
|
-- for testing purposes
|
||||||
--
|
--
|
||||||
slower = "sleep 10 && "
|
slower = "sleep 1 && "
|
||||||
slowbash = {
|
slowbash = {
|
||||||
|
delay = 5,
|
||||||
|
|
||||||
startup = function(source, target)
|
startup = function(source, target)
|
||||||
log(NORMAL, "cp -r from "..source.." -> "..target)
|
log(NORMAL, "cp -r from "..source.." -> "..target)
|
||||||
return exec("/bin/bash", "-c", "cp -r \"$1\"* \"$2\"", "/bin/bash",
|
return exec("/bin/bash", "-c", "cp -r \"$1\"* \"$2\"", "/bin/bash",
|
||||||
|
|
61
lsyncd.c
61
lsyncd.c
|
@ -323,6 +323,37 @@ l_log(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns (on Lua stack) true if time1 is earler or eq to time2
|
||||||
|
* @param (on Lua Stack) time1
|
||||||
|
* @param (on Lua Stack) time2
|
||||||
|
* @return the true if time1 <= time2
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
l_before_eq(lua_State *L)
|
||||||
|
{
|
||||||
|
clock_t t1 = (clock_t) luaL_checkinteger(L, 1);
|
||||||
|
clock_t t2 = (clock_t) luaL_checkinteger(L, 2);
|
||||||
|
lua_pushboolean(L, time_before_eq(t1, t2));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns (on Lua stack) the earlier or two clock times.
|
||||||
|
*
|
||||||
|
* @param (on Lua Stack) time1
|
||||||
|
* @param (on Lua Stack) time2
|
||||||
|
* @return the earlier time
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
l_earlier(lua_State *L)
|
||||||
|
{
|
||||||
|
clock_t t1 = (clock_t) luaL_checkinteger(L, 1);
|
||||||
|
clock_t t2 = (clock_t) luaL_checkinteger(L, 2);
|
||||||
|
lua_pushinteger(L, time_before(t1, t2) ? t1 : t2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns (on Lua stack) the current kernels clock state (jiffies, times() call)
|
* Returns (on Lua stack) the current kernels clock state (jiffies, times() call)
|
||||||
*/
|
*/
|
||||||
|
@ -628,11 +659,13 @@ l_wait_pids(lua_State *L)
|
||||||
|
|
||||||
|
|
||||||
static const luaL_reg lsyncdlib[] = {
|
static const luaL_reg lsyncdlib[] = {
|
||||||
{"addup_clocks", l_addup_clocks },
|
|
||||||
{"add_watch", l_add_watch },
|
{"add_watch", l_add_watch },
|
||||||
|
{"addup_clocks", l_addup_clocks },
|
||||||
|
{"before_eq", l_before_eq },
|
||||||
|
{"earlier", l_earlier },
|
||||||
|
{"exec", l_exec },
|
||||||
{"log", l_log },
|
{"log", l_log },
|
||||||
{"now", l_now },
|
{"now", l_now },
|
||||||
{"exec", l_exec },
|
|
||||||
{"real_dir", l_real_dir },
|
{"real_dir", l_real_dir },
|
||||||
{"stackdump", l_stackdump },
|
{"stackdump", l_stackdump },
|
||||||
{"sub_dirs", l_sub_dirs },
|
{"sub_dirs", l_sub_dirs },
|
||||||
|
@ -793,6 +826,7 @@ void handle_event(lua_State *L, struct inotify_event *event) {
|
||||||
lua_pushnumber(L, event_type);
|
lua_pushnumber(L, event_type);
|
||||||
lua_pushnumber(L, event->wd);
|
lua_pushnumber(L, event->wd);
|
||||||
lua_pushboolean(L, (event->mask & IN_ISDIR) != 0);
|
lua_pushboolean(L, (event->mask & IN_ISDIR) != 0);
|
||||||
|
lua_pushinteger(L, times(NULL));
|
||||||
if (event_type == MOVE) {
|
if (event_type == MOVE) {
|
||||||
lua_pushstring(L, move_event_buf->name);
|
lua_pushstring(L, move_event_buf->name);
|
||||||
lua_pushstring(L, event->name);
|
lua_pushstring(L, event->name);
|
||||||
|
@ -800,7 +834,7 @@ void handle_event(lua_State *L, struct inotify_event *event) {
|
||||||
lua_pushstring(L, event->name);
|
lua_pushstring(L, event->name);
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
}
|
}
|
||||||
lua_call(L, 5, 0);
|
lua_call(L, 6, 0);
|
||||||
|
|
||||||
/* if there is a buffered event executes it */
|
/* if there is a buffered event executes it */
|
||||||
if (after_buf) {
|
if (after_buf) {
|
||||||
|
@ -817,7 +851,7 @@ masterloop(lua_State *L)
|
||||||
size_t readbuf_size = 2048;
|
size_t readbuf_size = 2048;
|
||||||
char *readbuf = s_malloc(readbuf_size);
|
char *readbuf = s_malloc(readbuf_size);
|
||||||
while(!reset) {
|
while(!reset) {
|
||||||
int alarm_state;
|
bool have_alarm;
|
||||||
clock_t now = times(NULL);
|
clock_t now = times(NULL);
|
||||||
clock_t alarm_time;
|
clock_t alarm_time;
|
||||||
bool do_read = false;
|
bool do_read = false;
|
||||||
|
@ -825,18 +859,17 @@ masterloop(lua_State *L)
|
||||||
|
|
||||||
/* query runner about soonest alarm */
|
/* query runner about soonest alarm */
|
||||||
lua_getglobal(L, "lsyncd_get_alarm");
|
lua_getglobal(L, "lsyncd_get_alarm");
|
||||||
lua_pushnumber(L, now);
|
lua_call(L, 0, 2);
|
||||||
lua_call(L, 1, 2);
|
have_alarm = lua_toboolean(L, -2);
|
||||||
alarm_state = luaL_checkinteger(L, -2);
|
alarm_time = (clock_t) luaL_checkinteger(L, -1);
|
||||||
alarm_time = (clock_t) luaL_checknumber(L, -1);
|
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
|
|
||||||
if (alarm_state < 0) {
|
if (have_alarm && time_before(alarm_time, now)) {
|
||||||
/* there is a delay that wants to be handled already
|
/* there is a delay that wants to be handled already
|
||||||
* thus do not read from inotify_fd and jump directly to its handling */
|
* thus do not read from inotify_fd and jump directly to its handling */
|
||||||
logstring(DEBUG, "immediately handling delayed entries.");
|
logstring(DEBUG, "immediately handling delayed entries.");
|
||||||
do_read = 0;
|
do_read = 0;
|
||||||
} else if (alarm_state > 0) {
|
} else if (have_alarm) {
|
||||||
/* use select() to determine what happens next
|
/* use select() to determine what happens next
|
||||||
* + a new event on inotify
|
* + a new event on inotify
|
||||||
* + an alarm on timeout
|
* + an alarm on timeout
|
||||||
|
@ -844,7 +877,7 @@ masterloop(lua_State *L)
|
||||||
fd_set readfds;
|
fd_set readfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
if (time_after(now, alarm_time)) {
|
if (time_before(alarm_time, now)) {
|
||||||
/* should never happen */
|
/* should never happen */
|
||||||
logstring(ERROR, "critical failure, alarm_time is in past!\n");
|
logstring(ERROR, "critical failure, alarm_time is in past!\n");
|
||||||
exit(-1); //ERRNO
|
exit(-1); //ERRNO
|
||||||
|
@ -852,8 +885,8 @@ masterloop(lua_State *L)
|
||||||
|
|
||||||
tv.tv_sec = (alarm_time - now) / clocks_per_sec;
|
tv.tv_sec = (alarm_time - now) / clocks_per_sec;
|
||||||
tv.tv_usec = (alarm_time - now) * 1000000 / clocks_per_sec % 1000000;
|
tv.tv_usec = (alarm_time - now) * 1000000 / clocks_per_sec % 1000000;
|
||||||
/* if select returns a positive number there is data on inotify *
|
/* if select returns a positive number there is data on inotify
|
||||||
* on zero the timemout occured. */
|
* on zero the timemout occured. */
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_SET(inotify_fd, &readfds);
|
FD_SET(inotify_fd, &readfds);
|
||||||
do_read = select(inotify_fd + 1, &readfds, NULL, NULL, &tv);
|
do_read = select(inotify_fd + 1, &readfds, NULL, NULL, &tv);
|
||||||
|
@ -864,7 +897,7 @@ masterloop(lua_State *L)
|
||||||
logstring(DEBUG, "core: select() timeout or signal.");
|
logstring(DEBUG, "core: select() timeout or signal.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if nothing to wait for, enter a blocking read
|
/* if nothing to wait for, enter a blocking read */
|
||||||
logstring(DEBUG, "gone blocking.");
|
logstring(DEBUG, "gone blocking.");
|
||||||
do_read = 1;
|
do_read = 1;
|
||||||
}
|
}
|
||||||
|
|
48
lsyncd.lua
48
lsyncd.lua
|
@ -40,6 +40,7 @@ exec = lsyncd.exec
|
||||||
-- .processes = [pid] .. a sublist of processes[] for this target
|
-- .processes = [pid] .. a sublist of processes[] for this target
|
||||||
-- .delays = [#) { .. the delays stack
|
-- .delays = [#) { .. the delays stack
|
||||||
-- .atype .. enum, kind of action
|
-- .atype .. enum, kind of action
|
||||||
|
-- .alarm .. when it should fire
|
||||||
-- .wd .. watch descriptor id this origins from TODO needed?
|
-- .wd .. watch descriptor id this origins from TODO needed?
|
||||||
-- .sync .. link to sync that raised this delay.
|
-- .sync .. link to sync that raised this delay.
|
||||||
-- .filename .. filename or nil (=dir itself)
|
-- .filename .. filename or nil (=dir itself)
|
||||||
|
@ -114,7 +115,9 @@ local function delay_action(atype, wd, sync, filename, time)
|
||||||
sync = sync,
|
sync = sync,
|
||||||
filename = filename }
|
filename = filename }
|
||||||
if time ~= nil and origin.actions.delay ~= nil then
|
if time ~= nil and origin.actions.delay ~= nil then
|
||||||
nd.alarm = lsyncd.append_time(time, origin.actions.delay)
|
nd.alarm = lsyncd.addup_clocks(time, origin.actions.delay)
|
||||||
|
else
|
||||||
|
nd.alarm = lsyncd.now()
|
||||||
end
|
end
|
||||||
table.insert(delays, nd)
|
table.insert(delays, nd)
|
||||||
end
|
end
|
||||||
|
@ -169,7 +172,7 @@ function lsyncd_collect_process(pid, exitcode)
|
||||||
end
|
end
|
||||||
local sync = process.sync
|
local sync = process.sync
|
||||||
local origin = sync.origin
|
local origin = sync.origin
|
||||||
print("collected ", pid, ": ", vent_names[atpye], origin.source, "/", sync.path , process.filename, " = ", exitcode)
|
print("collected ", pid, ": ", event_names[atpye], origin.source, "/", sync.path , process.filename, " = ", exitcode)
|
||||||
processes[pid] = nil
|
processes[pid] = nil
|
||||||
origin.processes[pid] = nil
|
origin.processes[pid] = nil
|
||||||
end
|
end
|
||||||
|
@ -226,19 +229,12 @@ local function invoke_action(delay)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- .delays = [#) { .. the delays stack
|
|
||||||
-- .atype .. enum, kind of action
|
|
||||||
-- .wd .. watch descriptor id this origins from TODO needed?
|
|
||||||
-- .attend .. link to atttender that raised this delay.
|
|
||||||
-- .filename .. filename or nil (=dir itself)
|
|
||||||
-- (.movepeer) .. for MOVEFROM/MOVETO link to other delay
|
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
-- Called from core everytime at the latest of an
|
-- Called from core everytime at the latest of an
|
||||||
-- expired alarm (or more often)
|
-- expired alarm (or more often)
|
||||||
--
|
--
|
||||||
-- @param now the time is now
|
-- @param now the time now
|
||||||
--
|
--
|
||||||
function lsyncd_alarm(now)
|
function lsyncd_alarm(now)
|
||||||
-- goes through all targets and spawns more actions
|
-- goes through all targets and spawns more actions
|
||||||
|
@ -246,7 +242,7 @@ function lsyncd_alarm(now)
|
||||||
for i, o in ipairs(origins) do
|
for i, o in ipairs(origins) do
|
||||||
if #o.processes < o.actions.max_processes then
|
if #o.processes < o.actions.max_processes then
|
||||||
local delays = o.delays
|
local delays = o.delays
|
||||||
if delays[1] ~= nil then
|
if delays[1] ~= nil and lsyncd.before_eq(delays[1].alarm, now) then
|
||||||
invoke_action(o.delays[1])
|
invoke_action(o.delays[1])
|
||||||
table.remove(delays, 1)
|
table.remove(delays, 1)
|
||||||
end
|
end
|
||||||
|
@ -310,12 +306,30 @@ end
|
||||||
-- Called by core to query soonest alarm.
|
-- Called by core to query soonest alarm.
|
||||||
--
|
--
|
||||||
-- @return two variables.
|
-- @return two variables.
|
||||||
-- number -1 means ... alarm is in the past.
|
-- boolean false ... no alarm, core can in untimed sleep
|
||||||
-- 0 means ... no alarm, core can in untimed sleep
|
-- true ... alarm time specified.
|
||||||
-- 1 means ... alarm time specified.
|
|
||||||
-- times ... the alarm time (only read if number is 1)
|
-- times ... the alarm time (only read if number is 1)
|
||||||
function lsyncd_get_alarm()
|
function lsyncd_get_alarm()
|
||||||
return 0, 0
|
local have_alarm = false
|
||||||
|
local alarm = 0
|
||||||
|
for i, o in ipairs(origins) do
|
||||||
|
if o.delays[1] ~= nil then
|
||||||
|
if have_alarm then
|
||||||
|
alarm = lsyncd.earlier(alarm, o.delays[1].alarm)
|
||||||
|
else
|
||||||
|
alarm = o.delays[1].alarm
|
||||||
|
have_alarm = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local hs
|
||||||
|
if have_alarm then
|
||||||
|
hs = "true"
|
||||||
|
else
|
||||||
|
hs = "false"
|
||||||
|
end
|
||||||
|
log(DEBUG, "lsyncd_get_alarm ("..hs..","..alarm..")")
|
||||||
|
return have_alarm, alarm
|
||||||
end
|
end
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
@ -323,10 +337,11 @@ end
|
||||||
--
|
--
|
||||||
-- @param etype enum (ATTRIB, MODIFY, CREATE, DELETE, MOVE)
|
-- @param etype enum (ATTRIB, MODIFY, CREATE, DELETE, MOVE)
|
||||||
-- @param wd watch descriptor (matches lsyncd.add_watch())
|
-- @param wd watch descriptor (matches lsyncd.add_watch())
|
||||||
|
-- @param time time of event
|
||||||
-- @param filename string filename without path
|
-- @param filename string filename without path
|
||||||
-- @param filename2
|
-- @param filename2
|
||||||
--
|
--
|
||||||
function lsyncd_event(etype, wd, isdir, filename, filename2)
|
function lsyncd_event(etype, wd, isdir, time, filename, filename2)
|
||||||
local ftype;
|
local ftype;
|
||||||
if isdir then
|
if isdir then
|
||||||
ftype = "directory"
|
ftype = "directory"
|
||||||
|
@ -349,7 +364,6 @@ function lsyncd_event(etype, wd, isdir, filename, filename2)
|
||||||
|
|
||||||
-- works through all possible source->target pairs
|
-- works through all possible source->target pairs
|
||||||
for i, sync in ipairs(w.syncs) do
|
for i, sync in ipairs(w.syncs) do
|
||||||
time = nil -- TODO
|
|
||||||
delay_action(etype, wd, sync, filename, time)
|
delay_action(etype, wd, sync, filename, time)
|
||||||
-- add subdirs for new directories
|
-- add subdirs for new directories
|
||||||
if isdir then
|
if isdir then
|
||||||
|
|
Loading…
Reference in New Issue