mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-12-13 14:43:09 +00:00
made inotify (currently pseudo) optimal
This commit is contained in:
parent
82f80b5d7d
commit
c051e15750
@ -1,7 +1,11 @@
|
|||||||
AUTOMAKE_OPTIONS = foreign
|
AUTOMAKE_OPTIONS = foreign
|
||||||
CFLAGS = -Wall $(LIBLUA_CFLAGS)
|
CFLAGS = -Wall $(LIBLUA_CFLAGS)
|
||||||
bin_PROGRAMS = lsyncd
|
bin_PROGRAMS = lsyncd
|
||||||
lsyncd_SOURCES = lsyncd.h lsyncd.c lsyncd.lua inotify.c
|
lsyncd_SOURCES = lsyncd.h lsyncd.c lsyncd.lua
|
||||||
|
if INOTIFY
|
||||||
|
lsyncd_SOURCES += inotify.c
|
||||||
|
endif
|
||||||
|
|
||||||
lsyncd_LDADD = $(LIBLUA_LIBS)
|
lsyncd_LDADD = $(LIBLUA_LIBS)
|
||||||
exampledir = $(datarootdir)/doc/@PACKAGE@
|
exampledir = $(datarootdir)/doc/@PACKAGE@
|
||||||
dist_example_DATA = \
|
dist_example_DATA = \
|
||||||
|
27
configure.ac
27
configure.ac
@ -1,9 +1,10 @@
|
|||||||
# -*- Autoconf -*-
|
# -*- Autoconf -*-
|
||||||
|
echo XXXXXXXXX
|
||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
#AC_PREREQ(2.60)
|
#AC_PREREQ(2.60)
|
||||||
AC_INIT(lsyncd, 2.0beta3, axkibe@gmail.com)
|
AC_INIT(lsyncd, 2.0beta3, axkibe@gmail.com)
|
||||||
AC_CONFIG_SRCDIR([lsyncd.c],[lsyncd.lua],[inotify.c])
|
AC_CONFIG_SRCDIR([lsyncd.c])
|
||||||
AC_CONFIG_HEADER([config.h],[lsyncd.h])
|
AC_CONFIG_HEADER([config.h])
|
||||||
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
|
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
@ -14,14 +15,28 @@ PKG_CHECK_MODULES(LIBLUA, lua5.1)
|
|||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_CHECK_HEADERS([sys/inotify.h])
|
AC_CHECK_HEADERS([sys/inotify.h])
|
||||||
|
|
||||||
|
###
|
||||||
|
# --with-runner option
|
||||||
AC_ARG_WITH([runner],
|
AC_ARG_WITH([runner],
|
||||||
[ --with-runner=<dir> Specify directory where lsyncds part written in Lua will be placed.
|
[ --with-runner=<dir> Specify directory where lsyncds part written in Lua will be placed.
|
||||||
If missing it will be compiled into the binary)])
|
If missing it will be compiled into the binary])
|
||||||
if test "x${with_runner}" != x; then
|
if test "x${with_runner}" != x; then
|
||||||
AC_DEFINE_UNQUOTED(LSYNCD_DEFAULT_RUNNER_FILE, "${with_runner}/lsyncd.lua", "descr")
|
AC_DEFINE_UNQUOTED(LSYNCD_DEFAULT_RUNNER_FILE, "${with_runner}/lsyncd.lua", "descr")
|
||||||
AC_SUBST(RUNNER_DIR, "${with_runner}")
|
AC_SUBST(RUNNER_DIR, "${with_runner}")
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL([RUNNER], [test x${with_runner} != x])
|
AM_CONDITIONAL([RUNNER], [test x${with_runner} != x])
|
||||||
|
|
||||||
|
###
|
||||||
|
# --without-inotify option
|
||||||
|
AC_ARG_WITH([inotify],
|
||||||
|
[ --without-inotify Do not compile Linux inotify event interface (on by default)])
|
||||||
|
if test "x${with_inotify}" == xno; then
|
||||||
|
echo "compiling without inotify"
|
||||||
|
else
|
||||||
|
echo "compiling with inotify"
|
||||||
|
AC_DEFINE(LSYNCD_WITH_INOTIFY,,"descr")
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL([INOTIFY], [test x${with_inotify} != xno])
|
||||||
|
|
||||||
# Checks for typedefs, structures, and compiler characteristics.
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
|
41
inotify.c
41
inotify.c
@ -71,7 +71,7 @@ static int
|
|||||||
l_addwatch(lua_State *L)
|
l_addwatch(lua_State *L)
|
||||||
{
|
{
|
||||||
const char *path = luaL_checkstring(L, 1);
|
const char *path = luaL_checkstring(L, 1);
|
||||||
int wd = inotify_add_watch(inotify_fd, path, standard_event_mask);
|
lua_Integer wd = inotify_add_watch(inotify_fd, path, standard_event_mask);
|
||||||
printlogf(L, "Inotify", "addwatch(%s)->%d", path, wd);
|
printlogf(L, "Inotify", "addwatch(%s)->%d", path, wd);
|
||||||
lua_pushinteger(L, wd);
|
lua_pushinteger(L, wd);
|
||||||
return 1;
|
return 1;
|
||||||
@ -86,7 +86,7 @@ l_addwatch(lua_State *L)
|
|||||||
static int
|
static int
|
||||||
l_rmwatch(lua_State *L)
|
l_rmwatch(lua_State *L)
|
||||||
{
|
{
|
||||||
int wd = luaL_checkinteger(L, 1);
|
lua_Integer wd = luaL_checkinteger(L, 1);
|
||||||
inotify_rm_watch(inotify_fd, wd);
|
inotify_rm_watch(inotify_fd, wd);
|
||||||
printlogf(L, "Inotify", "rmwatch()<-%d", wd);
|
printlogf(L, "Inotify", "rmwatch()<-%d", wd);
|
||||||
return 0;
|
return 0;
|
||||||
@ -252,13 +252,8 @@ static char * readbuf = NULL;
|
|||||||
* to the runner.
|
* to the runner.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
inotify_ready(lua_State *L, struct observance *observance)
|
inotify_ready(lua_State *L, int fd, void *extra)
|
||||||
{
|
{
|
||||||
if (observance->fd != inotify_fd) {
|
|
||||||
logstring("Error",
|
|
||||||
"internal fail, inotify_ready on non-inotify file descriptor.");
|
|
||||||
exit(-1); // ERRNO
|
|
||||||
}
|
|
||||||
while(true) {
|
while(true) {
|
||||||
ptrdiff_t len;
|
ptrdiff_t len;
|
||||||
int err;
|
int err;
|
||||||
@ -312,24 +307,6 @@ inotify_ready(lua_State *L, struct observance *observance)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by function pointer when the core doesnt want the
|
|
||||||
* inotify fd anymore (term, hup or overflow)
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
inotify_tidy(struct observance *observance)
|
|
||||||
{
|
|
||||||
if (observance->fd != inotify_fd) {
|
|
||||||
logstring("Error",
|
|
||||||
"internal fail, inotify_ready on non-inotify file descriptor.");
|
|
||||||
exit(-1); // ERRNO
|
|
||||||
}
|
|
||||||
close(inotify_fd);
|
|
||||||
inotify_fd = -1;
|
|
||||||
free(readbuf);
|
|
||||||
readbuf = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* registers inotify functions.
|
* registers inotify functions.
|
||||||
*/
|
*/
|
||||||
@ -361,6 +338,16 @@ open_inotify(lua_State *L) {
|
|||||||
|
|
||||||
close_exec_fd(inotify_fd);
|
close_exec_fd(inotify_fd);
|
||||||
non_block_fd(inotify_fd);
|
non_block_fd(inotify_fd);
|
||||||
observe_fd(inotify_fd, inotify_ready, NULL, inotify_tidy, NULL);
|
observe_fd(inotify_fd, inotify_ready, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* closes inotify
|
||||||
|
*/
|
||||||
|
extern void
|
||||||
|
close_inotify() {
|
||||||
|
close(inotify_fd);
|
||||||
|
free(readbuf);
|
||||||
|
readbuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
227
lsyncd.c
227
lsyncd.c
@ -44,6 +44,16 @@ extern char _binary_luac_out_start;
|
|||||||
extern char _binary_luac_out_end;
|
extern char _binary_luac_out_end;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default notification system to use.
|
||||||
|
*/
|
||||||
|
#ifdef LSYNCD_WITH_INOTIFY
|
||||||
|
extern char *default_notify = "Inotify";
|
||||||
|
#else
|
||||||
|
# error "need at least one notifcation system. please rerun ./configure"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* configuration parameters
|
* configuration parameters
|
||||||
*/
|
*/
|
||||||
@ -158,7 +168,7 @@ add_logcat(const char *name, int priority)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!strcmp("scarce", name)) {
|
if (!strcmp("scarce", name)) {
|
||||||
settings.log_level = LOG_WARNING;
|
settings.log_level = LOG_ERR;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,29 +374,24 @@ struct pipemsg {
|
|||||||
* writeable again
|
* writeable again
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
pipe_writey(lua_State *L, struct observance *observance) {
|
pipe_writey(lua_State *L, int fd, void *extra) {
|
||||||
struct pipemsg *pm = (struct pipemsg *) observance->extra;
|
struct pipemsg *pm = (struct pipemsg *) extra;
|
||||||
int len = write(observance->fd, pm->text + pm->pos, pm->tlen - pm->pos);
|
int len = write(fd, pm->text + pm->pos, pm->tlen - pm->pos);
|
||||||
|
bool do_close = false;
|
||||||
pm->pos += len;
|
pm->pos += len;
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
logstring("Normal", "broken pipe.");
|
logstring("Normal", "broken pipe.");
|
||||||
nonobserve_fd(observance->fd);
|
do_close = true;
|
||||||
} else if (pm->pos >= pm->tlen) {
|
} else if (pm->pos >= pm->tlen) {
|
||||||
logstring("Debug", "finished pipe.");
|
logstring("Debug", "finished pipe.");
|
||||||
nonobserve_fd(observance->fd);
|
do_close = true;
|
||||||
|
}
|
||||||
|
if (do_close) {
|
||||||
|
close(fd);
|
||||||
|
free(pm->text);
|
||||||
|
free(extra);
|
||||||
|
unobserve_fd(fd);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
pipe_tidy(struct observance *observance)
|
|
||||||
{
|
|
||||||
struct pipemsg *pm = (struct pipemsg *) observance->extra;
|
|
||||||
close(observance->fd);
|
|
||||||
free(pm->text);
|
|
||||||
free(pm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -696,6 +701,7 @@ l_exec(lua_State *L)
|
|||||||
len = write(pipefd[1], pipe_text, tlen);
|
len = write(pipefd[1], pipe_text, tlen);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
logstring("Normal", "immediatly broken pipe.");
|
logstring("Normal", "immediatly broken pipe.");
|
||||||
|
close(pipefd[0]);
|
||||||
}
|
}
|
||||||
if (len == tlen) {
|
if (len == tlen) {
|
||||||
/* usual and best case, the pipe accepted all input -> close */
|
/* usual and best case, the pipe accepted all input -> close */
|
||||||
@ -703,13 +709,14 @@ l_exec(lua_State *L)
|
|||||||
logstring("Exec", "one-sweeped pipe");
|
logstring("Exec", "one-sweeped pipe");
|
||||||
} else {
|
} else {
|
||||||
struct pipemsg *pm;
|
struct pipemsg *pm;
|
||||||
logstring("Exec", "adding pipe observance");
|
logstring("Exec", "adding pipe observer");
|
||||||
pm = s_calloc(1, sizeof(struct pipemsg));
|
pm = s_calloc(1, sizeof(struct pipemsg));
|
||||||
pm->text = s_strdup(pipe_text);
|
pm->text = s_strdup(pipe_text);
|
||||||
pm->tlen = tlen;
|
pm->tlen = tlen;
|
||||||
pm->pos = len;
|
pm->pos = len;
|
||||||
observe_fd(pipefd[1], NULL, pipe_writey, pipe_tidy, pm);
|
observe_fd(pipefd[1], NULL, pipe_writey, pm);
|
||||||
}
|
}
|
||||||
|
close(pipefd[0]);
|
||||||
}
|
}
|
||||||
free(argv);
|
free(argv);
|
||||||
lua_pushnumber(L, pid);
|
lua_pushnumber(L, pid);
|
||||||
@ -890,7 +897,6 @@ l_configure(lua_State *L)
|
|||||||
if (!settings.log_file) {
|
if (!settings.log_file) {
|
||||||
settings.log_syslog = true;
|
settings.log_syslog = true;
|
||||||
}
|
}
|
||||||
// XXX
|
|
||||||
logstring("Debug", "daemonizing now.");
|
logstring("Debug", "daemonizing now.");
|
||||||
if (daemon(0, 0)) {
|
if (daemon(0, 0)) {
|
||||||
logstring("Error", "Failed to daemonize");
|
logstring("Error", "Failed to daemonize");
|
||||||
@ -921,6 +927,7 @@ l_configure(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const luaL_reg lsyncdlib[] = {
|
static const luaL_reg lsyncdlib[] = {
|
||||||
{"addtoclock", l_addtoclock },
|
{"addtoclock", l_addtoclock },
|
||||||
{"clockbefore", l_clockbefore },
|
{"clockbefore", l_clockbefore },
|
||||||
@ -945,13 +952,13 @@ static const luaL_reg lsyncdlib[] = {
|
|||||||
* Dummy variable whos address is used as the cores index in the lua registry
|
* Dummy variable whos address is used as the cores index in the lua registry
|
||||||
* to the lua runners function table in the lua registry.
|
* to the lua runners function table in the lua registry.
|
||||||
*/
|
*/
|
||||||
static int runner = 0;
|
static int runner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dummy variable whos address is used as the cores index n the lua registry
|
* Dummy variable whos address is used as the cores index n the lua registry
|
||||||
* to the lua runners error handler.
|
* to the lua runners error handler.
|
||||||
*/
|
*/
|
||||||
static int callError = 0;
|
static int callError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pushes a function from the runner on the stack.
|
* Pushes a function from the runner on the stack.
|
||||||
@ -976,12 +983,38 @@ load_runner_func(lua_State *L,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An observer to be called when a file descritor becomes
|
||||||
|
* read-ready or write-ready.
|
||||||
|
*/
|
||||||
|
struct observer {
|
||||||
|
/**
|
||||||
|
* The file descriptor to observe.
|
||||||
|
*/
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to call when read becomes ready.
|
||||||
|
*/
|
||||||
|
void (*ready)(lua_State *L, int fd, void *extra);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to call when write becomes ready.
|
||||||
|
*/
|
||||||
|
void (*writey)(lua_State *L, int fd, void *extra);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extra tokens to pass to the functions-
|
||||||
|
*/
|
||||||
|
void *extra;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of file descriptor watches.
|
* List of file descriptor watches.
|
||||||
*/
|
*/
|
||||||
static struct observance * observances = NULL;
|
static struct observer * observers = NULL;
|
||||||
static int observances_len = 0;
|
static int observers_len = 0;
|
||||||
static int observances_size = 0;
|
static int observers_size = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of file descriptors to unobserve.
|
* List of file descriptors to unobserve.
|
||||||
@ -989,14 +1022,14 @@ static int observances_size = 0;
|
|||||||
* not be altered, thus unobserve stores here the
|
* not be altered, thus unobserve stores here the
|
||||||
* actions that will be delayed.
|
* actions that will be delayed.
|
||||||
*/
|
*/
|
||||||
static int *nonobservances = NULL;
|
static int *unobservers = NULL;
|
||||||
static int nonobservances_len = 0;
|
static int unobservers_len = 0;
|
||||||
static int nonobservances_size = 0;
|
static int unobservers_size = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* true while the observances list is being handled.
|
* true while the observers list is being handled.
|
||||||
*/
|
*/
|
||||||
static bool observance_action = false;
|
static bool observer_action = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core watches a filedescriptor to become ready,
|
* Core watches a filedescriptor to become ready,
|
||||||
@ -1004,88 +1037,83 @@ static bool observance_action = false;
|
|||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
observe_fd(int fd,
|
observe_fd(int fd,
|
||||||
void (*ready) (lua_State *L, struct observance *observance),
|
void (*ready)(lua_State *L, int fd, void *extra),
|
||||||
void (*writey)(lua_State *L, struct observance *observance),
|
void (*writey)(lua_State *L, int fd, void *extra),
|
||||||
void (*tidy) (struct observance *observance),
|
void *extra)
|
||||||
void *extra)
|
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
if (observance_action) {
|
if (observer_action) {
|
||||||
// TODO
|
// TODO
|
||||||
logstring("Error",
|
logstring("Error",
|
||||||
"Adding observance in ready/writey handlers not yet supported");
|
"Adding observers in ready/writey handlers not yet supported");
|
||||||
exit(-1); // ERRNO
|
exit(-1); // ERRNO
|
||||||
}
|
}
|
||||||
|
|
||||||
if (observances_len + 1 > observances_size) {
|
if (observers_len + 1 > observers_size) {
|
||||||
observances_size = observances_len + 1;
|
observers_size = observers_len + 1;
|
||||||
observances = s_realloc(observances,
|
observers = s_realloc(observers,
|
||||||
observances_size * sizeof(struct observance));
|
observers_size * sizeof(struct observer));
|
||||||
}
|
}
|
||||||
for(pos = 0; pos < observances_len; pos++) {
|
for(pos = 0; pos < observers_len; pos++) {
|
||||||
if (observances[pos].fd <= fd) {
|
if (observers[pos].fd <= fd) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (observances[pos].fd == fd) {
|
if (observers[pos].fd == fd) {
|
||||||
logstring("Error",
|
logstring("Error",
|
||||||
"Observing already an observed file descriptor.");
|
"Observing already an observed file descriptor.");
|
||||||
exit(-1); // ERRNO
|
exit(-1); // ERRNO
|
||||||
}
|
}
|
||||||
memmove(observances + pos + 1, observances + pos,
|
memmove(observers + pos + 1, observers + pos,
|
||||||
(observances_len - pos) * (sizeof(struct observance)));
|
(observers_len - pos) * (sizeof(struct observer)));
|
||||||
|
|
||||||
observances_len++;
|
observers_len++;
|
||||||
observances[pos].fd = fd;
|
observers[pos].fd = fd;
|
||||||
observances[pos].ready = ready;
|
observers[pos].ready = ready;
|
||||||
observances[pos].writey = writey;
|
observers[pos].writey = writey;
|
||||||
observances[pos].tidy = tidy;
|
observers[pos].extra = extra;
|
||||||
observances[pos].extra = extra;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes core no longer watch fd.
|
* Makes core no longer watch fd.
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
nonobserve_fd(int fd)
|
unobserve_fd(int fd)
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
if (observance_action) {
|
if (observer_action) {
|
||||||
/* this function is called through a ready/writey handler
|
/* this function is called through a ready/writey handler
|
||||||
* while the core works through the observances list, thus
|
* while the core works through the observer list, thus
|
||||||
* it does not alter the list, but stores this actions
|
* it does not alter the list, but stores this actions
|
||||||
* on a stack
|
* on a stack
|
||||||
*/
|
*/
|
||||||
nonobservances_len++;
|
unobservers_len++;
|
||||||
if (nonobservances_len > nonobservances_size) {
|
if (unobservers_len > unobservers_size) {
|
||||||
nonobservances_size = nonobservances_len;
|
unobservers_size = unobservers_len;
|
||||||
nonobservances = s_realloc(nonobservances,
|
unobservers = s_realloc(unobservers,
|
||||||
nonobservances_size * sizeof(int));
|
unobservers_size * sizeof(int));
|
||||||
}
|
}
|
||||||
nonobservances[nonobservances_len - 1] = fd;
|
unobservers[unobservers_len - 1] = fd;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* looks for the fd */
|
/* looks for the fd */
|
||||||
for(pos = 0; pos < observances_len; pos++) {
|
for(pos = 0; pos < observers_len; pos++) {
|
||||||
if (observances[pos].fd == fd) {
|
if (observers[pos].fd == fd) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos >= observances_len) {
|
if (pos >= observers_len) {
|
||||||
logstring("Error",
|
logstring("Error",
|
||||||
"internal fail, not observed file descriptor in nonobserve_fd()");
|
"internal fail, not observer file descriptor in unobserve");
|
||||||
exit(-1); //ERRNO
|
exit(-1); //ERRNO
|
||||||
}
|
}
|
||||||
|
|
||||||
if (observances[pos].tidy) {
|
|
||||||
observances[pos].tidy(observances + pos);
|
|
||||||
}
|
|
||||||
/* and moves the list down */
|
/* and moves the list down */
|
||||||
memmove(observances + pos, observances + pos + 1,
|
memmove(observers + pos, observers + pos + 1,
|
||||||
(observances_len - pos) * (sizeof(struct observance)));
|
(observers_len - pos) * (sizeof(struct observer)));
|
||||||
observances_len--;
|
observers_len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1146,52 +1174,52 @@ masterloop(lua_State *L)
|
|||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_ZERO(&wfds);
|
FD_ZERO(&wfds);
|
||||||
|
|
||||||
for(pi = 0; pi < observances_len; pi++) {
|
for(pi = 0; pi < observers_len; pi++) {
|
||||||
int fd = observances[pi].fd;
|
int fd = observers[pi].fd;
|
||||||
if (observances[pi].ready) {
|
if (observers[pi].ready) {
|
||||||
FD_SET(fd, &rfds);
|
FD_SET(fd, &rfds);
|
||||||
}
|
}
|
||||||
if (observances[pi].writey) {
|
if (observers[pi].writey) {
|
||||||
FD_SET(fd, &wfds);
|
FD_SET(fd, &wfds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the great select */
|
/* the great select */
|
||||||
pr = pselect(
|
pr = pselect(
|
||||||
observances[observances_len - 1].fd + 1,
|
observers[observers_len - 1].fd + 1,
|
||||||
&rfds, &wfds, NULL,
|
&rfds, &wfds, NULL,
|
||||||
have_alarm ? &tv : NULL, &sigset);
|
have_alarm ? &tv : NULL, &sigset);
|
||||||
|
|
||||||
if (pr >= 0) {
|
if (pr >= 0) {
|
||||||
/* walks through the observances calling ready/writey fds */
|
/* walks through the observers calling ready/writey fds */
|
||||||
observance_action = true;
|
observer_action = true;
|
||||||
for(pi = 0; pi < observances_len; pi++) {
|
for(pi = 0; pi < observers_len; pi++) {
|
||||||
struct observance *obs = observances + pi;
|
int fd = observers[pi].fd;
|
||||||
int fd = obs->fd;
|
void *extra = observers[pi].extra;
|
||||||
if (hup || term) {
|
if (hup || term) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (obs->ready && FD_ISSET(fd, &rfds)) {
|
if (observers[pi].ready && FD_ISSET(fd, &rfds)) {
|
||||||
obs->ready(L, obs);
|
observers[pi].ready(L, fd, extra);
|
||||||
}
|
}
|
||||||
if (hup || term) {
|
if (hup || term) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nonobservances_len > 0 &&
|
if (unobservers_len > 0 &&
|
||||||
nonobservances[nonobservances_len - 1] == fd) {
|
unobservers[unobservers_len - 1] == fd) {
|
||||||
/* ready() nonobserved itself */
|
/* ready() unobserved itself */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (obs->writey && FD_ISSET(fd, &wfds)) {
|
if (observers[pi].writey && FD_ISSET(fd, &wfds)) {
|
||||||
obs->writey(L, obs);
|
observers[pi].writey(L, fd, extra);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
observance_action = false;
|
observer_action = false;
|
||||||
/* work through delayed unobserve_fd() calls */
|
/* work through delayed unobserve_fd() calls */
|
||||||
for (pi = 0; pi < nonobservances_len; pi++) {
|
for (pi = 0; pi < unobservers_len; pi++) {
|
||||||
nonobserve_fd(nonobservances[pi]);
|
unobserve_fd(unobservers[pi]);
|
||||||
}
|
}
|
||||||
nonobservances_len = 0;
|
unobservers_len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1287,7 +1315,6 @@ main1(int argc, char *argv[])
|
|||||||
/* prepares logging early */
|
/* prepares logging early */
|
||||||
int i = 1;
|
int i = 1;
|
||||||
add_logcat("Normal", LOG_NOTICE);
|
add_logcat("Normal", LOG_NOTICE);
|
||||||
add_logcat("Warn", LOG_WARNING);
|
|
||||||
add_logcat("Error", LOG_ERR);
|
add_logcat("Error", LOG_ERR);
|
||||||
while (i < argc) {
|
while (i < argc) {
|
||||||
if (strcmp(argv[i], "-log") && strcmp(argv[i], "--log")) {
|
if (strcmp(argv[i], "-log") && strcmp(argv[i], "--log")) {
|
||||||
@ -1511,19 +1538,6 @@ main1(int argc, char *argv[])
|
|||||||
masterloop(L);
|
masterloop(L);
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
{
|
|
||||||
/* close/frees observances */
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < observances_len; i++) {
|
|
||||||
struct observance *obs = observances + i;
|
|
||||||
if (obs->tidy) {
|
|
||||||
obs->tidy(obs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
observances_len = 0;
|
|
||||||
nonobservances_len = 0;
|
|
||||||
observance_action = false;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
/* frees logging categories */
|
/* frees logging categories */
|
||||||
int ci;
|
int ci;
|
||||||
@ -1552,6 +1566,7 @@ main1(int argc, char *argv[])
|
|||||||
settings.log_level = 0,
|
settings.log_level = 0,
|
||||||
settings.nodaemon = false,
|
settings.nodaemon = false,
|
||||||
|
|
||||||
|
close_inotify();
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
38
lsyncd.h
38
lsyncd.h
@ -103,43 +103,23 @@ extern void non_block_fd(int fd);
|
|||||||
/* Sets the close-on-exit flag for a file descriptor. */
|
/* Sets the close-on-exit flag for a file descriptor. */
|
||||||
extern void close_exec_fd(int fd);
|
extern void close_exec_fd(int fd);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An observance calls functions when a file descritor becomes
|
|
||||||
* read-ready or write-ready.
|
|
||||||
*/
|
|
||||||
struct observance {
|
|
||||||
/* The file descriptor observed. */
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
/* Function to call when read becomes ready. */
|
|
||||||
void (*ready)(lua_State *L, struct observance *observance);
|
|
||||||
|
|
||||||
/* Function to call when write becomes ready. */
|
|
||||||
void (*writey)(lua_State *L, struct observance *observance);
|
|
||||||
|
|
||||||
/* Function that tidies up, closes fd, frees extra data. etc. */
|
|
||||||
void (*tidy)(struct observance *observance);
|
|
||||||
|
|
||||||
/* Extra tokens to pass to the functions */
|
|
||||||
void *extra;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* makes the core to observe a file descriptor */
|
/* makes the core to observe a file descriptor */
|
||||||
extern void
|
extern void observe_fd(
|
||||||
observe_fd(int fd,
|
int fd,
|
||||||
void (*ready) (lua_State *L, struct observance *observance),
|
void (*ready)(lua_State *L, int fd, void *extra),
|
||||||
void (*writey)(lua_State *L, struct observance *observance),
|
void (*writey)(lua_State *L, int fd, void *extra),
|
||||||
void (*tidy) (struct observance *observance),
|
void *extra);
|
||||||
void *extra);
|
|
||||||
|
|
||||||
/* stops the core to observe a file descriptor */
|
/* stops the core to observe a file descriptor */
|
||||||
extern void nonobserve_fd(int fd);
|
extern void unobserve_fd(int fd);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
* inotify
|
* inotify
|
||||||
*/
|
*/
|
||||||
extern void register_inotify(lua_State *L);
|
extern void register_inotify(lua_State *L);
|
||||||
extern void open_inotify(lua_State *L);
|
extern void open_inotify(lua_State *L);
|
||||||
|
extern void close_inotify();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
89
lsyncd.lua
89
lsyncd.lua
@ -1402,8 +1402,11 @@ local Syncs = (function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- loads a default value for an option if not existent
|
-- loads a default value for an option if not existent
|
||||||
|
if not settings then
|
||||||
|
settings = {}
|
||||||
|
end
|
||||||
local defaultValues = {
|
local defaultValues = {
|
||||||
'action',
|
'action',
|
||||||
'collapse',
|
'collapse',
|
||||||
'collapseTable',
|
'collapseTable',
|
||||||
'collect',
|
'collect',
|
||||||
@ -1464,7 +1467,7 @@ end
|
|||||||
-- So lsyncd can work with other notifications mechanisms just
|
-- So lsyncd can work with other notifications mechanisms just
|
||||||
-- by changing this.
|
-- by changing this.
|
||||||
--
|
--
|
||||||
local Inotifies = (function()
|
local Inotify = (function()
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- A list indexed by inotifies watch descriptor yielding the
|
-- A list indexed by inotifies watch descriptor yielding the
|
||||||
@ -1514,7 +1517,7 @@ local Inotifies = (function()
|
|||||||
--
|
--
|
||||||
local function addWatch(path, recurse, raiseSync, raiseTime)
|
local function addWatch(path, recurse, raiseSync, raiseTime)
|
||||||
log("Function",
|
log("Function",
|
||||||
"Inotifies.addWatch(",path,", ",recurse,", ",
|
"Inotify.addWatch(",path,", ",recurse,", ",
|
||||||
raiseSync,", ",raiseTime,")")
|
raiseSync,", ",raiseTime,")")
|
||||||
|
|
||||||
-- lets the core registers watch with the kernel
|
-- lets the core registers watch with the kernel
|
||||||
@ -1574,8 +1577,8 @@ local Inotifies = (function()
|
|||||||
--
|
--
|
||||||
local function addSync(sync, root)
|
local function addSync(sync, root)
|
||||||
if syncRoots[sync] then
|
if syncRoots[sync] then
|
||||||
error("internal fail, duplicate sync in Inotifies()")
|
error("internal fail, duplicate sync in Inotify.addSync()")
|
||||||
end
|
end
|
||||||
syncRoots[sync] = root
|
syncRoots[sync] = root
|
||||||
addWatch(root, true)
|
addWatch(root, true)
|
||||||
end
|
end
|
||||||
@ -1957,7 +1960,7 @@ local StatusFile = (function()
|
|||||||
f:write("\n")
|
f:write("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
Inotifies.statusReport(f)
|
Inotify.statusReport(f)
|
||||||
f:close()
|
f:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2072,7 +2075,6 @@ USAGE:
|
|||||||
lsyncd [OPTIONS] -rsyncssh [SOURCE] [HOST] [TARGETDIR]
|
lsyncd [OPTIONS] -rsyncssh [SOURCE] [HOST] [TARGETDIR]
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
-dryrun Subprocesses are not actually invoked.
|
|
||||||
-help Shows this
|
-help Shows this
|
||||||
-log all Logs everything (debug)
|
-log all Logs everything (debug)
|
||||||
-log scarce Logs errors only
|
-log scarce Logs errors only
|
||||||
@ -2109,10 +2111,6 @@ function runner.configure(args)
|
|||||||
-- a list of all valid --options
|
-- a list of all valid --options
|
||||||
local options = {
|
local options = {
|
||||||
-- log is handled by core already.
|
-- log is handled by core already.
|
||||||
dryrun =
|
|
||||||
{0, function()
|
|
||||||
clSettings.dryrun=true
|
|
||||||
end},
|
|
||||||
log =
|
log =
|
||||||
{1, nil},
|
{1, nil},
|
||||||
logfile =
|
logfile =
|
||||||
@ -2283,7 +2281,7 @@ function runner.initialize()
|
|||||||
|
|
||||||
-- runs through the Syncs created by users
|
-- runs through the Syncs created by users
|
||||||
for _, s in Syncs.iwalk() do
|
for _, s in Syncs.iwalk() do
|
||||||
Inotifies.addSync(s, s.source)
|
Inotify.addSync(s, s.source)
|
||||||
if s.config.init then
|
if s.config.init then
|
||||||
InletControl.setSync(s)
|
InletControl.setSync(s)
|
||||||
s.config.init(Inlet)
|
s.config.init(Inlet)
|
||||||
@ -2409,42 +2407,13 @@ function spawn(agent, binary, ...)
|
|||||||
if lsyncdStatus == "fade" then
|
if lsyncdStatus == "fade" then
|
||||||
log("Normal", "ignored spawn processs since status fading")
|
log("Normal", "ignored spawn processs since status fading")
|
||||||
end
|
end
|
||||||
if not settings.dryrun then
|
local pid = lsyncd.exec(binary, ...)
|
||||||
local pid = lsyncd.exec(binary, ...)
|
if pid and pid > 0 then
|
||||||
if pid and pid > 0 then
|
|
||||||
local sync = InletControl.getSync()
|
|
||||||
local delay = InletControl.getDelay(agent)
|
|
||||||
if delay then
|
|
||||||
delay.status = "active"
|
|
||||||
sync.processes[pid] = delay
|
|
||||||
else
|
|
||||||
local dlist = InletControl.getDelayList(agent)
|
|
||||||
if not dlist then
|
|
||||||
error("spawning with an unknown agent", 2)
|
|
||||||
end
|
|
||||||
for k, d in pairs(dlist) do
|
|
||||||
if type(k) == "number" then
|
|
||||||
d.status = "active"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
sync.processes[pid] = dlist
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local a1, a2 = ...
|
|
||||||
if a1 ~= "<" then
|
|
||||||
log("Normal", "would call ", binary, " ", table.concat({...}, " "))
|
|
||||||
else
|
|
||||||
local aa = {...}
|
|
||||||
table.remove(aa, 1)
|
|
||||||
table.remove(aa, 1)
|
|
||||||
log("Normal", "would call ", binary, " ", table.concat(aa, " "),
|
|
||||||
"\ninput pipe <\n", a2)
|
|
||||||
end
|
|
||||||
local sync = InletControl.getSync()
|
local sync = InletControl.getSync()
|
||||||
local delay = InletControl.getDelay(agent)
|
local delay = InletControl.getDelay(agent)
|
||||||
if delay then
|
if delay then
|
||||||
sync:removeDelay(delay)
|
delay.status = "active"
|
||||||
|
sync.processes[pid] = delay
|
||||||
else
|
else
|
||||||
local dlist = InletControl.getDelayList(agent)
|
local dlist = InletControl.getDelayList(agent)
|
||||||
if not dlist then
|
if not dlist then
|
||||||
@ -2452,9 +2421,10 @@ function spawn(agent, binary, ...)
|
|||||||
end
|
end
|
||||||
for k, d in pairs(dlist) do
|
for k, d in pairs(dlist) do
|
||||||
if type(k) == "number" then
|
if type(k) == "number" then
|
||||||
sync:removeDelay(d)
|
d.status = "active"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
sync.processes[pid] = dlist
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -2466,6 +2436,7 @@ function spawnShell(agent, command, ...)
|
|||||||
return spawn(agent, "/bin/sh", "-c", command, "/bin/sh", ...)
|
return spawn(agent, "/bin/sh", "-c", command, "/bin/sh", ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- Comfort routine also for user.
|
-- Comfort routine also for user.
|
||||||
-- Returns true if 'String' starts with 'Start'
|
-- Returns true if 'String' starts with 'Start'
|
||||||
@ -2483,27 +2454,6 @@ function string.ends(String,End)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
------
|
|
||||||
-- Replaces default os.execute with a warning message,
|
|
||||||
-- doing the execute nevertheless, if not in dryrun.
|
|
||||||
--
|
|
||||||
local os_execute = os.execute
|
|
||||||
os.execute = function(...)
|
|
||||||
log("Warn", "using os.execute makes Lsyncd splutter, use spawn() instead.")
|
|
||||||
if not settings.dryrun then
|
|
||||||
os_execute(...)
|
|
||||||
else
|
|
||||||
log("Normal", "would os.execute ", table.concat({...}, " "))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----
|
|
||||||
-- An empty settings table optionally for the config to
|
|
||||||
-- expand instead of replace.
|
|
||||||
--
|
|
||||||
settings = {}
|
|
||||||
|
|
||||||
|
|
||||||
--============================================================================
|
--============================================================================
|
||||||
-- Lsyncd default settings
|
-- Lsyncd default settings
|
||||||
--============================================================================
|
--============================================================================
|
||||||
@ -2927,11 +2877,6 @@ default = {
|
|||||||
return rc
|
return rc
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-----
|
|
||||||
-- default Delay
|
|
||||||
--
|
|
||||||
delay = 5,
|
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- called on (re)initalizing of Lsyncd.
|
-- called on (re)initalizing of Lsyncd.
|
||||||
--
|
--
|
||||||
|
Loading…
Reference in New Issue
Block a user