Kernel Korner - Intro to inotify
The heart of inotify is the watch, which consists of a pathname specifying what to watch and an event mask specifying what to watch for. inotify can watch for many different events: opens, closes, reads, writes, creates, deletes, moves, metadata changes and unmounts. Each inotify instance can have thousands of watches, each watch for a different list of events.
Watches are added with the inotify_add_watch() system call:
int inotify_add_watch (int fd, const char *path, __u32 mask);
A call to inotify_add_watch() adds a watch for the one or more events given by the bitmask mask on the file path to the inotify instance associated with the file descriptor fd. On success, the call returns a watch descriptor, which is used to identify this particular watch uniquely. On failure, minus one is returned and errno is set as appropriate.
Usage is simple:
int wd;
wd = inotify_add_watch (fd,
"/home/rlove/Desktop",
IN_MODIFY | IN_CREATE | IN_DELETE);
if (wd < 0)
perror ("inotify_add_watch");
This example adds a watch on the directory /home/rlove/Desktop for any modifications, file creations or file deletions.
Table 1 shows valid events.
Table 1. Valid Events
| Event | Description |
|---|---|
| IN_ACCESS | File was read from. |
| IN_MODIFY | File was written to. |
| IN_ATTRIB | File's metadata (inode or xattr) was changed. |
| IN_CLOSE_WRITE | File was closed (and was open for writing). |
| IN_CLOSE_NOWRITE | File was closed (and was not open for writing). |
| IN_OPEN | File was opened. |
| IN_MOVED_FROM | File was moved away from watch. |
| IN_MOVED_TO | File was moved to watch. |
| IN_DELETE | File was deleted. |
| IN_DELETE_SELF | The watch itself was deleted. |
Table 2 shows the provided helper events.
Table 2. Helper Events
| Event | Description |
|---|---|
| IN_CLOSE | IN_CLOSE_WRITE | IN_CLOSE_NOWRITE |
| IN_MOVE | IN_MOVED_FROM | IN_MOVED_TO |
| IN_ALL_EVENTS | Bitwise OR of all events. |
As an example, if an application wanted to know whenever the file safe_combination.txt was opened or closed, it could do the following:
int wd;
wd = inotify_add_watch (fd,
"safe_combination.txt",
IN_OPEN | IN_CLOSE);
if (wd < 0)
perror ("inotify_add_watch");
With inotify initialized and watches added, your application is now ready to receive events. Events are queued asynchronously, in real time as the events happen, but they are read synchronously via the read() system call. The call blocks until events are ready and then returns all available events once any event is queued.
Events are delivered in the form of an inotify_event structure, which is defined as:
struct inotify_event {
__s32 wd; /* watch descriptor */
__u32 mask; /* watch mask */
__u32 cookie; /* cookie to synchronize two events */
__u32 len; /* length (including nulls) of name */
char name[0]; /* stub for possible name */
};
The wd field is the watch descriptor originally returned by inotify_add_watch(). The application is responsible for mapping this identifier back to the filename.
The mask field is a bitmask representing the event that occurred.
The cookie field is a unique identifier linking together two related but separate events. It is used to link together an IN_MOVED_FROM and an IN_MOVED_TO event. We will look at it later.
The len field is the length of the name field or nonzero if this event does not have a name. The length contains any potential padding—that is, the result of strlen() on the name field may be smaller than len.
The name field contains the name of the object to which the event occurred, relative to wd, if applicable. For example, if a watch for writes in /etc triggers an event on the writing to /etc/vimrc, the name field will contain vimrc, and the wd field will link back to the /etc watch. Conversely, if watching the file /etc/fstab for reads, a triggered read event will have a len of zero and no associated name whatsoever, because the watch descriptor associates directly with the affected file.
The size of name is dynamic. If the event has no associated filename, no name is sent at all and no space is consumed. If the event does have an associated filename, the name field is dynamically allocated and trails the structure for len bytes. This approach allows the name's length to vary in size and consume no space when not needed.
Because the name field is dynamic, the size of the buffer passed to read() is unknown. If the size is too small, the system call returns zero, alerting the application. inotify, however, allows user space to “slurp” multiple events at once. Consequently, most applications should pass in a large buffer, which inotify will fill with as many events as possible.
It sounds complicated, but usage is simple:
/* size of the event structure, not counting name */
#define EVENT_SIZE (sizeof (struct inotify_event))
/* reasonable guess as to size of 1024 events */
#define BUF_LEN (1024 * (EVENT_SIZE + 16)
char buf[BUF_LEN];
int len, i = 0;
len = read (fd, buf, BUF_LEN);
if (len < 0) {
if (errno == EINTR)
/* need to reissue system call */
else
perror ("read");
} else if (!len)
/* BUF_LEN too small? */
while (i < len) {
struct inotify_event *event;
event = (struct inotify_event *) &buf[i];
printf ("wd=%d mask=%u cookie=%u len=%u\n",
event->wd, event->mask,
event->cookie, event->len);
if (event->len)
printf ("name=%s\n", event->name);
i += EVENT_SIZE + event->len;
}
This approach is undertaken to allow many events to be read and processed in a single swoop and to deal with the dynamically sized name. Clever readers will immediately question whether the following code is safe with respect to alignment requirements:
while (i < len) {
struct inotify_event *event;
event = (struct inotify_event *) &buf[i];
/* ... */
i += EVENT_SIZE + event->len;
}
Indeed, it is. This is the reason that the len field may be longer than the string's length. Additional null characters may follow the string, padding it out to a size that ensures the following structure is properly aligned.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Validate an E-Mail Address with PHP, the Right Way
- A Topic for Discussion - Open Source Feature-Richness?
- Dart: a New Web Programming Experience
- Download the Free Red Hat White Paper "Using an Open Source Framework to Catch the Bad Guy"
- The Secret Password Is...
- myip
1 hour 49 min ago - Keeping track of IP address
3 hours 40 min ago - Roll your own dynamic dns
8 hours 53 min ago - Please correct the URL for Salt Stack's web site
12 hours 5 min ago - Android is Linux -- why no better inter-operation
14 hours 20 min ago - Connecting Android device to desktop Linux via USB
14 hours 49 min ago - Find new cell phone and tablet pc
15 hours 47 min ago - Epistle
17 hours 16 min ago - Automatically updating Guest Additions
18 hours 24 min ago - I like your topic on android
19 hours 11 min ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
support on 64-bit machines
Do i need to make some changes to get it working on 64 bit machines .
read() length, alignment
fyi, something that wasn't clear in the article is the requirements on the read() call.
I was playing with inotify, and I tried to call read an event in 2 parts:
struct inotify_event evt_hdr;
ssize_t nr = read(fd, &evt_hdr, sizeof(evt_hdr));
read() returned EINVAL
( at least on 2.6.23.17-88.fc7 )
When I restructured the code to read the entire event,
(similar to the article example) it works.
It would seem also that the read buffer must have proper alignment for a
struct inotify_event as well, so just declaring a char buffer on the stack
for the read() destination isn't necessarily going to work, either.
otherwise, nice article, nice feature!
Thanks
Inotify does not work
I have registered Inotify to a file for listening IN_MODIFY | IN_DELETE | IN_DELETE_SELF. But it does not work when I fwrite() to the file. This doest not happen always.
Seems to be a bug in iNotify
changes
Seems changes are coming, not primary in inotify and the old dnotify, but in the whole system of fs/notify.
After a long search I think there is a guy called Eric Paris (RedHat) that is currently in charge of notify structures in kernel.
He is actively commiting to the kernel git repository, which can be followed always at http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git.
As Eric Paris claims he is preparing the whole thing for upcoming "fanotify" system, which will be more powerfull, sending the possibility to decide which file accessse should be granted to the userspace (if I got right the idea).
http://lwn.net/Articles/311350/
http://lwn.net/Articles/339253/
Which is of course fantastic, but for many cases we dont need this power, and the inotify does the job at right level. I just needed a little add-on to provide the uid in inotify_event, but now it seems we will have to wait for the fanotify to be introduced first, and after to be decided the future of inotify ...
Inotify
Is there any possibility to obtain the uid of the trigger for certain inotify_event?
P.S. in general - is inotify a living project or it is shut-down?
how to check for status of the inotify
i have a problem and hope i get a response from you.
i have a script that will create an sql file to the watch directory of my inotify. upon detection, my C program then executes the sql statment using OCI functions. is there any way i can throw back the result/status to my script if the execution was successful or not?
i have a problem and hope i
i have a problem and hope i get a response from you.
currently, my C program with the inotify is already running. this C program will wait base on its watch directory.
i then have a script that will create an sql file to the watch directory of my inotify. upon detection, my C program then executes the sql statment using OCI functions. is there any way i can throw back the result/status to my script if the execution was successful or not?
*** note: my script did not call my C program which is already running from the start
Not able to notify changes apart from /tmp
Hi,
I am facing some different behaviour using inotify for notifying file changes.
I added file notification for some file in /tmp directory with IN_MODIFY flag.
when i modified contents in this file, i am able to read the notifications of this change and the mask value for this notification is IN_MODIFY(2).
If i use same file with same source code in other directory(ex : /home), iam getting mask value as IN_IGNORED flag(3276. After this any modifications to the file, i am not getting any notifications.
This is some strange behaviour.
Kernel : 2.6.15-1.2054_FC5
Thank you for this, it was
Thank you for this, it was very useful.
One annoyance for someone coming across this: while I created the inotify using
IN_MODIFY | IN_CREATE | IN_DELETE
When the file was deleted, it returned only IN_IGNORED (because the file was deleted, the inotify was removed), not IN_DELETED
inotify for /proc
Hi,
There is a problem in my application. I am trying to monitor /proc for process creation/deletion, but i am not able to monitor the /proc directory in particular. The inotify will monitor all the sub directories in the /proc and other directories, but not in /proc, i.e. for process creation/deletion. i am using linux kernel-2.6.20-hardened. There was a bug previously reported in v2.6.16 regarding this issue, but i think it is fixed in further versions. if not please may i know so i will be able to patch it myself.
Please help..
Waiting for the reply
How to install inotify
Hi..
can u pls send me the full procedure to download as wel as how to install inotify... it s very userful for me ...
Thanks
Refer this on how to install
Refer this on how to install and how to use for various scenarios. http://inotify.aiken.cz/?section=inotify&page=faq&lang=en
Monitoring whole directory tree
Can you please help me?
I want to monitor the whole directory tree, using inotify.
I have done monitoring directory which notify me changes in file within that perticular directory, creation of directories into it, butI am unable to get the changes done within its subdirectories.
Please help me for this.
How would one get the user associated with an event.....
If I wanted to write a utility that would list each time a file I was interested in was modified and by who, how would I do that? Could I do that with inotify? I'm guessing no.
INOTIFY a very helpful tool
I tested INOTIFY in conjunction with POSIX queues (mq_open…) on my CentOS 4.3 – 2.6.18 and it seems to work OK, I am really impressed by this ‘new’ feature:
Just a small ‘observation’ as the code piece from below is going to drastically decrease the performances (stack is exhausted as ‘event’ is an in loop declaration) :-)) :
while (i < len) {
struct inotify_event *event;
…………………
Thanks to INOTIFY creators and contributors,
John
you're flat out wrong about the stack exhausted <EOM>
Code Feedback from gcc and a.out
Thanks for posting this information and the examples. Was very stuck trying to convert to inotify without this article, and now have a working program thanks to your help. Feedback on this article accumulated from the process:
Thanks! inotify ROCKS!
wrong /proc path
As of 2.6.17, it is NOT
/proc/sys/filesystem/inotify/max_user_watches
but
/proc/sys/fs/inotify/max_user_watches
Nice and helpful article
Thanks for the same.
Special files
Hello!
Is inotify supposed to work on special files in /sys ?
I tried monitoring normal files and it works great, but when i try to monitor files on sysfs, strace shows that the executable is blocked on the read() call.
Thanks!
Alberto