Name Last Update
debian Loading commit data...
example Loading commit data...
man/man1 Loading commit data...
.gitignore Loading commit data...
GNUmakefile Loading commit data...
LICENSE Loading commit data...
README Loading commit data...
common.h Loading commit data...
config.h Loading commit data...
fileutils.c Loading commit data...
fileutils.h Loading commit data...
main.c Loading commit data...
main.h Loading commit data...
malloc.c Loading commit data...
malloc.h Loading commit data...
output.c Loading commit data...
output.h Loading commit data...
sync.c Loading commit data...
sync.h Loading commit data...

0.) Name
1.) Motivation
2.) inotify vs fanotify
3.) How to use
4.) Known issues
5.) Support


0.) Name

Why "clsync"? The first name of the utility was "insync" (due to inotify), but
then I suggested to use "fanotify" instead of "inotify" and utility was been
renamed to "fasync". After that I started to intensively write the program.
However I faced with some problems in "fanotify", so I was have to temporary
fallback to "inotify", then I decided, that the best name is "Runtime Sync" or
"Live Sync", but "rtsync" is a name of some corporation, and "lsync" is busy
by "lsyncd" project (""). So I called it
"clsync", that should be interpreted as "lsync, but on c" due to "lsyncd" that
written on "LUA" and may be used for the same purposes.


1.) Motivation

This utility was been writted for two purposes:
	- for making failover clusters
	- for making backups of them

To do failover cluster I've tried a lot of different solutions, like "simple 
rsync by cron", "glusterfs", "ocfs2 over drbd", "common mirrorable external 
storage", "incron + perl + rsync", "inosync", "lsyncd" and so on. Currently we
are using "lsyncd", "ceph" and "ocfs2 over drbd". However all of this
solutions doesn't arrange me, so I was have to write own utility for this

To do backups we also tried a lot of different solution, and again I was have
to write own utility for this purpose.

The best known (for me) replacement for this utility is "lsyncd", however:
	- It's code is >½ on LUA. There a lot of problems connected with it,
for example:
	    - It's more difficult to maintain the code with ordinary sysadmin.
	    - It really eats 100% CPU sometimes.
	    - It requires LUA libs, that cannot be easily installed to few
of our systems.
	- It's a little buggy. That may be easily fixed for our cases,
but LUA. :(
	- It doesn't support pthread or something like that. It's necessary
to serve huge directories with a lot of containers right.
	- It cannot run rsync for a pack of files. It runs rsync for every
event. :(
	- Sometimes, it's too complex in configuration for our situation.
	- It can't set another event-collecting delay for big files. We don't
want to sync big files (>1GiB) so often as ordinary files.

Sorry, if I'm wrong. Let me know if it is, please :). "lsyncd" - is really
good and useful utility, just it's not appropriate for us.


2.) inotify vs fanotify:

It's said, that fanotify is much better, than inotify. So I started to write 
this program with using of fanotify. However I encountered the problem, that
fanotify was unable to catch some important events at the moment of writing
the program, like "directory creation" or "file deletion". So I switched to
"inotify", leaving the code for "fanotify" in the safety... So, don't use
"fanotify" in this utility ;).


3.) How to use

First of all, I recommend you to look into the "man" ;).

However, well, let's see:

d[13:25:13] [xaionaro@linux ~/clsync]$ ./clsync 
syntax: clsync [options] <watch dir> <action script> [file with rules regexps]
possible options:
        --background              -b
        --pthread                 -p
        --collectdelay            -t
        --commondelay             -w
        --outlistsdir             -d
        --rsync                   -R
        --dontunlinklists         -U
        --bigfilethreshold        -B
        --bigfilecollectdelay     -T
        --verbose                 -v
        --debug                   -D
        --quite                   -q
        --fanotify                -f
        --inotify                 -i
        --label                   -l
        --help                    -h
        --version                 -V

"watch dir"	- what dir to recursively watch for events
"action script"	- path to script, that will be executed to process events
"file with rules regexps" - file with regexps of what files/dirs to watch

Options with "*" requires an argument:

  --background	- daemonize
  --pthread	- use multi-threading
* --collectdelay - delay to collect events for ordinary files/dirs (def: 30)
* --commondelay	- delay in addition for all queues (def: 15)
* --outlistsdir	- path to directory, where clsync should temporary save his
events' lists
  --rsync	- forces to generate list-files for "--include-from" of rsync
  --dontunlinklists - forces to do not delete list-files
