Linux: Replacing dnotify With inotify

Submitted by Jeremy
on September 16, 2004 - 8:36am

John McCutchan released version 0.9 of his inotify patch against the 2.6.8.1 kernel [story]. His detailed explanation of the patch begins:

"Inotify is designed as a replacement for dnotify. The key difference's are that inotify does not require the file to be opened to watch it, when you are watching something with inotify it can go away (if path is unmounted) and you will be sent an event telling you it is gone and events are delivered over a fd not by using signals."

Robert Love [interview] gave the patch a vote of confidence, "I want to expand on why dnotify is awful and why inotify is a great replacement, because dnotify's limitations are really showing up on modern desktop systems." He then praised inotify's use of file descriptors, especially how it will work even with removable devices, unlike dnotify. Making reference to Al Viro's disapproval of an earlier version, Robert added, "I have been going over the code for awhile now, and it looks good. I would really like to hear Al's opinion so we can move on fixing any possible issues that he has."


From: John McCutchan [email blocked]
To:  linux-kernel [email blocked]
Subject: [RFC][PATCH] inotify 0.9
Date: 	Wed, 15 Sep 2004 11:52:45 -0400

Hello,

I am releasing a new version of inotify. Attached is a patch for
2.6.8.1.

I am interested in getting inotify included in the mm tree. 

Inotify is designed as a replacement for dnotify. The key difference's
are that inotify does not require the file to be opened to watch it,
when you are watching something with inotify it can go away (if path
is unmounted) and you will be sent an event telling you it is gone and
events are delivered over a fd not by using signals.

New in this version:
Driver now supports reading more than one event at a time
Bump maximum number of watches per device from 64 to 8192
Bump maximum number of queued events per device from 64 to 256

--COMPLEXITY--

I have been asked what the complexity of inotify is. Inotify has
2 path codes where complexity could be an issue:

Adding a watcher to a device
	This code has to check if the inode is already being watched 
	by the device, this is O(1) since the maximum number of 
	devices is limited to 8.


Removing a watch from a device
	This code has to do a search of all watches on the device to
	find the watch descriptor that is being asked to remove.
	This involves a linear search, but should not really be an issue
	because it is limited to 8192 entries. If this does turn in to
	a concern, I would replace the list of watches on the device
	with a sorted binary tree, so that the search could be done
	very quickly.


The calls to inotify from the VFS code has a complexity of O(1) so
inotify does not affect the speed of VFS operations.

--MEMORY USAGE--

The inotify data structures are light weight:

inotify watch is 40 bytes
inotify device is 68 bytes
inotify event is 272 bytes

So assuming a device has 8192 watches, the structures are only going
to consume 320KB of memory. With a maximum number of 8 devices allowed
to exist at a time, this is still only 2.5 MB

Each device can also have 256 events queued at a time, which sums to
68KB per device. And only .5 MB if all devices are opened and have
a full event queue.

So approximately 3 MB of memory are used in the rare case of 
everything open and full.

Each inotify watch pins the inode of a directory/file in memory,
the size of an inode is different per file system but lets assume
that it is 512 byes. 

So assuming the maximum number of global watches are active, this would
pin down 32 MB of inodes in the inode cache. Again not a problem
on a modern system. 

On smaller systems, the maximum watches / events could be lowered
to provide a smaller foot print.

Older release notes:
I am resubmitting inotify for comments and review. Inotify has
changed drastically from the earlier proposal that Al Viro did not
approve of. There is no longer any use of (device number, inode number)
pairs. Please give this version of inotify a fresh view.


Inotify is a character device that when opened offers 2 IOCTL's.
(It actually has 4 but the other 2 are used for debugging)

