This commit is contained in:
Axel Kittenberger 2010-11-17 18:52:55 +00:00
parent a3424ed034
commit a5a0b04ae0
5 changed files with 112 additions and 49 deletions

View File

@ -36,5 +36,5 @@ bash = {
onMove = prefix..[[mv ^o.targetPathname ^d.targetPathname]], onMove = prefix..[[mv ^o.targetPathname ^d.targetPathname]],
} }
sync{bash, source="src", target="trg/"} sync{bash, source="src", target="/path/to/trg/"}

View File

@ -11,6 +11,6 @@ settings = {
sync{ sync{
default.rsync, default.rsync,
source="src", source="src",
target="/home/user/dst/", target="trg",
} }

View File

@ -900,17 +900,18 @@ l_stackdump(lua_State* L)
} }
/** /**
* Reads the directories sub directories. * Reads the directories entries.
* * XXX
* @param (Lua stack) absolute path to directory. * @param (Lua stack) absolute path to directory.
* @return (Lua stack) a table of directory names. * @return (Lua stack) a table of directory names.
* names are keys, values are boolean
* true on dirs.
*/ */
static int static int
l_subdirs (lua_State *L) l_readdir (lua_State *L)
{ {
const char * dirname = luaL_checkstring(L, 1); const char * dirname = luaL_checkstring(L, 1);
DIR *d; DIR *d;
int idx = 1;
d = opendir(dirname); d = opendir(dirname);
if (d == NULL) { if (d == NULL) {
@ -926,29 +927,30 @@ l_subdirs (lua_State *L)
/* finished */ /* finished */
break; break;
} }
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
/* ignores . and .. */
continue;
}
if (de->d_type == DT_UNKNOWN) { if (de->d_type == DT_UNKNOWN) {
/* must call stat on some systems :-/ */ /* must call stat on some systems :-/ */
char *subdir = s_malloc(strlen(dirname) + strlen(de->d_name) + 2); char *entry = s_malloc(strlen(dirname) + strlen(de->d_name) + 2);
struct stat st; struct stat st;
strcpy(subdir, dirname); strcpy(entry, dirname);
strcat(subdir, "/"); strcat(entry, "/");
strcat(subdir, de->d_name); strcat(entry, de->d_name);
stat(subdir, &st); stat(entry, &st);
isdir = S_ISDIR(st.st_mode); isdir = S_ISDIR(st.st_mode);
free(subdir); free(entry);
} else { } else {
/* readdir can trusted */ /* readdir can trusted */
isdir = de->d_type == DT_DIR; isdir = de->d_type == DT_DIR;
} }
if (!isdir || !strcmp(de->d_name, ".") ||
!strcmp(de->d_name, ".."))
{ /* ignore non directories and . and .. */
continue;
}
/* add this to the Lua table */ /* adds this entry to the Lua table */
lua_pushnumber(L, idx++);
lua_pushstring(L, de->d_name); lua_pushstring(L, de->d_name);
lua_pushboolean(L, isdir);
lua_settable(L, -3); lua_settable(L, -3);
} }
return 1; return 1;
@ -1032,9 +1034,9 @@ static const luaL_reg lsyncdlib[] = {
{"inotifyrm", l_inotifyrm }, {"inotifyrm", l_inotifyrm },
{"log", l_log }, {"log", l_log },
{"now", l_now }, {"now", l_now },
{"readdir", l_readdir },
{"realdir", l_realdir }, {"realdir", l_realdir },
{"stackdump", l_stackdump }, {"stackdump", l_stackdump },
{"subdirs", l_subdirs },
{"terminate", l_terminate }, {"terminate", l_terminate },
{NULL, NULL} {NULL, NULL}
}; };

View File

