Storage and beyond


libionotify is a IO notification library based on inotify. It allows application not to care about low-level inotify interface, but just provide a set of callbacks for existing events. Currently read, write, create and remove events are used. When multiple events form a mask, callback is invoked if at least one of them matches.


#include "notify.h"

static int notify_create_callback(struct notify_root *r, struct callback *c,
		struct notify_event *e)
	return notify_add_object(r, e->path, e->len, 0, 0);

static int notify_delete_callback(struct notify_root *r, struct callback *c,
		struct notify_event *e)
	return notify_remove_object(r, e->path, e->len);

static struct callback notify_callbacks[] = {
	{ .mask = CREATE_EVENT, .callback = notify_create_callback, .data = NULL, },
	{ .mask = DELETE_EVENT, .callback = notify_delete_callback, .data = NULL, },

int main()
	r = notify_init(num, notify_callbacks, sizeof(notify_callbacks)/sizeof(struct callback));
	if (!r)
		return err;

	err = notify_add_object(r, root_dir, strlen(root_dir), 0, 0);
	if (err)
		return err;

	while (1)

This code sets a watch on given root directory and then add or remove watches for all objects created or removed in the root directory itself and its subdirs.
struct notify_event used in callbacks is defined in notify.h header:

struct notify_event
        char                    *path;
        unsigned int            len;
        unsigned int            hash;
        unsigned int            event;
        unsigned int            cookie;
        __u64                   id;
        __u64                   ino;

path is a string containing full path based on provided root directory
len its length
hash – jenkins hash of the originated path (i.e. if new object is created or removed in dir, this contains hash of the directory path, and if read or write event happend, it contains hash of the filename itself)
event – what event has happend: read, write, create or remove. Definitions can be found in notify.h header. This can be a mask of multiple events.
cookie is used to determine move event, but it is unused now.
id and ino are private parameters provided to notify_add_object()

One could store private data in each callback structure and then use it in provided function.

Function declarations.

int notify_remove_object(struct notify_root *r, char *path, unsigned int len);
int notify_add_object(struct notify_root *r, char *path, unsigned int len, __u64 id, __u64 ino);

int notify_thread_add(struct notify_root *r);
void notify_thread_remove(struct notify_root *r);

struct notify_root *notify_init(int thread_num, struct callback *cbs, int callnum);
void notify_exit(struct notify_root *r);

First two are used to add and remove new objects from the watched list with some additional private data (id and ino). The last two are used to initialize and cleanup notification control structure. notify_thread_add() and notify_thread_remove() are used to add remove notification reading events on behalf of which callbacks are executed. Initial number of such threads is provided via notify_init() parameter.

Source code is always available from archive.