mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-12-04 19:03:17 +00:00
fixing creation recursing
This commit is contained in:
parent
6faf99d952
commit
5e4fdba53a
81
inotify.c
81
inotify.c
@ -77,22 +77,20 @@ l_addwatch(lua_State *L)
|
||||
uint32_t mask = standard_event_mask;
|
||||
if (*imode) {
|
||||
if (!strcmp(imode, "Modify")) {
|
||||
/* act on modify instead of closeWrite */
|
||||
// act on modify instead of closeWrite
|
||||
mask |= IN_MODIFY;
|
||||
mask &= ~IN_CLOSE_WRITE;
|
||||
} else if (!strcmp(imode, "CloseWrite")) {
|
||||
/* default */
|
||||
// default
|
||||
} else if (!strcmp(imode, "CloseWrite or Modify")) {
|
||||
/* acts on modify and closeWrite */
|
||||
// acts on modify and closeWrite
|
||||
mask |= IN_MODIFY;
|
||||
} else if (!strcmp(imode, "CloseWrite after Modify")) {
|
||||
/* might be done in future */
|
||||
printlogf(L, "Error",
|
||||
"'CloseWrite after Modify' not implemented.");
|
||||
// might be done in future
|
||||
printlogf(L, "Error", "'CloseWrite after Modify' not implemented.");
|
||||
exit(-1); // ERRNO
|
||||
} else {
|
||||
printlogf(L, "Error",
|
||||
"'%s' not a valid inotfiyMode.", imode);
|
||||
printlogf(L, "Error", "'%s' not a valid inotfiyMode.", imode);
|
||||
exit(-1); // ERRNO
|
||||
}
|
||||
}
|
||||
@ -101,14 +99,11 @@ l_addwatch(lua_State *L)
|
||||
int wd = inotify_add_watch(inotify_fd, path, mask);
|
||||
if (wd < 0) {
|
||||
if (errno == ENOSPC) {
|
||||
printlogf(L, "Error",
|
||||
"Terminating since out of inotify watches.");
|
||||
printlogf(L, "Error",
|
||||
"Consider increasing /proc/sys/fs/inotify/max_user_watches");
|
||||
printlogf(L, "Error", "Terminating since out of inotify watches.");
|
||||
printlogf(L, "Error", "Consider increasing /proc/sys/fs/inotify/max_user_watches");
|
||||
exit(-1); // ERRNO.
|
||||
}
|
||||
printlogf(L, "Inotify", "addwatch(%s)->%d; err=%d:%s", path, wd,
|
||||
errno, strerror(errno));
|
||||
printlogf(L, "Inotify", "addwatch(%s)->%d; err=%d:%s", path, wd, errno, strerror(errno));
|
||||
} else {
|
||||
printlogf(L, "Inotify", "addwatch(%s)->%d", path, wd);
|
||||
}
|
||||
@ -168,7 +163,7 @@ handle_event(lua_State *L,
|
||||
{
|
||||
const char *event_type = NULL;
|
||||
|
||||
/* used to execute two events in case of unmatched MOVE_FROM buffer */
|
||||
// used to execute two events in case of unmatched MOVE_FROM buffer
|
||||
struct inotify_event *after_buf = NULL;
|
||||
if (event && (IN_Q_OVERFLOW & event->mask)) {
|
||||
/* and overflow happened, tells the runner */
|
||||
@ -180,27 +175,27 @@ handle_event(lua_State *L,
|
||||
hup = 1;
|
||||
return;
|
||||
}
|
||||
/* cancel on ignored or resetting */
|
||||
// cancel on ignored or resetting
|
||||
if (event && (IN_IGNORED & event->mask)) {
|
||||
return;
|
||||
}
|
||||
if (event && event->len == 0) {
|
||||
/* sometimes inotify sends such strange events,
|
||||
* (e.g. when touching a dir */
|
||||
// sometimes inotify sends such strange events,
|
||||
// (e.g. when touching a dir
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == NULL) {
|
||||
/* a buffered MOVE_FROM is not followed by anything,
|
||||
thus it is unary */
|
||||
// a buffered MOVE_FROM is not followed by anything,
|
||||
// thus it is unary
|
||||
event = move_event_buf;
|
||||
event_type = "Delete";
|
||||
move_event = false;
|
||||
} else if (move_event &&
|
||||
( !(IN_MOVED_TO & event->mask) ||
|
||||
event->cookie != move_event_buf->cookie) ) {
|
||||
/* there is a MOVE_FROM event in the buffer and this is not the match
|
||||
* continue in this function iteration to handle the buffer instead */
|
||||
// there is a MOVE_FROM event in the buffer and this is not the match
|
||||
// continue in this function iteration to handle the buffer instead */
|
||||
logstring("Inotify", "icore, changing unary MOVE_FROM into DELETE")
|
||||
after_buf = event;
|
||||
event = move_event_buf;
|
||||
@ -209,13 +204,13 @@ handle_event(lua_State *L,
|
||||
} else if ( move_event &&
|
||||
(IN_MOVED_TO & event->mask) &&
|
||||
event->cookie == move_event_buf->cookie ) {
|
||||
/* this is indeed a matched move */
|
||||
// this is indeed a matched move */
|
||||
event_type = "Move";
|
||||
move_event = false;
|
||||
} else if (IN_MOVED_FROM & event->mask) {
|
||||
/* just the MOVE_FROM, buffers this event, and wait if next event is
|
||||
* a matching MOVED_TO of this was an unary move out of the watched
|
||||
* tree. */
|
||||
// just the MOVE_FROM, buffers this event, and wait if next event is
|
||||
// a matching MOVED_TO of this was an unary move out of the watched
|
||||
// tree.
|
||||
size_t el = sizeof(struct inotify_event) + event->len;
|
||||
if (move_event_buf_size < el) {
|
||||
move_event_buf_size = el;
|
||||
@ -225,26 +220,26 @@ handle_event(lua_State *L,
|
||||
move_event = true;
|
||||
return;
|
||||
} else if (IN_MOVED_TO & event->mask) {
|
||||
/* must be an unary move-to */
|
||||
// must be an unary move-to
|
||||
event_type = CREATE;
|
||||
} else if (IN_ATTRIB & event->mask) {
|
||||
/* just attrib change */
|
||||
// just attrib change
|
||||
event_type = ATTRIB;
|
||||
} else if (IN_CLOSE_WRITE & event->mask) {
|
||||
/* closed after written something */
|
||||
// closed after written something
|
||||
event_type = MODIFY;
|
||||
} else if (IN_CREATE & event->mask) {
|
||||
/* a new file */
|
||||
// a new file
|
||||
event_type = CREATE;
|
||||
} else if (IN_DELETE & event->mask) {
|
||||
/* rm'ed */
|
||||
// rm'ed
|
||||
event_type = DELETE;
|
||||
} else {
|
||||
logstring("Inotify", "icore, skipped some inotify event.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* and hands over to runner */
|
||||
// and hands over to runner
|
||||
load_runner_func(L, "inotifyEvent");
|
||||
if (!event_type) {
|
||||
logstring("Error", "Internal: unknown event in handle_event()");
|
||||
@ -272,7 +267,7 @@ handle_event(lua_State *L,
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
/* if there is a buffered event executes it */
|
||||
// if there is a buffered event, executes it
|
||||
if (after_buf) {
|
||||
logstring("Inotify", "icore, handling buffered event.");
|
||||
handle_event(L, after_buf);
|
||||
@ -304,23 +299,23 @@ inotify_ready(lua_State *L, struct observance *obs)
|
||||
len = read (inotify_fd, readbuf, readbuf_size);
|
||||
err = errno;
|
||||
if (len < 0 && err == EINVAL) {
|
||||
/* kernel > 2.6.21 indicates that way that way that
|
||||
* the buffer was too small to fit a filename.
|
||||
* double its size and try again. When using a lower
|
||||
* kernel and a filename > 2KB appears lsyncd
|
||||
* will fail. (but does a 2KB filename really happen?)
|
||||
*/
|
||||
// kernel > 2.6.21 indicates that way that way that
|
||||
// the buffer was too small to fit a filename.
|
||||
// double its size and try again. When using a lower
|
||||
// kernel and a filename > 2KB appears lsyncd
|
||||
// will fail. (but does a 2KB filename really happen?)
|
||||
//
|
||||
readbuf_size *= 2;
|
||||
readbuf = s_realloc(readbuf, readbuf_size);
|
||||
}
|
||||
} while(len < 0 && err == EINVAL);
|
||||
if (len == 0) {
|
||||
/* nothing more inotify */
|
||||
// nothing more inotify
|
||||
break;
|
||||
}
|
||||
if (len < 0) {
|
||||
if (err == EAGAIN) {
|
||||
/* nothing more inotify */
|
||||
// nothing more inotify
|
||||
break;
|
||||
} else {
|
||||
printlogf(L, "Error", "Read fail on inotify");
|
||||
@ -337,12 +332,12 @@ inotify_ready(lua_State *L, struct observance *obs)
|
||||
}
|
||||
}
|
||||
if (!move_event) {
|
||||
/* give it a pause if not endangering splitting a move */
|
||||
// give it a pause if not endangering splitting a move
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* checks if there is an unary MOVE_FROM left in the buffer */
|
||||
// checks if there is an unary MOVE_FROM left in the buffer
|
||||
if (move_event) {
|
||||
logstring("Inotify", "icore, handling unary move from.");
|
||||
handle_event(L, NULL);
|
||||
|
30
lsyncd.lua
30
lsyncd.lua
@ -1245,7 +1245,7 @@ local Sync = (function()
|
||||
--
|
||||
local function delay(self, etype, time, path, path2)
|
||||
log('Function', 'delay(',self.config.name,', ',etype,', ',path,', ',path2,')')
|
||||
|
||||
|
||||
-- TODO
|
||||
local function recurse()
|
||||
if etype == 'Create' and path:byte(-1) == 47 then
|
||||
@ -1828,12 +1828,9 @@ local Inotify = (function()
|
||||
--
|
||||
-- @param path absolute path of directory to observe
|
||||
-- @param recurse true if recursing into subdirs
|
||||
-- @param raiseSync --X --
|
||||
-- raiseTime if not nil sends create Events for all files/dirs
|
||||
-- to this sync.
|
||||
--
|
||||
local function addWatch(path, recurse, raiseSync, raiseTime)
|
||||
log('Function','Inotify.addWatch(',path,', ',recurse,', ',raiseSync,', ',raiseTime,')')
|
||||
local function addWatch(path)
|
||||
log('Function','Inotify.addWatch(',path,')')
|
||||
|
||||
if not Syncs.concerns(path) then
|
||||
log('Inotify', 'not concerning "',path,'"')
|
||||
@ -1862,9 +1859,6 @@ local Inotify = (function()
|
||||
|
||||
-- registers and adds watches for all subdirectories
|
||||
-- and/or raises create events for all entries
|
||||
if not recurse and not raise then
|
||||
return
|
||||
end
|
||||
|
||||
local entries = lsyncd.readdir(path)
|
||||
if not entries then return end
|
||||
@ -1872,15 +1866,8 @@ local Inotify = (function()
|
||||
for dirname, isdir in pairs(entries) do
|
||||
local pd = path .. dirname
|
||||
if isdir then pd = pd..'/' end
|
||||
|
||||
-- creates a Create event for entry.
|
||||
-- No longer needed? (TODO)
|
||||
-- if raiseSync then
|
||||
-- local relative = splitPath(pd, syncRoots[raiseSync])
|
||||
-- if relative then raiseSync:delay('Create', raiseTime, relative) end
|
||||
-- end
|
||||
-- adds syncs for subdirs
|
||||
if isdir then addWatch(pd, true, raiseSync, raiseTime) end
|
||||
if isdir then addWatch(pd) end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1895,7 +1882,7 @@ local Inotify = (function()
|
||||
error('duplicate sync in Inotify.addSync()')
|
||||
end
|
||||
syncRoots[sync] = rootdir
|
||||
addWatch(rootdir, true)
|
||||
addWatch(rootdir)
|
||||
end
|
||||
|
||||
-----
|
||||
@ -1965,18 +1952,19 @@ local Inotify = (function()
|
||||
etyped = 'Create'
|
||||
end
|
||||
end
|
||||
sync:delay(etyped, time, relative, relative2)
|
||||
|
||||
if isdir then
|
||||
if etyped == 'Create' then
|
||||
addWatch(path, true, sync, time)
|
||||
addWatch(path)
|
||||
elseif etyped == 'Delete' then
|
||||
removeWatch(path, true)
|
||||
elseif etyped == 'Move' then
|
||||
removeWatch(path, false)
|
||||
addWatch(path2, true, sync, time)
|
||||
addWatch(path2)
|
||||
end
|
||||
end
|
||||
|
||||
sync:delay(etyped, time, relative, relative2)
|
||||
until true end
|
||||
end
|
||||
|
||||
|
@ -1,115 +1,115 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
require("posix")
|
||||
dofile("tests/testlib.lua")
|
||||
require('posix')
|
||||
dofile('tests/testlib.lua')
|
||||
|
||||
cwriteln("****************************************************************");
|
||||
cwriteln(" Testing excludes ");
|
||||
cwriteln("****************************************************************");
|
||||
cwriteln(" (this test needs passwordless ssh localhost access ");
|
||||
cwriteln(" for current user)");
|
||||
cwriteln('****************************************************************');
|
||||
cwriteln(' Testing excludes');
|
||||
cwriteln('****************************************************************');
|
||||
cwriteln(' (this test needs passwordless ssh localhost access ');
|
||||
cwriteln(' for current user)');
|
||||
|
||||
local tdir, srcdir, trgdir = mktemps()
|
||||
local logfile = tdir .. "log"
|
||||
local cfgfile = tdir .. "config.lua"
|
||||
local logfile = tdir .. 'log'
|
||||
local cfgfile = tdir .. 'config.lua'
|
||||
local range = 5
|
||||
local log = {}
|
||||
log = {"-log", "all"}
|
||||
log = {'-log', 'all'}
|
||||
|
||||
writefile(cfgfile, [[
|
||||
settings = {
|
||||
logfile = "]]..logfile..[[",
|
||||
logfile = ']]..logfile..[[',
|
||||
nodaemon = true,
|
||||
delay = 3,
|
||||
}
|
||||
|
||||
sync {
|
||||
default.rsyncssh,
|
||||
host = "localhost",
|
||||
source = "]]..srcdir..[[",
|
||||
targetdir = "]]..trgdir..[[",
|
||||
host = 'localhost',
|
||||
source = ']]..srcdir..[[',
|
||||
targetdir = ']]..trgdir..[[',
|
||||
exclude = {
|
||||
"erf",
|
||||
"/eaf",
|
||||
"erd/",
|
||||
"/ead/",
|
||||
'erf',
|
||||
'/eaf',
|
||||
'erd/',
|
||||
'/ead/',
|
||||
},
|
||||
}]]);
|
||||
|
||||
-- writes all files
|
||||
local function writefiles()
|
||||
posix.mkdir(srcdir .. "d");
|
||||
writefile(srcdir .. "erf", "erf");
|
||||
writefile(srcdir .. "eaf", "erf");
|
||||
writefile(srcdir .. "erd", "erd");
|
||||
writefile(srcdir .. "ead", "ead");
|
||||
writefile(srcdir .. "d/erf", "erf");
|
||||
writefile(srcdir .. "d/eaf", "erf");
|
||||
writefile(srcdir .. "d/erd", "erd");
|
||||
writefile(srcdir .. "d/ead", "ead");
|
||||
local function writefiles()
|
||||
posix.mkdir(srcdir .. 'd');
|
||||
writefile(srcdir .. 'erf', 'erf');
|
||||
writefile(srcdir .. 'eaf', 'erf');
|
||||
writefile(srcdir .. 'erd', 'erd');
|
||||
writefile(srcdir .. 'ead', 'ead');
|
||||
writefile(srcdir .. 'd/erf', 'erf');
|
||||
writefile(srcdir .. 'd/eaf', 'erf');
|
||||
writefile(srcdir .. 'd/erd', 'erd');
|
||||
writefile(srcdir .. 'd/ead', 'ead');
|
||||
end
|
||||
|
||||
-- test if the filename exists, fails if this is different to expect
|
||||
local function testfile(filename, expect)
|
||||
local function testfile(filename, expect)
|
||||
local stat, err = posix.stat(filename)
|
||||
if stat and not expect then
|
||||
cwriteln("failure: ",filename," should be excluded");
|
||||
cwriteln('failure: ',filename,' should be excluded');
|
||||
os.exit(1);
|
||||
end
|
||||
if not stat and expect then
|
||||
cwriteln("failure: ",filename," should not be excluded");
|
||||
cwriteln('failure: ',filename,' should not be excluded');
|
||||
os.exit(1);
|
||||
end
|
||||
end
|
||||
|
||||
-- test all files
|
||||
local function testfiles()
|
||||
testfile(trgdir .. "erf", false);
|
||||
testfile(trgdir .. "eaf", false);
|
||||
testfile(trgdir .. "erd", true);
|
||||
testfile(trgdir .. "ead", true);
|
||||
testfile(trgdir .. "d/erf", false);
|
||||
testfile(trgdir .. "d/eaf", true);
|
||||
testfile(trgdir .. "d/erd", true);
|
||||
testfile(trgdir .. "d/ead", true);
|
||||
local function testfiles()
|
||||
testfile(trgdir .. 'erf', false);
|
||||
testfile(trgdir .. 'eaf', false);
|
||||
testfile(trgdir .. 'erd', true);
|
||||
testfile(trgdir .. 'ead', true);
|
||||
testfile(trgdir .. 'd/erf', false);
|
||||
testfile(trgdir .. 'd/eaf', true);
|
||||
testfile(trgdir .. 'd/erd', true);
|
||||
testfile(trgdir .. 'd/ead', true);
|
||||
end
|
||||
|
||||
|
||||
cwriteln("testing startup excludes");
|
||||
cwriteln('testing startup excludes');
|
||||
writefiles();
|
||||
cwriteln("starting Lsyncd");
|
||||
local pid = spawn("./lsyncd", cfgfile, unpack(log));
|
||||
cwriteln("waiting for Lsyncd to start");
|
||||
posix.sleep(3)
|
||||
cwriteln("testing excludes after startup");
|
||||
cwriteln('starting Lsyncd');
|
||||
local pid = spawn('./lsyncd', cfgfile, unpack(log));
|
||||
cwriteln('waiting for Lsyncd to start');
|
||||
posix.sleep(10)
|
||||
cwriteln('testing excludes after startup');
|
||||
testfiles();
|
||||
cwriteln("ok, removing sources");
|
||||
if srcdir:sub(1,4) ~= "/tmp" then
|
||||
cwriteln('ok, removing sources');
|
||||
if srcdir:sub(1,4) ~= '/tmp' then
|
||||
-- just to make sure before rm -rf
|
||||
cwriteln("exist before drama, srcdir is '", srcdir, "'");
|
||||
cwriteln('exist before drama, srcdir is "', srcdir, '"');
|
||||
os.exit(1);
|
||||
end
|
||||
os.execute("rm -rf "..srcdir.."/*");
|
||||
cwriteln("waiting for Lsyncd to remove destination");
|
||||
os.execute('rm -rf '..srcdir..'/*');
|
||||
cwriteln('waiting for Lsyncd to remove destination');
|
||||
posix.sleep(5);
|
||||
if os.execute("diff -urN "..srcdir.." "..trgdir) ~= 0 then
|
||||
cwriteln("fail, target directory not empty!");
|
||||
if os.execute('diff -urN '..srcdir..' '..trgdir) ~= 0 then
|
||||
cwriteln('fail, target directory not empty!');
|
||||
os.exit(1);
|
||||
end
|
||||
|
||||
cwriteln("writing files after startup");
|
||||
cwriteln('writing files after startup');
|
||||
writefiles();
|
||||
cwriteln("waiting for Lsyncd to transmit changes");
|
||||
posix.sleep(5);
|
||||
cwriteln('waiting for Lsyncd to transmit changes');
|
||||
posix.sleep(15);
|
||||
testfiles();
|
||||
|
||||
cwriteln("killing started Lsyncd");
|
||||
cwriteln('killing started Lsyncd');
|
||||
posix.kill(pid);
|
||||
local _, exitmsg, lexitcode = posix.wait(lpid);
|
||||
cwriteln("Exitcode of Lsyncd = ", exitmsg, " ", lexitcode);
|
||||
cwriteln('Exitcode of Lsyncd = ', exitmsg, ' ', lexitcode);
|
||||
posix.sleep(1);
|
||||
if lexitcode == 0 then
|
||||
cwriteln("OK");
|
||||
cwriteln('OK');
|
||||
end
|
||||
os.exit(lexitcode);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user