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]],
}
sync{bash, source="src", target="trg/"}
sync{bash, source="src", target="/path/to/trg/"}

View File

@ -11,6 +11,6 @@ settings = {
sync{
default.rsync,
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.
* @return (Lua stack) a table of directory names.
* names are keys, values are boolean
* true on dirs.
*/
static int
l_subdirs (lua_State *L)
l_readdir (lua_State *L)
{
const char * dirname = luaL_checkstring(L, 1);
DIR *d;
int idx = 1;
d = opendir(dirname);
if (d == NULL) {
@ -926,29 +927,30 @@ l_subdirs (lua_State *L)
/* finished */
break;
}
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
/* ignores . and .. */
continue;
}
if (de->d_type == DT_UNKNOWN) {
/* 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;
strcpy(subdir, dirname);
strcat(subdir, "/");
strcat(subdir, de->d_name);
stat(subdir, &st);
strcpy(entry, dirname);
strcat(entry, "/");
strcat(entry, de->d_name);
stat(entry, &st);
isdir = S_ISDIR(st.st_mode);
free(subdir);
free(entry);
} else {
/* readdir can trusted */
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 */
lua_pushnumber(L, idx++);
/* adds this entry to the Lua table */
lua_pushstring(L, de->d_name);
lua_pushboolean(L, isdir);
lua_settable(L, -3);
}
return 1;
@ -1032,9 +1034,9 @@ static const luaL_reg lsyncdlib[] = {
{"inotifyrm", l_inotifyrm },
{"log", l_log },
{"now", l_now },
{"readdir", l_readdir },
{"realdir", l_realdir },
{"stackdump", l_stackdump },
{"subdirs", l_subdirs },
{"terminate", l_terminate },
{NULL, NULL}
};

View File

@ -348,6 +348,14 @@ local Inlet, InletControl = (function()
return getPath(event)
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
-- Excludes a trailing slash for dirs.
@ -1421,26 +1429,34 @@ local Inotifies = (function()
-- the relative path to root for recursed inotifies
-- @param sync link to the observer to be notified.
-- 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",
"Inotifies.add(",root,", ",path,", ",recurse,", ",sync,")")
-- registers watch
"Inotifies.addSync(",root,", ",path,", ",recurse,", ",sync,")")
-- lets the core registers watch with the kernel
local wd = lsyncd.inotifyadd(root .. path);
if wd < 0 then
log("Error","Failure adding watch ",dir," -> ignored ")
return
end
-- creates a sublist in wdlist
if not wdlist[wd] then
wdlist[wd] = Array.new()
end
-- and adds this sync to wdlist.
table.insert(wdlist[wd], {
root = root,
path = path,
recurse = recurse,
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]
if not sp then
sp = {}
@ -1449,10 +1465,23 @@ local Inotifies = (function()
sp[path] = wd
-- registers and adds watches for all subdirectories
if recurse then
local subdirs = lsyncd.subdirs(root .. path)
for _, dirname in ipairs(subdirs) do
add(root, path..dirname.."/", true, sync)
-- and/or raises create events for all entries
if recurse or raise then
local entries = lsyncd.readdir(root .. path)
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
@ -1534,15 +1563,16 @@ local Inotifies = (function()
path2 = inotify.path .. filename2
end
inotify.sync:delay(etype, time, path, path2)
-- adds subdirs for new directories
if isdir and inotify.recurse then
if etype == "Create" then
add(inotify.root, path, true, inotify.sync)
addSync(inotify.root, path, true, inotify.sync, time)
elseif etype == "Delete" then
removeSync(inotify.sync, path)
elseif etype == "Move" then
removeSync(inotify.sync, path)
add(inotify.root, path2, true, inotify.sync)
addSync(inotify.root, path2, true, inotify.sync, time)
end
end
end
@ -1572,7 +1602,7 @@ local Inotifies = (function()
-- public interface
return {
add = add,
addSync = addSync,
size = size,
event = event,
statusReport = statusReport
@ -1588,6 +1618,7 @@ local functionWriter = (function()
-- all variables for layer 3
transVars = {
{ "%^pathname", "event.pathname" , 1, },
{ "%^pathdir", "event.pathdir" , 1, },
{ "%^path", "event.path" , 1, },
{ "%^sourcePathname", "event.sourcePathname" , 1, },
{ "%^sourcePath", "event.sourcePath" , 1, },
@ -2156,9 +2187,9 @@ function runner.initialize()
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
Inotifies.add(s.source, "", true, s)
Inotifies.addSync(s.source, "", true, s, nil, nil)
if s.config.init then
InletControl.setSync(s)
s.config.init(Inlet)
@ -2365,6 +2396,7 @@ local rsync_ssh = {
[255] = "again",
}
-----
-- Lsyncd classic - sync with rsync
--
@ -2373,17 +2405,44 @@ local default_rsync = {
-- Spawns rsync for a list of events
--
action = function(inlet)
local elist = inlet.getEvents()
local config = inlet.getConfig()
local paths = elist.getPaths()
log("Normal", "rsyncing list\n", paths)
spawn(elist, "/usr/bin/rsync",
"<", paths,
"--delete",
config.rsyncOps .. "r",
"--include-from=-",
"--exclude=*",
config.source, config.target)
local event = inlet.getEvent()
-- if the next element is a Delete does a delete operation
-- over its directory
if event.etype == "Delete" then
local evDir = event.pathdir
-- gets all deletes in the same directory
local elist = inlet.getEvents(function(e2)
return e2.etype == "Delete" and evDir == e2.pathdir
end)
local paths = elist.getPaths()
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,
-----
@ -2415,9 +2474,9 @@ local default_rsync = {
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* populating the source$C0"
echo -e "$C1* ceating d[x]/e/f1 $C0"
mkdir -p "$S"/d/e
echo 'test' > "$S"/d/e/f1
echo -e "$C1* starting lsyncd$C0"
@ -35,10 +36,11 @@ echo -e "$C1* waiting for lsyncd to start$C0"
sleep 4s
# 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
cp -r "$S"/d "$S"/d${i}
echo 'test2' > "$S"/d${i}/e/f2
# echo 'test2' > "$S"/d${i}/e/f2
done
#mkdir -p "$S"/m/n
@ -49,7 +51,7 @@ done
#done
echo -e "$C1* waiting for Lsyncd to do its job.$C0"
sleep 30s
sleep 20s
echo -e "$C1* killing Lsyncd$C0"
PID=$(cat "$P")