mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-09-21 19:49:02 +00:00
Fixing HUP behaviour (reported and original path by Pavel Gulchouck)
This commit is contained in:
parent
ebe69f981d
commit
d222ef82f9
@ -1,3 +1,9 @@
|
|||||||
|
??-??-????: 2.1.0
|
||||||
|
fix: no longer stops syslogging on HUP signals
|
||||||
|
fix: OSX event watcher no longer misses moves into and out of the watch tree
|
||||||
|
fix: not refinding a relative path to the config file in case of HUP.
|
||||||
|
change: Lsyncd now remembers the absolute path of its config file during HUPs
|
||||||
|
|
||||||
25-08-2011: 2.0.5
|
25-08-2011: 2.0.5
|
||||||
fix: Lsyncd will now terminate if it inotify watching exceeds
|
fix: Lsyncd will now terminate if it inotify watching exceeds
|
||||||
its preset limit.
|
its preset limit.
|
||||||
|
144
lsyncd.c
144
lsyncd.c
@ -97,6 +97,12 @@ struct settings settings = {
|
|||||||
*/
|
*/
|
||||||
static bool is_daemon = false;
|
static bool is_daemon = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The config file loaded by Lsyncd.
|
||||||
|
* Global so it is retained during HUPs
|
||||||
|
*/
|
||||||
|
char * lsyncd_config_file = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* False after first time Lsyncd started up.
|
* False after first time Lsyncd started up.
|
||||||
*
|
*
|
||||||
@ -149,6 +155,26 @@ sig_handler(int sig)
|
|||||||
static struct tms *dummy_tms = &_dummy_tms;
|
static struct tms *dummy_tms = &_dummy_tms;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
| Returns the absolute path of path.
|
||||||
|
| This is a wrapper to various C-Library differences.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
get_realpath(const char * rpath) {
|
||||||
|
// uses c-library to get the absolute path
|
||||||
|
#ifdef __GLIBC__
|
||||||
|
// in case of GLIBC the task is easy.
|
||||||
|
return realpath(path, NULL);
|
||||||
|
#else
|
||||||
|
# warning having to use old style realpath()
|
||||||
|
// otherwise less so and requires PATH_MAX limit.
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
char *asw = realpath(rpath, buf);
|
||||||
|
if (!asw) return NULL;
|
||||||
|
return s_strdup(asw);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Logging
|
* Logging
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -580,7 +606,7 @@ observe_fd(int fd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes core no longer watch fd.
|
* Makes the core to no longer watch a filedescriptor.
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
nonobserve_fd(int fd)
|
nonobserve_fd(int fd)
|
||||||
@ -920,28 +946,17 @@ l_exec(lua_State *L)
|
|||||||
/**
|
/**
|
||||||
* Converts a relative directory path to an absolute.
|
* Converts a relative directory path to an absolute.
|
||||||
*
|
*
|
||||||
* @param dir a relative path to directory
|
* @param dir: a relative path to directory
|
||||||
* @return absolute path of directory
|
* @return the absolute path of directory
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
l_realdir(lua_State *L)
|
l_realdir(lua_State *L)
|
||||||
{
|
{
|
||||||
luaL_Buffer b;
|
luaL_Buffer b;
|
||||||
char *cbuf;
|
|
||||||
const char *rdir = luaL_checkstring(L, 1);
|
const char *rdir = luaL_checkstring(L, 1);
|
||||||
|
char *adir = get_realpath(rdir);
|
||||||
|
|
||||||
// uses c-library to get the absolute path
|
if (!adir) {
|
||||||
#ifdef __GLIBC__
|
|
||||||
cbuf = realpath(rdir, NULL);
|
|
||||||
#else
|
|
||||||
# warning having to use old style realpath()
|
|
||||||
{
|
|
||||||
char *ccbuf = s_calloc(sizeof(char), PATH_MAX);
|
|
||||||
cbuf = realpath(rdir, ccbuf);
|
|
||||||
if (!cbuf) free(ccbuf);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!cbuf) {
|
|
||||||
printlogf(L, "Error", "failure getting absolute path of [%s]", rdir);
|
printlogf(L, "Error", "failure getting absolute path of [%s]", rdir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -949,25 +964,28 @@ l_realdir(lua_State *L)
|
|||||||
{
|
{
|
||||||
// makes sure its a directory
|
// makes sure its a directory
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(cbuf, &st)) {
|
if (stat(adir, &st)) {
|
||||||
printlogf(L, "Error",
|
printlogf(L, "Error",
|
||||||
"cannot get absolute path of dir '%s': %s", rdir, strerror(errno));
|
"cannot get absolute path of dir '%s': %s", rdir, strerror(errno));
|
||||||
|
free(adir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISDIR(st.st_mode)) {
|
if (!S_ISDIR(st.st_mode)) {
|
||||||
printlogf(L, "Error",
|
printlogf(L, "Error",
|
||||||
"cannot get absolute path of dir '%s': is not a directory", rdir);
|
"cannot get absolute path of dir '%s': is not a directory", rdir);
|
||||||
free(cbuf);
|
free(adir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns absolute path with a concated '/'
|
// returns absolute path with a concated '/'
|
||||||
luaL_buffinit(L, &b);
|
luaL_buffinit(L, &b);
|
||||||
luaL_addstring(&b, cbuf);
|
luaL_addstring(&b, adir);
|
||||||
luaL_addchar(&b, '/');
|
luaL_addchar(&b, '/');
|
||||||
luaL_pushresult(&b);
|
luaL_pushresult(&b);
|
||||||
free(cbuf);
|
|
||||||
|
free(adir);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1083,28 +1101,33 @@ l_configure(lua_State *L)
|
|||||||
// from this on log to configurated log end instead of
|
// from this on log to configurated log end instead of
|
||||||
// stdout/stderr
|
// stdout/stderr
|
||||||
first_time = false;
|
first_time = false;
|
||||||
if (settings.log_syslog || !settings.log_file) {
|
|
||||||
|
if (!settings.nodaemon && !settings.log_file) {
|
||||||
|
settings.log_syslog = true;
|
||||||
const char * log_ident = settings.log_ident ? settings.log_ident : "lsyncd";
|
const char * log_ident = settings.log_ident ? settings.log_ident : "lsyncd";
|
||||||
openlog(log_ident, 0, settings.log_facility);
|
openlog(log_ident, 0, settings.log_facility);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!settings.nodaemon && !is_daemon) {
|
if (!settings.nodaemon && !is_daemon) {
|
||||||
if (!settings.log_file) settings.log_syslog = true;
|
|
||||||
logstring("Debug", "daemonizing now.");
|
logstring("Debug", "daemonizing now.");
|
||||||
daemonize(L);
|
daemonize(L);
|
||||||
}
|
}
|
||||||
if (settings.pidfile) {
|
|
||||||
write_pidfile(L, settings.pidfile);
|
if (settings.pidfile) write_pidfile(L, settings.pidfile);
|
||||||
}
|
|
||||||
} else if (!strcmp(command, "nodaemon")) {
|
} else if (!strcmp(command, "nodaemon")) {
|
||||||
settings.nodaemon = true;
|
settings.nodaemon = true;
|
||||||
|
|
||||||
} else if (!strcmp(command, "logfile")) {
|
} else if (!strcmp(command, "logfile")) {
|
||||||
const char * file = luaL_checkstring(L, 2);
|
const char * file = luaL_checkstring(L, 2);
|
||||||
if (settings.log_file) free(settings.log_file);
|
if (settings.log_file) free(settings.log_file);
|
||||||
settings.log_file = s_strdup(file);
|
settings.log_file = s_strdup(file);
|
||||||
|
|
||||||
} else if (!strcmp(command, "pidfile")) {
|
} else if (!strcmp(command, "pidfile")) {
|
||||||
const char * file = luaL_checkstring(L, 2);
|
const char * file = luaL_checkstring(L, 2);
|
||||||
if (settings.pidfile) free(settings.pidfile);
|
if (settings.pidfile) free(settings.pidfile);
|
||||||
settings.pidfile = s_strdup(file);
|
settings.pidfile = s_strdup(file);
|
||||||
|
|
||||||
} else if (!strcmp(command, "logfacility")) {
|
} else if (!strcmp(command, "logfacility")) {
|
||||||
if (lua_isstring(L, 2)) {
|
if (lua_isstring(L, 2)) {
|
||||||
const char * fname = luaL_checkstring(L, 2);
|
const char * fname = luaL_checkstring(L, 2);
|
||||||
@ -1123,16 +1146,17 @@ l_configure(lua_State *L)
|
|||||||
printlogf(L, "Error", "Logging facility must be a number or string");
|
printlogf(L, "Error", "Logging facility must be a number or string");
|
||||||
exit(-1); // ERRNO;
|
exit(-1); // ERRNO;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (!strcmp(command, "logident")) {
|
} else if (!strcmp(command, "logident")) {
|
||||||
const char * ident = luaL_checkstring(L, 2);
|
const char * ident = luaL_checkstring(L, 2);
|
||||||
if (settings.log_ident) free(settings.log_ident);
|
if (settings.log_ident) free(settings.log_ident);
|
||||||
settings.log_ident = s_strdup(ident);
|
settings.log_ident = s_strdup(ident);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
printlogf(L, "Error",
|
printlogf(L, "Error", "Internal error, unknown parameter in l_configure(%s)", command);
|
||||||
"Internal error, unknown parameter in l_configure(%s)",
|
|
||||||
command);
|
|
||||||
exit(-1); //ERRNO
|
exit(-1); //ERRNO
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1516,12 +1540,8 @@ masterloop(lua_State *L)
|
|||||||
|
|
||||||
for(pi = 0; pi < observances_len; pi++) {
|
for(pi = 0; pi < observances_len; pi++) {
|
||||||
struct observance *obs = observances + pi;
|
struct observance *obs = observances + pi;
|
||||||
if (obs->ready) {
|
if (obs->ready) FD_SET(obs->fd, &rfds);
|
||||||
FD_SET(obs->fd, &rfds);
|
if (obs->writey) FD_SET(obs->fd, &wfds);
|
||||||
}
|
|
||||||
if (obs->writey) {
|
|
||||||
FD_SET(obs->fd, &wfds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!observances_len) {
|
if (!observances_len) {
|
||||||
@ -1623,7 +1643,8 @@ masterloop(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The effective main.
|
* The effective main for one run.
|
||||||
|
* HUP signals may cause several runs of the one main.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
main1(int argc, char *argv[])
|
main1(int argc, char *argv[])
|
||||||
@ -1633,7 +1654,6 @@ main1(int argc, char *argv[])
|
|||||||
|
|
||||||
// scripts
|
// scripts
|
||||||
char * lsyncd_runner_file = NULL;
|
char * lsyncd_runner_file = NULL;
|
||||||
char * lsyncd_config_file = NULL;
|
|
||||||
|
|
||||||
int argp = 1;
|
int argp = 1;
|
||||||
|
|
||||||
@ -1814,34 +1834,43 @@ main1(int argc, char *argv[])
|
|||||||
if (lua_pcall(L, 2, 1, -3)) {
|
if (lua_pcall(L, 2, 1, -3)) {
|
||||||
exit(-1); // ERRNO
|
exit(-1); // ERRNO
|
||||||
}
|
}
|
||||||
s = lua_tostring(L, -1);
|
if (first_time) {
|
||||||
if (s) {
|
// If not first time, simply retains the config file given
|
||||||
lsyncd_config_file = s_strdup(s);
|
s = lua_tostring(L, -1);
|
||||||
|
if (s) lsyncd_config_file = s_strdup(s);
|
||||||
}
|
}
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checks existence of the config file
|
||||||
if (lsyncd_config_file) {
|
if (lsyncd_config_file) {
|
||||||
// checks existence of the config file
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
// gets the absolute path to the config file
|
||||||
|
// so in case of HUPing the daemon, it finds it again
|
||||||
|
char * apath = get_realpath(lsyncd_config_file);
|
||||||
|
if (!apath) {
|
||||||
|
printlogf(L, "Error", "Cannot find config file at '%s'.", lsyncd_config_file);
|
||||||
|
exit(-1); // ERRNO
|
||||||
|
}
|
||||||
|
free(lsyncd_config_file);
|
||||||
|
lsyncd_config_file = apath;
|
||||||
|
|
||||||
if (stat(lsyncd_config_file, &st)) {
|
if (stat(lsyncd_config_file, &st)) {
|
||||||
printlogf(L, "Error",
|
printlogf(L, "Error", "Cannot find config file at '%s'.", lsyncd_config_file);
|
||||||
"Cannot find config file at '%s'.",
|
|
||||||
lsyncd_config_file);
|
|
||||||
exit(-1); // ERRNO
|
exit(-1); // ERRNO
|
||||||
}
|
}
|
||||||
|
|
||||||
// loads and executes the config file
|
// loads and executes the config file
|
||||||
if (luaL_loadfile(L, lsyncd_config_file)) {
|
if (luaL_loadfile(L, lsyncd_config_file)) {
|
||||||
printlogf(L, "Error",
|
printlogf(L, "Error",
|
||||||
"error loading %s: %s",
|
"error loading %s: %s", lsyncd_config_file, lua_tostring(L, -1));
|
||||||
lsyncd_config_file, lua_tostring(L, -1));
|
|
||||||
exit(-1); // ERRNO
|
exit(-1); // ERRNO
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
|
if (lua_pcall(L, 0, LUA_MULTRET, 0)) {
|
||||||
printlogf(L, "Error",
|
printlogf(L, "Error",
|
||||||
"error preparing %s: %s",
|
"error preparing %s: %s", lsyncd_config_file, lua_tostring(L, -1));
|
||||||
lsyncd_config_file, lua_tostring(L, -1));
|
|
||||||
exit(-1); // ERRNO
|
exit(-1); // ERRNO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1872,9 +1901,7 @@ main1(int argc, char *argv[])
|
|||||||
* lua code will set configuration and add watches */
|
* lua code will set configuration and add watches */
|
||||||
load_runner_func(L, "initialize");
|
load_runner_func(L, "initialize");
|
||||||
lua_pushboolean(L, first_time);
|
lua_pushboolean(L, first_time);
|
||||||
if (lua_pcall(L, 1, 0, -3)) {
|
if (lua_pcall(L, 1, 0, -3)) exit(-1); // ERRNO
|
||||||
exit(-1); // ERRNO
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1907,24 +1934,7 @@ main1(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lsyncd_config_file) {
|
|
||||||
free(lsyncd_config_file);
|
|
||||||
lsyncd_config_file = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// resets settings to default.
|
|
||||||
if (settings.log_file) {
|
|
||||||
free(settings.log_file);
|
|
||||||
settings.log_file = NULL;
|
|
||||||
}
|
|
||||||
settings.log_syslog = false;
|
|
||||||
if (settings.log_ident) {
|
|
||||||
free(settings.log_ident);
|
|
||||||
settings.log_ident = NULL;
|
|
||||||
}
|
|
||||||
settings.log_facility = LOG_USER;
|
|
||||||
settings.log_level = LOG_NOTICE;
|
|
||||||
settings.nodaemon = false;
|
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user