mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-12-13 14:43:09 +00:00
working on fsevents
This commit is contained in:
parent
2f21d0f0b8
commit
44e0e45594
16
Makefile.am
16
Makefile.am
@ -2,16 +2,16 @@ AUTOMAKE_OPTIONS = foreign
|
|||||||
CFLAGS += -Wall $(LUA_CFLAGS)
|
CFLAGS += -Wall $(LUA_CFLAGS)
|
||||||
bin_PROGRAMS = lsyncd
|
bin_PROGRAMS = lsyncd
|
||||||
lsyncd_SOURCES = lsyncd.h lsyncd.c lsyncd.lua
|
lsyncd_SOURCES = lsyncd.h lsyncd.c lsyncd.lua
|
||||||
#if INOTIFY
|
if INOTIFY
|
||||||
lsyncd_SOURCES += inotify.c
|
lsyncd_SOURCES += inotify.c
|
||||||
#endif
|
endif
|
||||||
#if FANOTIFY
|
if FANOTIFY
|
||||||
#lsyncd_SOURCES += fanotify.c
|
lsyncd_SOURCES += fanotify.c
|
||||||
#endif
|
endif
|
||||||
|
|
||||||
#if FSEVENTS
|
if FSEVENTS
|
||||||
#lsyncd_SOURCES += fsevents.c
|
lsyncd_SOURCES += fsevents.c
|
||||||
#endif
|
endif
|
||||||
|
|
||||||
lsyncd_LDADD = $(LUA_LIBS)
|
lsyncd_LDADD = $(LUA_LIBS)
|
||||||
exampledir = $(datarootdir)/doc/@PACKAGE@
|
exampledir = $(datarootdir)/doc/@PACKAGE@
|
||||||
|
62
configure.ac
62
configure.ac
@ -41,44 +41,44 @@ AM_CONDITIONAL([RUNNER], [test x${with_runner} != x])
|
|||||||
## With this release Lsyncd can yet only do with inotify.
|
## With this release Lsyncd can yet only do with inotify.
|
||||||
## enabling fsevents and disabling inotify is thus commented out.
|
## enabling fsevents and disabling inotify is thus commented out.
|
||||||
|
|
||||||
####
|
###
|
||||||
## --without-inotify option
|
# --without-inotify option
|
||||||
#AC_ARG_WITH([inotify],
|
AC_ARG_WITH([inotify],
|
||||||
#[ --without-inotify Do not use Linux inotify event interface. On by default.])
|
[ --without-inotify Do not use Linux inotify event interface. On by default.])
|
||||||
#if test "x${with_inotify}" == xno; then
|
if test "x${with_inotify}" == xno; then
|
||||||
# echo "compiling without inotify"
|
echo "compiling without inotify"
|
||||||
#else
|
else
|
||||||
echo "compiling with inotify"
|
echo "compiling with inotify"
|
||||||
AC_DEFINE(LSYNCD_WITH_INOTIFY,,"descr")
|
AC_DEFINE(LSYNCD_WITH_INOTIFY,,"descr")
|
||||||
#fi
|
fi
|
||||||
AM_CONDITIONAL([INOTIFY], [test x${with_inotify} != xno])
|
AM_CONDITIONAL([INOTIFY], [test x${with_inotify} != xno])
|
||||||
|
|
||||||
####
|
###
|
||||||
## --with-fanotify option
|
# --with-fanotify option
|
||||||
##
|
#
|
||||||
#AC_ARG_WITH([fanotify],
|
AC_ARG_WITH([fanotify],
|
||||||
#[ --with-fanotify Uses Linux new fanotify event interface. EXPERIMENTAL!
|
[ --with-fanotify Uses Linux new fanotify event interface. EXPERIMENTAL!
|
||||||
# Off by default.])
|
Off by default.])
|
||||||
##if test "x${with_fanotify}" == xno; then
|
if test "x${with_fanotify}" == x || test "x${with_fanotify}no" == xno; then
|
||||||
# echo "compiling without fanotify"
|
echo "compiling without fanotify"
|
||||||
#else
|
else
|
||||||
# echo "compiling with fanotify - WARNING experimental!"
|
echo "compiling with fanotify - WARNING experimental!"
|
||||||
# AC_DEFINE(LSYNCD_WITH_FANOTIFY,,"descr")
|
AC_DEFINE(LSYNCD_WITH_FANOTIFY,,"descr")
|
||||||
##fi
|
fi
|
||||||
AM_CONDITIONAL([FANOTIFY],
|
AM_CONDITIONAL([FANOTIFY],
|
||||||
[test x${with_fanotify} != x -a x${with_fanotify} != xno])
|
[test x${with_fanotify} != x -a x${with_fanotify} != xno])
|
||||||
|
|
||||||
####
|
###
|
||||||
## --with-fsevents
|
# --with-fsevents
|
||||||
#AC_ARG_WITH([fsevents],
|
AC_ARG_WITH([fsevents],
|
||||||
#[ --with-fsevents Uses MacOS (10.5) /dev/fsevents. EXPERIMENTAL!
|
[ --with-fsevents Uses MacOS (10.5) /dev/fsevents. EXPERIMENTAL!
|
||||||
# Off by default.])
|
Off by default.])
|
||||||
#if test "x${with_fsevents}" != x; then
|
if test "x${with_fsevents}" != x; then
|
||||||
# echo "compiling with fsevents. WARNING experimental!"
|
echo "compiling with fsevents. WARNING experimental!"
|
||||||
# AC_DEFINE(LSYNCD_WITH_FSEVENTS,,"descr")
|
AC_DEFINE(LSYNCD_WITH_FSEVENTS,,"descr")
|
||||||
#else
|
else
|
||||||
# echo "compiling without fsevents"
|
echo "compiling without fsevents"
|
||||||
#fi
|
fi
|
||||||
AM_CONDITIONAL([FSEVENTS],
|
AM_CONDITIONAL([FSEVENTS],
|
||||||
[test x${with_fsevents} != x -a xno${with_fsevents} != xno])
|
[test x${with_fsevents} != x -a xno${with_fsevents} != xno])
|
||||||
|
|
||||||
|
147
fsevents.c
147
fsevents.c
@ -25,9 +25,6 @@
|
|||||||
* including Spotlight. Consequently, Spotlight may need to look at the entire
|
* including Spotlight. Consequently, Spotlight may need to look at the entire
|
||||||
* volume to determine "what changed".
|
* volume to determine "what changed".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#error "This code is not yet finished."
|
|
||||||
|
|
||||||
#include "lsyncd.h"
|
#include "lsyncd.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -90,7 +87,8 @@ struct kfs_event {
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
/* event arguments */
|
/* event arguments */
|
||||||
struct kfs_event_arg args[KFS_NUM_ARGS];
|
struct kfs_event_arg args[];
|
||||||
|
/* struct kfs_event_arg args[KFS_NUM_ARGS]; */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,7 +100,7 @@ static const luaL_reg lfseventslib[] = {
|
|||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
// event names
|
/* event names */
|
||||||
static const char *eventNames[FSE_MAX_EVENTS] = {
|
static const char *eventNames[FSE_MAX_EVENTS] = {
|
||||||
"CREATE_FILE",
|
"CREATE_FILE",
|
||||||
"DELETE",
|
"DELETE",
|
||||||
@ -117,9 +115,111 @@ static const char *eventNames[FSE_MAX_EVENTS] = {
|
|||||||
"XATTR_REMOVED",
|
"XATTR_REMOVED",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* argument names*/
|
||||||
|
static const char *argNames[] = {
|
||||||
|
"UNKNOWN",
|
||||||
|
"VNODE",
|
||||||
|
"STRING",
|
||||||
|
"PATH",
|
||||||
|
"INT32",
|
||||||
|
"INT64",
|
||||||
|
"RAW",
|
||||||
|
"INO",
|
||||||
|
"UID",
|
||||||
|
"DEV",
|
||||||
|
"MODE",
|
||||||
|
"GID",
|
||||||
|
"FINFO",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The read buffer
|
||||||
|
*/
|
||||||
static size_t const readbuf_size = 131072;
|
static size_t const readbuf_size = 131072;
|
||||||
static char * readbuf = NULL;
|
static char * readbuf = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles one fsevents event
|
||||||
|
* @returns the size of the event
|
||||||
|
*/
|
||||||
|
static ssize_t
|
||||||
|
handle_event(lua_State *L, struct kfs_event *event, ssize_t mlen)
|
||||||
|
{
|
||||||
|
/* the len of the event */
|
||||||
|
ssize_t len = sizeof(int32_t) + sizeof(pid_t);
|
||||||
|
|
||||||
|
bool want_path = false;
|
||||||
|
const char *path = NULL;
|
||||||
|
|
||||||
|
if (event->type == FSE_EVENTS_DROPPED) {
|
||||||
|
logstring("Fsevents", "Events dropped!");
|
||||||
|
load_runner_func(L, "overflow");
|
||||||
|
if (lua_pcall(L, 0, 0, -2)) {
|
||||||
|
exit(-1); // ERRNO
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
hup = 1;
|
||||||
|
len += sizeof(u_int16_t);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
int32_t atype = event->type & FSE_TYPE_MASK;
|
||||||
|
uint32_t aflags = FSE_GET_FLAGS(event->type);
|
||||||
|
|
||||||
|
if ((atype < FSE_MAX_EVENTS) && (atype >= -1)) {
|
||||||
|
printlogf(L, "Fsevents", "got event %s", eventNames[atype]);
|
||||||
|
if (aflags & FSE_COMBINED_EVENTS) {
|
||||||
|
logstring("Fsevents", "combined events");
|
||||||
|
}
|
||||||
|
if (aflags & FSE_CONTAINS_DROPPED_EVENTS) {
|
||||||
|
logstring("Fsevents", "contains dropped events");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printlogf(L, "Error", "unknown event(%d) in fsevents.",
|
||||||
|
atype);
|
||||||
|
exit(-1); // ERRNO
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(atype) {
|
||||||
|
case FSE_CREATE_FILE :
|
||||||
|
want_path = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct kfs_event_arg *arg = event->args;
|
||||||
|
while (len < mlen) {
|
||||||
|
int eoff;
|
||||||
|
if (arg->type == FSE_ARG_DONE) {
|
||||||
|
logstring("Fsevents", "argdone");
|
||||||
|
len += sizeof(u_int16_t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (arg->type) {
|
||||||
|
case FSE_ARG_STRING :
|
||||||
|
if (want_path && !path) {
|
||||||
|
path = arg->data.str;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
eoff = sizeof(arg->type) + sizeof(arg->len) + arg->len;
|
||||||
|
len += eoff;
|
||||||
|
printlogf(L, "Fsevents", "arg:%s:%d",
|
||||||
|
argNames[arg->type > FSE_MAX_ARGS ? 0 : arg->type],
|
||||||
|
arg->len);
|
||||||
|
arg = (struct kfs_event_arg *) ((char *) arg + eoff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path) {
|
||||||
|
// printlogf(L, "path=%s", path);
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when fsevents has something to read
|
* Called when fsevents has something to read
|
||||||
*/
|
*/
|
||||||
@ -141,7 +241,7 @@ fsevents_ready(lua_State *L, struct observance *obs)
|
|||||||
}
|
}
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (err == EAGAIN) {
|
if (err == EAGAIN) {
|
||||||
/* nothing more inotify */
|
/* nothing more */
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
printlogf(L, "Error", "Read fail on fsevents");
|
printlogf(L, "Error", "Read fail on fsevents");
|
||||||
@ -150,40 +250,9 @@ fsevents_ready(lua_State *L, struct observance *obs)
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
int off = 0;
|
int off = 0;
|
||||||
int32_t atype;
|
|
||||||
uint32_t aflags;
|
|
||||||
|
|
||||||
while (off < len && !hup && !term) {
|
while (off < len && !hup && !term) {
|
||||||
struct kfs_event *event = (struct kfs_event *) &readbuf[off];
|
struct kfs_event *event = (struct kfs_event *) &readbuf[off];
|
||||||
off += sizeof(int32_t) + sizeof(pid_t);
|
off += handle_event(L, event, len);
|
||||||
|
|
||||||
if (event->type == FSE_EVENTS_DROPPED) {
|
|
||||||
logstring("Fsevents", "Events dropped!");
|
|
||||||
load_runner_func(L, "overflow");
|
|
||||||
if (lua_pcall(L, 0, 0, -2)) {
|
|
||||||
exit(-1); // ERRNO
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
|
||||||
hup = 1;
|
|
||||||
off += sizeof(u_int16_t);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
atype = event->type & FSE_TYPE_MASK;
|
|
||||||
aflags = FSE_GET_FLAGS(event->type);
|
|
||||||
|
|
||||||
if ((atype < FSE_MAX_EVENTS) && (atype >= -1)) {
|
|
||||||
printlogf(L, "Fsevents", "got event %s", eventNames[atype]);
|
|
||||||
if (aflags & FSE_COMBINED_EVENTS) {
|
|
||||||
logstring("Fsevents", "combined events");
|
|
||||||
}
|
|
||||||
if (aflags & FSE_CONTAINS_DROPPED_EVENTS) {
|
|
||||||
logstring("Fsevents", "contains dropped events");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printlogf(L, "Error", "unknown event(%d) in fsevents.",
|
|
||||||
atype);
|
|
||||||
exit(-1); // ERRNO
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,8 +289,6 @@ register_fsevents(lua_State *L) {
|
|||||||
extern void
|
extern void
|
||||||
open_fsevents(lua_State *L)
|
open_fsevents(lua_State *L)
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
|
|
||||||
int8_t event_list[] = { // action to take for each event
|
int8_t event_list[] = { // action to take for each event
|
||||||
FSE_REPORT, /* FSE_CREATE_FILE */
|
FSE_REPORT, /* FSE_CREATE_FILE */
|
||||||
FSE_REPORT, /* FSE_DELETE */
|
FSE_REPORT, /* FSE_DELETE */
|
||||||
|
100
lsyncd.lua
100
lsyncd.lua
@ -1871,60 +1871,60 @@ local Inotify = (function()
|
|||||||
}
|
}
|
||||||
end)()
|
end)()
|
||||||
|
|
||||||
------
|
|
||||||
---- Interface to OSX /dev/fsevents, watches the whole filesystems
|
|
||||||
----
|
----
|
||||||
---- All fsevents specific implementation should be enclosed here.
|
-- Interface to OSX /dev/fsevents, watches the whole filesystems
|
||||||
----
|
|
||||||
--local Fsevents = (function()
|
|
||||||
-- -----
|
|
||||||
-- -- A list indexed by sync's containing the root path this
|
|
||||||
-- -- sync is interested in.
|
|
||||||
-- --
|
|
||||||
-- local syncPaths = {}
|
|
||||||
--
|
--
|
||||||
-- -----
|
-- All fsevents specific implementation should be enclosed here.
|
||||||
-- -- adds a Sync to receive events
|
|
||||||
-- --
|
|
||||||
-- -- @param sync Object to receive events
|
|
||||||
-- -- @param dir dir to watch
|
|
||||||
-- --
|
|
||||||
-- local function addSync(sync, dir)
|
|
||||||
-- if syncRoots[sync] then
|
|
||||||
-- error("duplicate sync in Fanotify.addSync()")
|
|
||||||
-- end
|
|
||||||
-- -- TODO for non subdirs adddir only
|
|
||||||
-- syncRoots[sync] = dir
|
|
||||||
-- end
|
|
||||||
--
|
--
|
||||||
-- -----
|
local Fsevents = (function()
|
||||||
-- -- Called when any event has occured.
|
-----
|
||||||
-- --
|
-- A list indexed by sync's containing the root path this
|
||||||
-- -- @param etype "Attrib", "Mofify", "Create", "Delete", "Move")
|
-- sync is interested in.
|
||||||
-- -- @param wd watch descriptor (matches lsyncd.inotifyadd())
|
|
||||||
-- -- @param isdir true if filename is a directory
|
|
||||||
-- -- @param time time of event
|
|
||||||
-- -- @param filename string filename without path
|
|
||||||
-- -- @param filename2
|
|
||||||
-- --
|
|
||||||
-- local function event(etype, isdir, time, filename, filename2)
|
|
||||||
-- log("Fsevents", etype, isdir, time, filename, filename2)
|
|
||||||
-- end
|
|
||||||
--
|
--
|
||||||
-- -----
|
local syncRoots = {}
|
||||||
-- -- Writes a status report about inotifies to a filedescriptor
|
|
||||||
-- --
|
-----
|
||||||
-- local function statusReport(f)
|
-- adds a Sync to receive events
|
||||||
-- -- TODO
|
|
||||||
-- end
|
|
||||||
--
|
--
|
||||||
-- -- public interface
|
-- @param sync Object to receive events
|
||||||
-- return {
|
-- @param dir dir to watch
|
||||||
-- addSync = addSync,
|
--
|
||||||
-- event = event,
|
local function addSync(sync, dir)
|
||||||
-- statusReport = statusReport
|
if syncRoots[sync] then
|
||||||
-- }
|
error("duplicate sync in Fanotify.addSync()")
|
||||||
--end)()
|
end
|
||||||
|
-- TODO for non subdirs adddir only
|
||||||
|
syncRoots[sync] = dir
|
||||||
|
end
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- Called when any event has occured.
|
||||||
|
--
|
||||||
|
-- @param etype "Attrib", "Mofify", "Create", "Delete", "Move")
|
||||||
|
-- @param wd watch descriptor (matches lsyncd.inotifyadd())
|
||||||
|
-- @param isdir true if filename is a directory
|
||||||
|
-- @param time time of event
|
||||||
|
-- @param filename string filename without path
|
||||||
|
-- @param filename2
|
||||||
|
--
|
||||||
|
local function event(etype, isdir, time, filename, filename2)
|
||||||
|
log("Fsevents", etype, isdir, time, filename, filename2)
|
||||||
|
end
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- Writes a status report about inotifies to a filedescriptor
|
||||||
|
--
|
||||||
|
local function statusReport(f)
|
||||||
|
-- TODO
|
||||||
|
end
|
||||||
|
|
||||||
|
-- public interface
|
||||||
|
return {
|
||||||
|
addSync = addSync,
|
||||||
|
event = event,
|
||||||
|
statusReport = statusReport
|
||||||
|
}
|
||||||
|
end)()
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- Holds information about the event monitor capabilities
|
-- Holds information about the event monitor capabilities
|
||||||
@ -2643,7 +2643,7 @@ function runner.initialize()
|
|||||||
for _, s in Syncs.iwalk() do
|
for _, s in Syncs.iwalk() do
|
||||||
if s.config.monitor == "inotify" then
|
if s.config.monitor == "inotify" then
|
||||||
Inotify.addSync(s, s.source)
|
Inotify.addSync(s, s.source)
|
||||||
elseif s.config.monitor == "fanotify" then
|
elseif s.config.monitor == "fsevents" then
|
||||||
Fsevents.addSync(s, s.source)
|
Fsevents.addSync(s, s.source)
|
||||||
else
|
else
|
||||||
error("sync "..s.config.name..
|
error("sync "..s.config.name..
|
||||||
|
Loading…
Reference in New Issue
Block a user