fixing creation recursing

This commit is contained in:
Axel Kittenberger 2012-02-16 16:49:34 +01:00
parent 6faf99d952
commit 5e4fdba53a
3 changed files with 106 additions and 123 deletions

View File

@ -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);

View File

@ -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

View File

@ -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);