@ -348,6 +348,14 @@ local Inlet, InletControl = (function()
return getPath(event) return getPath(event)
end, end,
-----
-- Returns the directory of the file/dir relative to watch root
-- Always includes a trailing slash.
--
pathdir = function(event)
return string.match(getPath(event), "^(.*/)[^/]*/?") or ""
end,
----- -----
-- Returns the file/dir relativ to watch root -- Returns the file/dir relativ to watch root
-- Excludes a trailing slash for dirs. -- Excludes a trailing slash for dirs.
@ -1421,26 +1429,34 @@ local Inotifies = (function()
-- the relative path to root for recursed inotifies -- the relative path to root for recursed inotifies
-- @param sync link to the observer to be notified. -- @param sync link to the observer to be notified.
-- Note: Inotifies should handle this opaquely -- Note: Inotifies should handle this opaquely
local function add(root, path, recurse, sync) -- @param raise if not nil creates Create events for all files/dirs
-- in this directory. Value is time for event.
local function addSync(root, path, recurse, sync, raise)
log("Function", log("Function",
"Inotifies.add(",root,", ",path,", ",recurse,", ",sync,")") "Inotifies.addSync(",root,", ",path,", ",recurse,", ",sync,")")
-- registers watch
-- lets the core registers watch with the kernel
local wd = lsyncd.inotifyadd(root .. path); local wd = lsyncd.inotifyadd(root .. path);
if wd < 0 then if wd < 0 then
log("Error","Failure adding watch ",dir," -> ignored ") log("Error","Failure adding watch ",dir," -> ignored ")
return return
end end
-- creates a sublist in wdlist
if not wdlist[wd] then if not wdlist[wd] then
wdlist[wd] = Array.new() wdlist[wd] = Array.new()
end end
-- and adds this sync to wdlist.
table.insert(wdlist[wd], { table.insert(wdlist[wd], {
root = root, root = root,
path = path, path = path,
recurse = recurse, recurse = recurse,
sync = sync sync = sync
}) })
-- create an entry for receival of with sync/path keys
-- creates an entry in syncpaths to quickly retrieve
-- all entries of this sync for a path.
local sp = syncpaths[sync] local sp = syncpaths[sync]
if not sp then if not sp then
sp = {} sp = {}
@ -1449,10 +1465,23 @@ local Inotifies = (function()
sp[path] = wd sp[path] = wd
-- registers and adds watches for all subdirectories -- registers and adds watches for all subdirectories
if recurse then -- and/or raises create events for all entries
local subdirs = lsyncd.subdirs(root .. path) if recurse or raise then
for _, dirname in ipairs(subdirs) do local entries = lsyncd.readdir(root .. path)
add(root, path..dirname.."/", true, sync) for dirname, isdir in pairs(entries) do
local pd = path .. dirname
if isdir then
pd = pd .. "/"
end
-- creates a Create event for entry.
if raise then
sync:delay("Create", raise, pd, nil)
end
-- adds syncs for subdirs
if isdir and recurse then
addSync(root, pd, true, sync, raise)
end
end end
end end
end end
@ -1534,15 +1563,16 @@ local Inotifies = (function()
path2 = inotify.path .. filename2 path2 = inotify.path .. filename2
end end
inotify.sync:delay(etype, time, path, path2) inotify.sync:delay(etype, time, path, path2)
-- adds subdirs for new directories -- adds subdirs for new directories
if isdir and inotify.recurse then if isdir and inotify.recurse then
if etype == "Create" then if etype == "Create" then
add(inotify.root, path, true, inotify.sync) addSync(inotify.root, path, true, inotify.sync, time)
elseif etype == "Delete" then elseif etype == "Delete" then
removeSync(inotify.sync, path) removeSync(inotify.sync, path)
elseif etype == "Move" then elseif etype == "Move" then
removeSync(inotify.sync, path) removeSync(inotify.sync, path)
add(inotify.root, path2, true, inotify.sync) addSync(inotify.root, path2, true, inotify.sync, time)
end end
end end
end end
@ -1572,7 +1602,7 @@ local Inotifies = (function()
-- public interface -- public interface
return { return {
add = add, addSync = addSync,
size = size, size = size,
event = event, event = event,
statusReport = statusReport statusReport = statusReport
@ -1588,6 +1618,7 @@ local functionWriter = (function()
-- all variables for layer 3 -- all variables for layer 3
transVars = { transVars = {
{ "%^pathname", "event.pathname" , 1, }, { "%^pathname", "event.pathname" , 1, },
{ "%^pathdir", "event.pathdir" , 1, },
{ "%^path", "event.path" , 1, }, { "%^path", "event.path" , 1, },
{ "%^sourcePathname", "event.sourcePathname" , 1, }, { "%^sourcePathname", "event.sourcePathname" , 1, },
{ "%^sourcePath", "event.sourcePath" , 1, }, { "%^sourcePath", "event.sourcePath" , 1, },
@ -2156,9 +2187,9 @@ function runner.initialize()
end end
end end
-- runs through the syncs table filled by user calling directory() -- runs through the Syncs created by users
for _, s in Syncs.iwalk() do for _, s in Syncs.iwalk() do
Inotifies.add(s.source, "", true, s) Inotifies.addSync(s.source, "", true, s, nil, nil)
if s.config.init then if s.config.init then
InletControl.setSync(s) InletControl.setSync(s)
s.config.init(Inlet) s.config.init(Inlet)
@ -2365,6 +2396,7 @@ local rsync_ssh = {
[255] = "again", [255] = "again",
} }
----- -----
-- Lsyncd classic - sync with rsync -- Lsyncd classic - sync with rsync
-- --
@ -2373,17 +2405,44 @@ local default_rsync = {
-- Spawns rsync for a list of events -- Spawns rsync for a list of events
-- --
action = function(inlet) action = function(inlet)
local elist = inlet.getEvents() local event = inlet.getEvent()
local config = inlet.getConfig() -- if the next element is a Delete does a delete operation
local paths = elist.getPaths() -- over its directory
log("Normal", "rsyncing list\n", paths) if event.etype == "Delete" then
spawn(elist, "/usr/bin/rsync", local evDir = event.pathdir
"<", paths, -- gets all deletes in the same directory
"--delete", local elist = inlet.getEvents(function(e2)
config.rsyncOps .. "r", return e2.etype == "Delete" and evDir == e2.pathdir
"--include-from=-", end)
"--exclude=*", local paths = elist.getPaths()
config.source, config.target) log("Normal", "rsyncing deletes in ",evDir,":\n",paths)
local config = inlet.getConfig()
spawn(elist, "/usr/bin/rsync",
"<", paths,
"--delete",
config.rsyncOps .. "d",
"--include-from=-",
"--exclude=*",
config.source .. evDir, config.target .. evDir)
else
-- if it isn't it does a normal transfer of everything
-- new or altered.
-- gets all non-deletes.
local elist = inlet.getEvents(function(e2)
return e2.etype ~= "Delete"
end)
local paths = elist.getPaths()
log("Normal", "rsyncing a list of new/modified files/dirs\n",
paths)
local config = inlet.getConfig()
spawn(elist, "/usr/bin/rsync",
"<", paths,
config.rsyncOps,
"--files-from=-",
config.source, config.target)
end
end, end,
----- -----
@ -2415,9 +2474,9 @@ local default_rsync = {
exitcodes = rsync_exitcodes, exitcodes = rsync_exitcodes,
----- -----
-- Default delay 3 seconds -- Default delay
-- --
delay = 20, delay = 10,
} }

View File

@ -25,6 +25,7 @@ P=$R/pid
echo -e "$C1* using root dir for test $R$C0" echo -e "$C1* using root dir for test $R$C0"
echo -e "$C1* populating the source$C0" echo -e "$C1* populating the source$C0"
echo -e "$C1* ceating d[x]/e/f1 $C0"
mkdir -p "$S"/d/e mkdir -p "$S"/d/e
echo 'test' > "$S"/d/e/f1 echo 'test' > "$S"/d/e/f1
echo -e "$C1* starting lsyncd$C0" echo -e "$C1* starting lsyncd$C0"
@ -35,10 +36,11 @@ echo -e "$C1* waiting for lsyncd to start$C0"
sleep 4s sleep 4s
# cp -r the directory # cp -r the directory
echo -e "$C1* making some data$CO" echo -e "$C1* making some data$C0"
echo -e "$C1* ceating d[x]/e/f2 $C0"
for i in $RANGE; do for i in $RANGE; do
cp -r "$S"/d "$S"/d${i} cp -r "$S"/d "$S"/d${i}
echo 'test2' > "$S"/d${i}/e/f2 # echo 'test2' > "$S"/d${i}/e/f2
done done
#mkdir -p "$S"/m/n #mkdir -p "$S"/m/n
@ -49,7 +51,7 @@ done
#done #done
echo -e "$C1* waiting for Lsyncd to do its job.$C0" echo -e "$C1* waiting for Lsyncd to do its job.$C0"
sleep 30s sleep 20s
echo -e "$C1* killing Lsyncd$C0" echo -e "$C1* killing Lsyncd$C0"
PID=$(cat "$P") PID=$(cat "$P")