INOTIFY_WATCH:
        Which takes a path and event mask and returns a unique 
        (to the instance of the driver) integer (wd [watcher descriptor]
        from here on) that is a 1:1 mapping to the path passed. 
        What happens is inotify gets the inode (and ref's the inode)
        for the path and adds a inotify_watcher structure to the inodes
        list of watchers. If this instance of the driver is already
        watching the path, the event mask will be updated and
        the original wd will be returned.

INOTIFY_IGNORE:
        Which takes an integer (that you got from INOTIFY_WATCH) 
        representing a wd that you are not interested in watching
        anymore. This will:

        send an IGNORE event to the device
        remove the inotify_watcher structure from the device and 
        from the inode and unref the inode.
        

After you are watching 1 or more paths, you can read from the fd
and get events. The events are struct inotify_event. If you are
watching a directory and something happens to a file in the directory
the event will contain the filename (just the filename not the full
path).

Aside from the inotify character device driver. 
The changes to the kernel are very minor. 

The first change is adding calls to inotify_inode_queue_event and
inotify_dentry_parent_queue_event from the various vfs functions. This
is identical to dnotify.

The second change is more serious, it adds a call to
inotify_super_block_umount
inside generic_shutdown_superblock. What inotify_super_block_umount does
is:

find all of the inodes that are on the super block being shut down,
sends each watcher on each inode the UNMOUNT and IGNORED event
removes the watcher structures from each instance of the device driver 
and each inode.
unref's the inode.

I have tested this code on my system for over three weeks now and have
not had problems. I would appreciate design review, code review and
testing.

John

[patch]


From: Robert Love [email blocked] Subject: Re: [RFC][PATCH] inotify 0.9 Date: Wed, 15 Sep 2004 14:00:09 -0400 On Wed, 2004-09-15 at 11:52 -0400, John McCutchan wrote: > I am interested in getting inotify included in the mm tree. > > Inotify is designed as a replacement for dnotify. The key difference's > are that inotify does not require the file to be opened to watch it, > when you are watching something with inotify it can go away (if path > is unmounted) and you will be sent an event telling you it is gone and > events are delivered over a fd not by using signals. I want to expand on why dnotify is awful and why inotify is a great replacement, because dnotify's limitations are really showing up on modern desktop systems. Some technical issues with dnotify and why inotify solves the problem: - dnotify requires one fd per watched directory. this results in a lot of file descriptors if you are trying to do anything creative. inotify solves this by only having one open file descriptor. - with dnotify, you open the fd on the directory to watch, which pins the directory. this makes unmounting the backing filesystem impossible and means using dnotify on removable devices is nontrivial. This is a problem with desktop systems. Not only does inotify solve this problem (by not requiring an open of each watched directory), but it even sends an "unmount" event when the watched directory is unmounted. - Using dnotify is, uh, interesting. I mean, fcntl(2) and SIGIO? You end up needing to use real-time signals. Gross gross gross. This does not working well with modern event- driven applications that use mainloops. You end up needing a complicated daemon like FAM. We don't want FAM, and in fact we should not even need a daemon (although we might want one). Conversely, inotify is trivial to use and integrates well and is select()-able. I have been going over the code for awhile now, and it looks good. I would really like to hear Al's opinion so we can move on fixing any possible issues that he has. Best, Robert Love

Related Links:

Note about using inotify with GNOME/KDE

on
September 16, 2004 - 9:51am

If you are interested in using inotify with your GNOME/KDE desktop I suggest you download gamin (cvs.gnome.org). Gamin is a API/ABI compatible FAM replacement and I have written an inotify backend for it.

For Kde too?

Anonymous
on
September 16, 2004 - 10:24am

I noted that sometimes kde didn't let me unmount a CF. Could gamin resolve this?

Gamin with inotify could resolve this

on
September 16, 2004 - 10:49am

As long as KDE doesn't keep a fd open on the CF, gamin with the inotify backend should resolve this.

unmounting file system

Anonymous
on
September 16, 2004 - 2:11pm

So when you can not unmount a filesystem. Is there any solution other than rebooting the machine? For sure there is.

So thanks in advance.

unmounting file system

on
September 16, 2004 - 2:59pm

You can kill whatever process has a fd open on or in the mountpoint. Using

lsof /mnt/point

will show you the processes you need to kill. Not a perfect solution, but maybe better than rebooting.

You can do a "Lazy" unmount--

on
September 16, 2004 - 8:09pm

You can do a "Lazy" unmount-- which will stop any new accesses to the filesystem (removing it from the directory hierarchy), then truly unmount it after all remaining accesses to it close.

umount -l /path/to/mountpoint

And you should be good to go.

Is the inotify support in 0.0

Anonymous
on
September 17, 2004 - 4:19am

Is the inotify support in 0.0.9 or do I need to pull from CVS?

It is in 0.0.9

on
September 17, 2004 - 8:30am

Just ./configure --enable-inotify

This is great news. But I'll

Anonymous
on
September 16, 2004 - 6:20pm

This is great news. But I'll stick with Dazuko for quite awhile.

How about overmounting?

Anonymous
on
September 19, 2004 - 1:30pm

How about file disappearing from directory structure by mounting
new filesystem over one already mounted? Does inotify monitor such events?

Emil Stepniewski

We could send an event when a

on
September 20, 2004 - 6:55pm

We could send an event when a directory has something mounted on it. But traversing the hierarchy and sending events to all files below this mount point isn't something I think should be done in the kernel.

Don't actually know this

Anonymous
on
November 18, 2004 - 1:11pm

Sure, the kernel knows when you mount a filesystem, but say you mount a filesystem onto /foo, hiding /foo/file.txt -- the kernel doesn't know (unless it wants to search your whole disk) whether that same inode is also linked as /bar/file.dat, and since inotify does the sane thing and works with inodes, it couldn't reliably tell you whether the name you're looking at actually got covered up, or another one did.

seems to be unstable

Anonymous (not verified)
on
January 10, 2005 - 12:37am

with 2.6.10-bk12, it turned off my computer.
sometimes my computer very clogging..

Is it possible for inotify to

Anonymous (not verified)
on
January 11, 2005 - 5:18pm

Is it possible for inotify to monitor all subdirectories of a given directory automatically, or will I have to call a separate ioctl() for each of them?

intercepting the system calls?

Anonymous (not verified)
on
March 20, 2006 - 12:30pm

To observe the whole file system, I wonder if it isn't better to intercept the system calls, that may do changes to files. This would be how lids (linux intrusion dection) does it.

Any reasons for this or that?

What about the user causing the event?

Darrell (not verified)
on
April 22, 2005 - 12:38pm

I understand that inotify sends a signal whenever one of the specified events happens on a directory or a file in the directory. That is really great for a real time backup solution I am needing to implement so I can automatically copy every file that gets created or updated to an off-site storage facility in near real time.

But, I have another problem to solve. I have to create a log of every user who accesses a file in a specific directory and the date and time they open that file. Is there any information passed in the inotify transaction that indicates what user was responsible for the event?

Thanks

Similar Situation

Billy Crook (not verified)
on
May 21, 2006 - 1:50am

Darrell,
I am in a similar situation. I want to perform an action when files are added, removed, or modified in or under //. I'd like to log this to a mysql db and copy the file to another server or delete it from the other.
I will looking for more information on inotify and FAM, but would like to pick your brain on the subject if you would oblige.

Thanks,
Billy

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.