mirror of
https://github.com/octoleo/lsyncd.git
synced 2025-01-06 08:40:44 +00:00
made watch_vector a non-global variable
This commit is contained in:
parent
4150baf455
commit
15f3c9261c
154
lsyncd.c
154
lsyncd.c
@ -40,7 +40,7 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Number of inotifies to read at once from the kernel.
|
||||
* Number of inotifies to read max. at once from the kernel.
|
||||
*/
|
||||
#define INOTIFY_BUF_LEN (64 * (sizeof(struct inotify_event) + 16))
|
||||
|
||||
@ -385,8 +385,6 @@ struct watch_vector {
|
||||
size_t size;
|
||||
size_t len;
|
||||
};
|
||||
struct watch_vector watches_obj = {0, };
|
||||
struct watch_vector *watches = &watches_obj;
|
||||
|
||||
/**
|
||||
* Array of strings of directory names to include.
|
||||
@ -749,11 +747,13 @@ dir_conf_add_target(const struct log *log, struct dir_conf *dir_conf, char *targ
|
||||
/**
|
||||
* Adds a directory on the delays list
|
||||
*
|
||||
* @param watch the index in watches to the directory.
|
||||
* @param alarm times() when the directory should be acted.
|
||||
* @param log logging information
|
||||
* @param watches the watches vector
|
||||
* @param watch the index in watches to the directory
|
||||
* @param alarm times() when the directory should be acted
|
||||
*/
|
||||
bool
|
||||
append_delay(const struct log *log, int watch, clock_t alarm) {
|
||||
append_delay(const struct log *log, struct watch_vector *watches, int watch, clock_t alarm) {
|
||||
printlogf(log, DEBUG, "append delay(%d)", watch);
|
||||
if (watches->data[watch].delayed) {
|
||||
printlogf(log, DEBUG, "ignored since already delayed.", watch);
|
||||
@ -768,9 +768,11 @@ append_delay(const struct log *log, int watch, clock_t alarm) {
|
||||
|
||||
/**
|
||||
* Removes the first entry on the delay list.
|
||||
*
|
||||
* @param watches the watches vector
|
||||
*/
|
||||
void
|
||||
remove_first_delay() {
|
||||
remove_first_delay(struct watch_vector *watches) {
|
||||
int tw = delays->data[0];
|
||||
memmove(delays->data, delays->data + 1, (--delays->len) * sizeof(int));
|
||||
watches->data[tw].delayed = false;
|
||||
@ -974,10 +976,11 @@ action(const struct global_options *opts,
|
||||
/**
|
||||
* Adds a directory to watch.
|
||||
*
|
||||
* @param log logging information.
|
||||
* @param inotify_fd inotify file descriptor.
|
||||
* @param pathname the absolute path of the directory to watch.
|
||||
* @param dirname the name of the directory only (yes this is a bit redudant, but oh well)
|
||||
* @param log logging information
|
||||
* @param watches the vector of watches
|
||||
* @param inotify_fd inotify file descriptor
|
||||
* @param pathname the absolute path of the directory to watch
|
||||
* @param dirname the name of the directory only
|
||||
* @param parent if not -1 the index to the parent directory that is already watched
|
||||
* @param dir_conf the applicateable configuration
|
||||
*
|
||||
@ -985,6 +988,7 @@ action(const struct global_options *opts,
|
||||
*/
|
||||
int
|
||||
add_watch(const struct log *log,
|
||||
struct watch_vector *watches,
|
||||
int inotify_fd,
|
||||
char const * pathname,
|
||||
char const * dirname,
|
||||
@ -1043,11 +1047,15 @@ add_watch(const struct log *log,
|
||||
* strlen(pathname) if successful
|
||||
*/
|
||||
int
|
||||
builddir(char *pathname, int pathsize, int watch, char const * prefix)
|
||||
builddir(char *pathname,
|
||||
int pathsize,
|
||||
struct watch_vector *watches, //TODO remove and change to pointer
|
||||
int watch,
|
||||
char const * prefix)
|
||||
{
|
||||
int len = 0;
|
||||
if (watch == -1) {
|
||||
// When is this called this way???
|
||||
// TODO When is this called this way???
|
||||
char const * p = prefix ? prefix : "";
|
||||
len = strlen(p);
|
||||
if (pathsize <= len) {
|
||||
@ -1064,7 +1072,7 @@ builddir(char *pathname, int pathsize, int watch, char const * prefix)
|
||||
strcpy(pathname, p);
|
||||
} else {
|
||||
// this is some sub dir
|
||||
len = builddir(pathname, pathsize, watches->data[watch].parent, prefix); /* recurse */
|
||||
len = builddir(pathname, pathsize, watches, watches->data[watch].parent, prefix); /* recurse */
|
||||
len += strlen(watches->data[watch].dirname);
|
||||
if (pathsize <= len) {
|
||||
return -1;
|
||||
@ -1093,11 +1101,12 @@ bool
|
||||
buildpath(const struct log *log,
|
||||
char *pathname,
|
||||
int pathsize,
|
||||
struct watch_vector *watches, // TODO remove need
|
||||
int watch,
|
||||
const char *dirname,
|
||||
const char *prefix)
|
||||
{
|
||||
int len = builddir(pathname, pathsize, watch, prefix);
|
||||
int len = builddir(pathname, pathsize, watches, watch, prefix);
|
||||
if (len < 0) {
|
||||
printlogf(log, ERROR, "path too long!");
|
||||
return false;
|
||||
@ -1124,7 +1133,9 @@ buildpath(const struct log *log,
|
||||
* @returns true when all targets were successful.
|
||||
*/
|
||||
bool
|
||||
rsync_dir(const struct global_options *opts, int watch)
|
||||
rsync_dir(const struct global_options *opts,
|
||||
struct watch_vector *watches, // TODO remove
|
||||
int watch)
|
||||
{
|
||||
char pathname[PATH_MAX+1];
|
||||
char destname[PATH_MAX+1];
|
||||
@ -1132,12 +1143,12 @@ rsync_dir(const struct global_options *opts, int watch)
|
||||
char ** target;
|
||||
const struct log *log = &opts->log;
|
||||
|
||||
if (!buildpath(log, pathname, sizeof(pathname), watch, NULL, NULL)) {
|
||||
if (!buildpath(log, pathname, sizeof(pathname), watches, watch, NULL, NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (target = watches->data[watch].dir_conf->targets; *target; target++) {
|
||||
if (!buildpath(log, destname, sizeof(destname), watch, NULL, *target)) {
|
||||
if (!buildpath(log, destname, sizeof(destname), watches, watch, NULL, *target)) {
|
||||
status = false;
|
||||
continue;
|
||||
}
|
||||
@ -1153,29 +1164,31 @@ rsync_dir(const struct global_options *opts, int watch)
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a directory on the delay list.
|
||||
*
|
||||
* Directly calls rsync_dir if delay == 0;
|
||||
* Puts a directory on the delay list OR
|
||||
* directly calls rsync_dir if delay == 0;
|
||||
*
|
||||
* @param watch the index in ir_watches to the directory.
|
||||
* @param alarm times() when the directory handling should be fired.
|
||||
*/
|
||||
void
|
||||
delay_dir(const struct global_options *opts, int watch, clock_t alarm)
|
||||
delay_dir(const struct global_options *opts,
|
||||
struct watch_vector *watches, //TODO remove?
|
||||
int watch,
|
||||
clock_t alarm)
|
||||
{
|
||||
char pathname[PATH_MAX+1];
|
||||
const struct log *log = &opts->log;
|
||||
|
||||
if (opts->delay == 0) {
|
||||
rsync_dir(opts, watch);
|
||||
rsync_dir(opts, watches, watch);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!buildpath(log, pathname, sizeof(pathname), watch, NULL, NULL)) {
|
||||
if (!buildpath(log, pathname, sizeof(pathname), watches, watch, NULL, NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (append_delay(log, watch, alarm)) {
|
||||
if (append_delay(log, watches, watch, alarm)) {
|
||||
printlogf(log, NORMAL, "Putted %s on a delay", pathname);
|
||||
} else {
|
||||
printlogf(log, NORMAL, "Not acted on %s already on delay", pathname);
|
||||
@ -1187,6 +1200,7 @@ delay_dir(const struct global_options *opts, int watch, clock_t alarm)
|
||||
* Puts the directory with all subdirectories on the delay FIFO.
|
||||
*
|
||||
* @param opts global options
|
||||
* @param watches the watch vector
|
||||
* @param inotify_fd inotify file descriptor.
|
||||
* @param dirname The name or absolute path of the directory to watch.
|
||||
* @param parent If not -1, the index in watches to the parent directory already watched.
|
||||
@ -1197,6 +1211,7 @@ delay_dir(const struct global_options *opts, int watch, clock_t alarm)
|
||||
*/
|
||||
int
|
||||
add_dirwatch(const struct global_options *opts,
|
||||
struct watch_vector *watches,
|
||||
int inotify_fd,
|
||||
char const *dirname,
|
||||
int parent,
|
||||
@ -1204,7 +1219,6 @@ add_dirwatch(const struct global_options *opts,
|
||||
{
|
||||
const struct log *log = &opts->log;
|
||||
DIR *d;
|
||||
|
||||
int dw;
|
||||
char pathname[PATH_MAX+1];
|
||||
|
||||
@ -1212,7 +1226,7 @@ add_dirwatch(const struct global_options *opts,
|
||||
dirname,
|
||||
parent >= 0 ? watches->data[parent].dirname : "NULL");
|
||||
|
||||
if (!buildpath(log, pathname, sizeof(pathname), parent, dirname, NULL)) {
|
||||
if (!buildpath(log, pathname, sizeof(pathname), watches, parent, dirname, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1228,13 +1242,13 @@ add_dirwatch(const struct global_options *opts,
|
||||
}
|
||||
|
||||
// watch this directory
|
||||
dw = add_watch(log, inotify_fd, pathname, dirname, parent, dir_conf);
|
||||
dw = add_watch(log, watches, inotify_fd, pathname, dirname, parent, dir_conf);
|
||||
if (dw == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// put this directory on list to be synced ASAP.
|
||||
delay_dir(opts, dw, times(NULL));
|
||||
delay_dir(opts, watches, dw, times(NULL));
|
||||
|
||||
if (strlen(pathname) + strlen(dirname) + 2 > sizeof(pathname)) {
|
||||
printlogf(log, ERROR, "pathname too long %s//%s", pathname, dirname);
|
||||
@ -1263,7 +1277,7 @@ add_dirwatch(const struct global_options *opts,
|
||||
// use traditional means to determine if its a directory.
|
||||
char subdir[PATH_MAX+1];
|
||||
struct stat st;
|
||||
isdir = buildpath(log, subdir, sizeof(subdir), dw, de->d_name, NULL) &&
|
||||
isdir = buildpath(log, subdir, sizeof(subdir), watches, dw, de->d_name, NULL) &&
|
||||
!stat(subdir, &st) &&
|
||||
S_ISDIR(st.st_mode);
|
||||
} else {
|
||||
@ -1273,7 +1287,7 @@ add_dirwatch(const struct global_options *opts,
|
||||
// add watches if its a directory and not . or ..
|
||||
if (isdir && strcmp(de->d_name, "..") && strcmp(de->d_name, ".")) {
|
||||
// recurse into subdir
|
||||
int ndw = add_dirwatch(opts, inotify_fd, de->d_name, dw, dir_conf);
|
||||
int ndw = add_dirwatch(opts, watches, inotify_fd, de->d_name, dw, dir_conf);
|
||||
printlogf(log, NORMAL,
|
||||
"found new directory: %s in %s -- %s",
|
||||
de->d_name, dirname, ndw >= 0 ? "will be synced" : "ignored it");
|
||||
@ -1287,16 +1301,18 @@ add_dirwatch(const struct global_options *opts,
|
||||
/**
|
||||
* Removes a watched dir, including recursevily all subdirs.
|
||||
*
|
||||
* @param opts global options.
|
||||
* @param inotify_fd inotify file descriptor.
|
||||
* @param opts global options
|
||||
* @param watches the watch vector
|
||||
* @param inotify_fd inotify file descriptor
|
||||
* @param name optionally. If not NULL, the directory name
|
||||
* to remove which is a child of parent.
|
||||
* to remove which is a child of parent
|
||||
* @param parent the index to the parent directory of the
|
||||
* directory 'name' to remove, or to be removed
|
||||
* itself if name == NULL.
|
||||
*/
|
||||
bool
|
||||
remove_dirwatch(const struct global_options *opts,
|
||||
struct watch_vector *watches,
|
||||
int inotify_fd,
|
||||
const char * name,
|
||||
int parent)
|
||||
@ -1328,7 +1344,7 @@ remove_dirwatch(const struct global_options *opts,
|
||||
int i;
|
||||
for (i = 0; i < watches->len; i++) {
|
||||
if (watches->data[i].wd >= 0 && watches->data[i].parent == dw) {
|
||||
remove_dirwatch(opts, inotify_fd, NULL, i);
|
||||
remove_dirwatch(opts, watches, inotify_fd, NULL, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1359,14 +1375,16 @@ remove_dirwatch(const struct global_options *opts,
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the matching dw entry from wd (watch descriptor), and return
|
||||
* the offset in the table.
|
||||
* Find the matching dw entry containing a watch descriptor
|
||||
* and return its offset.
|
||||
*
|
||||
* @param watches the watch vector
|
||||
* @param wd the wd (watch descriptor) given by inotify
|
||||
*
|
||||
* @param wd The wd (watch descriptor) given by inotify
|
||||
* @return offset, or -1 if not found
|
||||
*/
|
||||
int
|
||||
get_watch_offset(int wd) {
|
||||
get_watch_offset(const struct watch_vector *watches, int wd) {
|
||||
int i;
|
||||
for (i = 0; i < watches->len; i++) {
|
||||
if (watches->data[i].wd == wd) {
|
||||
@ -1380,12 +1398,14 @@ get_watch_offset(int wd) {
|
||||
* Handles an inotify event.
|
||||
*
|
||||
* @param opts global options
|
||||
* @param watches the watch vector
|
||||
* @param inotify_fd inotify file descriptor
|
||||
* @param event the event to handle
|
||||
* @param alarm times() moment when it should fire
|
||||
*/
|
||||
bool
|
||||
handle_event(const struct global_options *opts,
|
||||
handle_event(const struct global_options *opts,
|
||||
struct watch_vector *watches,
|
||||
int inotify_fd,
|
||||
struct inotify_event *event,
|
||||
clock_t alarm)
|
||||
@ -1426,7 +1446,7 @@ handle_event(const struct global_options *opts,
|
||||
}
|
||||
}
|
||||
|
||||
watch = get_watch_offset(event->wd);
|
||||
watch = get_watch_offset(watches, event->wd);
|
||||
if (watch == -1) {
|
||||
// this can happen in case of data moving faster than lsyncd can monitor it.
|
||||
printlogf(log, NORMAL,
|
||||
@ -1436,12 +1456,12 @@ handle_event(const struct global_options *opts,
|
||||
|
||||
// in case of a new directory create new watches
|
||||
if (((IN_CREATE | IN_MOVED_TO) & event->mask) && (IN_ISDIR & event->mask)) {
|
||||
subwatch = add_dirwatch(opts, inotify_fd, event->name, watch, watches->data[watch].dir_conf);
|
||||
subwatch = add_dirwatch(opts, watches, inotify_fd, event->name, watch, watches->data[watch].dir_conf);
|
||||
}
|
||||
|
||||
// in case of a removed directory remove watches
|
||||
if (((IN_DELETE | IN_MOVED_FROM) & event->mask) && (IN_ISDIR & event->mask)) {
|
||||
remove_dirwatch(opts, inotify_fd, event->name, watch);
|
||||
remove_dirwatch(opts, watches, inotify_fd, event->name, watch);
|
||||
}
|
||||
|
||||
// call the binary if something changed
|
||||
@ -1449,7 +1469,7 @@ handle_event(const struct global_options *opts,
|
||||
IN_MOVED_TO | IN_MOVED_FROM) & event->mask
|
||||
) {
|
||||
printlogf(log, NORMAL, "received event %s:%s.", masktext, event->name);
|
||||
delay_dir(opts, watch, alarm);
|
||||
delay_dir(opts, watches, watch, alarm);
|
||||
} else {
|
||||
printlogf(log, DEBUG, "... ignored this event.");
|
||||
}
|
||||
@ -1460,14 +1480,16 @@ handle_event(const struct global_options *opts,
|
||||
* The control loop waiting for inotify events.
|
||||
*
|
||||
* @param opts global options
|
||||
* @param watches the watch vector
|
||||
* @param inotify_fd inotify file descriptor
|
||||
*/
|
||||
bool
|
||||
master_loop(const struct global_options *opts,
|
||||
struct watch_vector *watches,
|
||||
int inotify_fd)
|
||||
{
|
||||
char buf[INOTIFY_BUF_LEN];
|
||||
int len, i = 0;
|
||||
int len;
|
||||
long clocks_per_sec = sysconf(_SC_CLK_TCK);
|
||||
|
||||
struct timeval tv;
|
||||
@ -1488,7 +1510,7 @@ master_loop(const struct global_options *opts,
|
||||
|
||||
while (keep_going) {
|
||||
int do_read;
|
||||
if (delays->len > 0 && time_after(times(NULL), watches->data[delays->data[0]].alarm)) {
|
||||
if (delays->len > 0 && time_after_eq(times(NULL), watches->data[delays->data[0]].alarm)) {
|
||||
// there is a delay that wants to be handled already
|
||||
// do not read from inotify_fd and jump directly to delay handling
|
||||
printlogf(log, DEBUG, "immediately handling delayed entries");
|
||||
@ -1540,21 +1562,24 @@ master_loop(const struct global_options *opts,
|
||||
now = times(NULL);
|
||||
alarm = now + opts->delay * clocks_per_sec;
|
||||
|
||||
// first handle all events that might have happened
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
struct inotify_event *event = (struct inotify_event *) &buf[i];
|
||||
handle_event(opts, inotify_fd, event, alarm);
|
||||
i += sizeof(struct inotify_event) + event->len;
|
||||
{
|
||||
// first handle all events read.
|
||||
int i = 0;
|
||||
while (i < len) {
|
||||
struct inotify_event *event = (struct inotify_event *) &buf[i];
|
||||
handle_event(opts, watches, inotify_fd, event, alarm);
|
||||
i += sizeof(struct inotify_event) + event->len;
|
||||
}
|
||||
}
|
||||
|
||||
// Then pull of directories from the top of the delay stack
|
||||
// Then take of directories from the top of the delay FIFO
|
||||
// until one item is found whose expiry time has not yet come
|
||||
// or the stack is empty.
|
||||
while (delays->len > 0 && time_after(times(NULL), watches->data[delays->data[0]].alarm)) {
|
||||
// or the stack is empty. Using now time - times(NULL) - everytime
|
||||
// again as time may progresses while handling delayed entries.
|
||||
while (delays->len > 0 && time_after_eq(times(NULL), watches->data[delays->data[0]].alarm)) {
|
||||
printlogf(log, DEBUG, "time for %d arrived.", delays->data[0]);
|
||||
rsync_dir(opts, delays->data[0]);
|
||||
remove_first_delay();
|
||||
rsync_dir(opts, watches, delays->data[0]);
|
||||
remove_first_delay(watches);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2213,6 +2238,7 @@ main(int argc, char **argv)
|
||||
{
|
||||
struct global_options opts = {{0,}}; // global options
|
||||
struct log *log = &opts.log;
|
||||
struct watch_vector watches = {0, }; // all watches
|
||||
int inotify_fd; // inotify file descriptor
|
||||
|
||||
openlog("lsyncd", LOG_CONS | LOG_PID, LOG_DAEMON);
|
||||
@ -2248,15 +2274,15 @@ main(int argc, char **argv)
|
||||
write_pidfile(log, opts.pidfile);
|
||||
}
|
||||
|
||||
watches->size = 2;
|
||||
watches->data = s_calloc(log, watches->size, sizeof(struct watch));
|
||||
watches.size = 2;
|
||||
watches.data = s_calloc(log, watches.size, sizeof(struct watch));
|
||||
|
||||
{
|
||||
// add all watches
|
||||
int i;
|
||||
for (i = 0; i < opts.dir_conf_n; i++) {
|
||||
printlogf(log, NORMAL, "watching %s", opts.dir_confs[i].source);
|
||||
add_dirwatch(&opts, inotify_fd, opts.dir_confs[i].source, -1, &opts.dir_confs[i]);
|
||||
add_dirwatch(&opts, &watches, inotify_fd, opts.dir_confs[i].source, -1, &opts.dir_confs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2266,8 +2292,8 @@ main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < delays->len; i++) {
|
||||
watches->data[i].delayed = false;
|
||||
watches->data[i].alarm = 0;
|
||||
watches.data[i].delayed = false;
|
||||
watches.data[i].alarm = 0;
|
||||
}
|
||||
delays->len = 0;
|
||||
}
|
||||
@ -2295,11 +2321,11 @@ main(int argc, char **argv)
|
||||
|
||||
printlogf(log, NORMAL,
|
||||
"--- Entering normal operation with [%d] monitored directories ---",
|
||||
watches->len);
|
||||
watches.len);
|
||||
|
||||
signal(SIGTERM, catch_alarm);
|
||||
|
||||
master_loop(&opts, inotify_fd);
|
||||
master_loop(&opts, &watches, inotify_fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user