mirror of
https://github.com/octoleo/lsyncd.git
synced 2025-01-06 08:40:44 +00:00
configureable inotifies
This commit is contained in:
parent
c2354ede16
commit
ac5357ea5e
@ -120,6 +120,12 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
|
||||
|
||||
<para>With a <option><callopts></option> node you can control the arguments lsyncd will call the <binary> (rsync) with. Each child node will specify one argument. <option> specifies a literal argument. Only %r will be replaced with 'r' when rsycnd is supposed to work recursive (on startup of lsyncd) or 'd' on normal operations. <exclude-file> will be replaced with <option>--exclude-from [FILE]</option> if an <exclude-from> file is specified. <source> will be replaced the source directory to sync from. <destination> will be replace to the target to sync to. Default arguments are <option>-lt%r --delete {--exclude-from [FILE]} [SOURCE] [DIRECTORY]</option>.</para>
|
||||
<programlisting> <callopts>
|
||||
<para>With a <option><inotify></option> node you can control the inotify events lsyncd will register to. Each event is configured by a <event> child node and its attribute 'id'. The following events may be registered: ACCESS,ATTRIB,CLOSE_WRITE,CLOSE_NOWRITE,CREATE,DELETE,DELETE_SELF,MODIFY,MOVE_SELF,MOVED_FROM,MOVED_TO,OPEN. If the inotify node is omitted the following events are registered by default: IN_ATTRIB,IN_CLOSE_WRITE,IN_CREATE,IN_DELETE,IN_DELETE_SELF,IN_MOVED_FROM,IN_MOVED_TO,IN_DONT_FOLLOW,IN_ONLYDIR.</para>
|
||||
<programlisting> <inotify>
|
||||
<event id="MOVED_TO"/>
|
||||
<event id="DELETE"/>
|
||||
</inotify></programlisting>
|
||||
|
||||
<option text="-lt%r"/>
|
||||
<option text="--delete"/>
|
||||
<exclude-file/>
|
||||
@ -132,8 +138,8 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
|
||||
|
||||
<refsect2 id="directory">
|
||||
<title>DIRECTORIES</title>
|
||||
<para>With <option><directory></option> nodes arbitrarily many sources to be watched can be specified. Within a <directory> entry you can again specify a <option><binary></option>, <option><exclude-from></option> or a <option><callopt></option> node which will override global settings just for this source. See SETTINGS for details on this options.</para>
|
||||
<para> The mandatory <option><source></option> node specifies with the parameter "path" the directory to watch and sync. (once in a while something is mandatory. Also at least one <option><target;></option> node has to specified where to sync to. This has to be a format accepted by rsync.</para>
|
||||
+ <para>With <option><directory></option> nodes arbitrarily many sources to be watched can be specified. Within a <directory> entry you can again specify a <option><binary></option>, <option><exclude-from></option>, <option><callopt></option> or a <option><inotify></option> node which will override global settings just for this source. See SETTINGS for details on this options.</para>
|
||||
+ <para> The mandatory <option><source></option> node specifies with the paramater "path" the directory to watch and sync. (once in a while something is mandatory. Also at least one <option><target;></option> node has to specified where to sync to. This has to be a format accepted by rsync.</para>
|
||||
<programlisting> <directory>
|
||||
<source path="/absolute/path/to/source"/>
|
||||
<target path="desthost::module/"/>
|
||||
|
123
lsyncd.c
123
lsyncd.c
@ -59,7 +59,10 @@
|
||||
*/
|
||||
#define DEFAULT_BINARY "/usr/bin/rsync"
|
||||
#define DEFAULT_CONF_FILENAME "/etc/lsyncd.conf.xml"
|
||||
|
||||
const uint32_t standard_event_mask =
|
||||
IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE |
|
||||
IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM |
|
||||
IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR;
|
||||
/**
|
||||
* Macros to compare times() values
|
||||
* (borrowed from linux/jiffies.h)
|
||||
@ -168,6 +171,11 @@ struct dir_conf {
|
||||
*/
|
||||
struct call_option * callopts;
|
||||
|
||||
/**
|
||||
* bitmask of inotify events to watch (defaults to global default setting)
|
||||
*/
|
||||
uint32_t event_mask;
|
||||
|
||||
/**
|
||||
* the exclude-file to pass to rsync (defaults to global default setting)
|
||||
* TODO, Currently ignored!
|
||||
@ -284,6 +292,11 @@ struct global_options {
|
||||
* Global Option: this binary is used if no other specified in dir_conf.
|
||||
*/
|
||||
char *default_binary;
|
||||
|
||||
/**
|
||||
* Global Option: default bitmask of inotify events to react upon.
|
||||
*/
|
||||
uint32_t default_event_mask;
|
||||
|
||||
/**
|
||||
* Global Option: default exclude file
|
||||
@ -832,6 +845,8 @@ reset_options(struct global_options *opts) {
|
||||
s_free(opts->default_binary);
|
||||
}
|
||||
opts->default_binary = DEFAULT_BINARY;
|
||||
|
||||
opts->default_event_mask = standard_event_mask;
|
||||
|
||||
if (opts->default_exclude_file) {
|
||||
s_free(opts->default_exclude_file);
|
||||
@ -1185,7 +1200,7 @@ action(const struct global_options *opts,
|
||||
/**
|
||||
* Adds a directory to watch.
|
||||
*
|
||||
* @param log logging information
|
||||
* @param opts global options
|
||||
* @param watches the vector of watches
|
||||
* @param inotify_fd inotify file descriptor
|
||||
* @param pathname the absolute path of the directory to watch
|
||||
@ -1196,7 +1211,7 @@ action(const struct global_options *opts,
|
||||
* @return the watches of the new dir, NULL on error
|
||||
*/
|
||||
struct watch *
|
||||
add_watch(const struct log *log,
|
||||
add_watch(const struct global_options *opts,
|
||||
struct watch_vector *watches,
|
||||
int inotify_fd,
|
||||
char const *pathname,
|
||||
@ -1204,14 +1219,13 @@ add_watch(const struct log *log,
|
||||
struct watch *parent,
|
||||
struct dir_conf *dir_conf)
|
||||
{
|
||||
int wd; // kernels inotify descriptor
|
||||
int wi; // index to insert this watch into the watch vector
|
||||
struct watch *w; // the new watch
|
||||
const struct log *log = &opts->log; // loginfo shortcut
|
||||
int wd; // kernels inotify descriptor
|
||||
int wi; // index to insert this watch into the watch vector
|
||||
struct watch *w; // the new watch
|
||||
|
||||
wd = inotify_add_watch(inotify_fd, pathname,
|
||||
IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE |
|
||||
IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM |
|
||||
IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR);
|
||||
wd = inotify_add_watch(inotify_fd, pathname,
|
||||
dir_conf->event_mask ? dir_conf->event_mask : opts->default_event_mask);
|
||||
|
||||
if (wd == -1) {
|
||||
printlogf(log, ERROR, "Cannot add watch %s (%d:%s)",
|
||||
@ -1409,6 +1423,30 @@ delay_or_act_dir(const struct global_options *opts,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the inotify event mask for the specified event text.
|
||||
*
|
||||
* @param text the name of the event to look up
|
||||
*
|
||||
* @return the inotify event mask or 0 if the mask name is unknown.
|
||||
*/
|
||||
int
|
||||
event_text_to_mask(char * text)
|
||||
{
|
||||
int mask = 0;
|
||||
struct inotify_mask_text *p;
|
||||
|
||||
for (p = mask_texts; p->mask; p++) {
|
||||
if (!strcmp(p->text, text)) {
|
||||
mask = p->mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a directory including all subdirectories to watch.
|
||||
* Puts the directory with all subdirectories on the delay FIFO.
|
||||
@ -1460,7 +1498,7 @@ add_dirwatch(const struct global_options *opts,
|
||||
}
|
||||
|
||||
// watch this directory
|
||||
w = add_watch(log, watches, inotify_fd, pathname, dirname, parent, dir_conf);
|
||||
w = add_watch(opts, watches, inotify_fd, pathname, dirname, parent, dir_conf);
|
||||
if (!w) {
|
||||
return NULL;
|
||||
}
|
||||
@ -1975,6 +2013,44 @@ parse_callopts(struct global_options *opts, xmlNodePtr node) {
|
||||
return asw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses <inotify>
|
||||
*/
|
||||
uint32_t
|
||||
parse_inotify(xmlNodePtr node) {
|
||||
xmlNodePtr dnode;
|
||||
xmlChar *xc;
|
||||
uint32_t mask = 0;
|
||||
int id = 0;
|
||||
for (dnode = node->children; dnode; dnode = dnode->next) {
|
||||
if (dnode->type != XML_ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
if (!xmlStrcmp(dnode->name, BAD_CAST "event")) {
|
||||
xc = xmlGetProp(dnode, BAD_CAST "id");
|
||||
if (xc == NULL) {
|
||||
printlogf(NULL, ERROR, "error in config file: attribute id missing from <event>\n");
|
||||
exit(LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
id = event_text_to_mask((char*) xc);
|
||||
if (!id) {
|
||||
printlogf(NULL, ERROR, "error in config file: attribute id of <event>: \"%s\" not known.\n", (char*) xc);
|
||||
exit(LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
mask |= id;
|
||||
} else {
|
||||
printlogf(NULL, ERROR, "error in config file: unknown node in <inotify> \"%s\"\n", dnode->name);
|
||||
exit(LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
}
|
||||
if (!mask) {
|
||||
printlogf(NULL, ERROR, "error in config file: no valid <event> node in <inotify>\n");
|
||||
exit(LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses <diretory>
|
||||
*/
|
||||
@ -2013,6 +2089,12 @@ parse_directory(struct global_options *opts, xmlNodePtr node) {
|
||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
dc->binary = s_strdup(NULL, (char *) xc, "xml binary");
|
||||
} else if (!xmlStrcmp(dnode->name, BAD_CAST "callopts")) {
|
||||
if (dc->callopts) {
|
||||
printlogf(NULL, ERROR, "error in config file: there is more than one <callopts> in a <directory>\n");
|
||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
dc->callopts = parse_callopts(opts, dnode);
|
||||
} else if (!xmlStrcmp(dnode->name, BAD_CAST "exclude-from")) {
|
||||
xc = xmlGetProp(dnode, BAD_CAST "filename");
|
||||
if (xc == NULL) {
|
||||
@ -2020,14 +2102,13 @@ parse_directory(struct global_options *opts, xmlNodePtr node) {
|
||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
dc->exclude_file = s_strdup(NULL, (char *) xc, "xml exclude");
|
||||
} else if (!xmlStrcmp(dnode->name, BAD_CAST "callopts")) {
|
||||
if (dc->callopts) {
|
||||
printlogf(NULL, ERROR, "error in config file: there is more than one <callopts> in a <directory>\n");
|
||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
dc->callopts = parse_callopts(opts, dnode);
|
||||
} else if (!xmlStrcmp(dnode->name, BAD_CAST "inotify")) {
|
||||
if (dc->event_mask) {
|
||||
fprintf(stderr, "error in config file: there is more than one <inotify> in a <directory>\n");
|
||||
exit(LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
dc->event_mask = parse_inotify(dnode);
|
||||
} else {
|
||||
// TODO missing sourcespecific exclude files?
|
||||
printlogf(NULL, ERROR, "error in config file: unknown node in <directory> \"%s\"\n", dnode->name);
|
||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
@ -2082,6 +2163,12 @@ parse_settings(struct global_options *opts, xmlNodePtr node) {
|
||||
terminate(NULL, LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
opts->default_exclude_file = s_strdup(NULL, (char *) xc, "xml default-exclude-file");
|
||||
} else if (!xmlStrcmp(snode->name, BAD_CAST "inotify")) {
|
||||
if (opts->default_event_mask) {
|
||||
printlogf(NULL, ERROR, "error in config file: there is more than one <inotify> in a <directory>\n");
|
||||
exit(LSYNCD_BADCONFIGFILE);
|
||||
}
|
||||
opts->default_event_mask = parse_inotify(snode);
|
||||
} else if (!xmlStrcmp(snode->name, BAD_CAST "logfile")) {
|
||||
xc = xmlGetProp(snode, BAD_CAST "filename");
|
||||
if (xc == NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user