* --bigfilethreshold - file size theshold to mark file as big (def: 134217728)
* --bigfilecollectdelay - delay to collect events for big files (def: 1800)
  --verbose	- increases verbosity (doesn't do anything at the moment)
  --debug	- increases debugging output
  --quite	- suppresses errors output
  --fanotify	- uses "fanotify" subsystem instead of "inotify"
  --inotify	- uses "inotify" subsystem instead of "fanotify" (def)
* --label	- sets label of current clsync instance
  --help	- outputs the same info as above
  --version	- outputs version of clsync

Now, let me explain few things:

--pthread - Should be used to watch huge file trees with high dynamics to
remove huge delays to update something due to updating something another

--collectdelay - Is way to aggregate events for ordinary files/dirs. Than this
value greater, the aggrigation will be more effective, but the sync delay will
be higher

--outlistsdir - Enables "sync by list" notification of "action script", but to
sync by list it's required a directory for temporary files (with lists of 
events). So you're aggregation a lot of actions per collect-delay period,
it's need to provide it and set the path to it to this parameter.

--fanotify - Enables "fanotify" subsystem instead of "inotify". However
developing of "fanotify" support was been frozen at the start of this program
life, so "fanotify" doesn't work at the moment. Don't use it :)

--label - May be useful, if you're going to serve different clsync instances
by one action script


As I said, pthread is recommended for file trees with high dynamics to
minimize side-effected delays. However threading code is much more complex,
so the sum of bugs there will be much higher. If you will find some of them,
please mail me, I'll fix it :)

Delays' calculcation:

Ordinary file/dir maximum sync delay = collectdelay + commondelay
Big files maximum sync delay = bigfilecollectdelay + commondelay

Action script:

The clsync with run "action script" every time, when it will want to notify
about requirement of sync. So the "action script" should do this syncing by
this notifications.

The clsync can run "action script" with four ways:
    a.) action_script initialsync label dirpath
    b.) action_script sync label evmask path
    c.) action_script synclist label listpath
    d.) action_script rsynclist label rsynclistpath

In all four cases, clsync passes parameter "label" (the label of current, 
instance, see "--label").
In case "a", clsync asks "action script" to recursively sync the dir
In case 'b', clsync asks "action script" to non-recursively sync the file/dir
"path" due to event of mask "evmask".
In case "c", clsync asks "action script" to non-recursively sync files/dirs
from list in file "listpath".
In case "d", clsync asks "action script" to run "rsync" with parameters
'-aH --delete-before --include-from="rsynclistpath" --exclude "*"'.

Format of list-files:

List-files "consists" from lines (delimited by NL, without CR) of next format:
sync label evmask path

"sync" is always "sync" at the moment. It's supposed to be supported different
commands in this list, but at the moment there's only "sync" supported.
"label" is "label" (see "--label").
"evmask" is mask of the event, why the file/dir should be updated (see below).
"path" is the path of file/dir that should be updated.

Event mask:

Event mask is bitmask sum of events of the file/dir, that were been aggregated
for collect-delay. You can learn that bits in "/usr/include/linux/inotify.h".

Rules file:

Filter riles can be placed into rules-file with one rule per line.

Rule format: [+|-][fd*]regexp

"+" - means include; "-" - means exclude;
"f" - means file;    "d" - means directory; "*" - means all.

For example: -*/[Tt]estdir


Example of usage, that works on my PC is in directory "example". Just run
"" and try to create/modify/delete files/dirs in
"example/testdir/from". All modifications should appear (with some delay) in
directory "example/testdir/to" ;)


First of all, you should install dependencies to compile clsync. As you can
see from GNUmakefile clsync depends only on "glib-2.0", so on debian-like
systems you should execute something like "apt-get install libglib2.0-dev".

Next step is compiling. To compile usually it's enough to execute "make".

Next step in installing. To install usually it's enough to execute
"su -c 'make install'".

Also, debian-users can use my repository to install the clsync:
deb [arth=amd64] unstable main


4.) Known issues

    1.) Doesn't compiles on old systems

	In this case you should compile with command "make onoldsystem"

    2.) Exits with error "Error: Cannot inotify_add_watch() on [...]"

	In this case you should increase "fs.inotify.max_user_watches" value,
	for example with command: sysctl fs.inotify.max_user_watches=26214400


5.) Support

    To get support, you can contact with me this ways:
	- IRC: SSL+UTF-8,xaionaro,xai
	- e-mail: <>, <>, <>
		PGP pubkey: 0x8E30679C


				-- Dmitry Yu Okunev <> 0x8E30679C

P.S.: Sorry for my English and for the code :)