Вы находитесь на странице: 1из 17

Monitor Linux file system events with inotify

Efficient and effective file system event-monitoring in the 2.6 kernel


Ian Shields Senior Programmer IBM Skill Level: Introductory Date: 06 Apr 2010 (Updated 10 Sep 2010)

Use inotify when you need efficient, fine-grained, asynchronous monitoring of Linux file system events. Use it for user-space monitoring for security, performance, or other purposes. (On 10 September 2010, the downloadable sample code for this article was refreshed to correct a typo. -Ed.) Connect with Ian
Ian is one of our most popular and prolific authors. Browse all of Ian's articles on developerWorks. Check out Ian's profile and connect with him, other authors, and fellow readers in My developerWorks.

I am indebted to Eli Dow of IBM who wrote an earlier version of this article, prior to the final integration of inotify in the Linux kernel. In particular, the sample code available in the Download section is still based heavily on Eli's original sample code.

Introducing inotify
File system event monitoring is essential for many types of programs ranging from file managers to security tools. Since the Linux 2.6.13 kernel, Linux has included inotify, which allows a monitoring program to open a single file descriptor and watch one or more files or directories for a specified set of events, such as open, close, move/rename, delete, create or change attributes. Some enhancements have been made in later kernels, so check your kernel level before depending on those features. In this article, you will learn how to use inotify functions for a simple monitoring application. Download the sample code and compile it on your system to explore further.
Copyright IBM Corporation 2010 Monitor Linux file system events with inotify Trademarks Page 1 of 17

developerWorks

ibm.com/developerWorks/

A little history
Before inotify there was dnotify. Unfortunately, dnotify had limitations that left users hoping for something better. Some of the advantages of inotify are: Inotify uses a single file descriptor, while dnotify requires opening one file descriptor for each directory that you intend to watch for changes. This can be very costly when you are monitoring several directories at once, and you may even reach a per-process file descriptor limit. The file descriptor used by inotify is obtained using a system call and does not have an associated device or file. With dnotify, the file descriptor pins the directory, preventing the backing device to be unmounted, a particular problem with removable media. With inotify, a watched file or directory on a file system that is unmounted generates an event, and the watch is automatically removed. Inotify can watch files or directories. Dnotify monitors directories, and so programmers had to keep stat structures or an equivalent data structure reflecting the files in the directories being watched, then compare those with the current state after an event occurred in order to know what happened to the entry in the directory. As noted above, inotify uses a file descriptor, allowing programmers to use standard select or poll functions to watch for events. This allows for efficient multiplexed I/O or integration with Glib's mainloop. In contrast, dnotify uses signals, which programmers often find more difficult or less than elegant. Signaldrive I.O notification was also added to inotify in kernel 2.6.25.

The API for inotify


Inotify provides a simple API that uses minimal file descriptors and allows fine granularity of monitoring. Communication with inotify is established through a system call. The available functions are as follows: inotify_init is the system call that creates an inotify instance and returns a file descriptor referring to the instance. inotify_init1 is similar to inotify_init with additional flags. If the flags are not specified, it behaves the same as inotify_init. inotify_add_watch adds a watch for a file or directory and specifies which events are to be watched. Flags control whether events should be added to an existing watch, whether the watch should be done only if the path represents a directory, whether symbolic links should be followed or not, and whether the watch is a one-shot watch that should be stopped after the first event. inotify_rm_watch removes a watched item from a watch list. read reads a buffer containing information about one or more events.
Monitor Linux file system events with inotify Page 2 of 17

ibm.com/developerWorks/

developerWorks

close closes the file descriptor, and removes any watches still remaining on that descriptor. When all file descriptors for an instance are closed, the resources and underlying object are freed so the kernel can reuse them. So, a typical monitoring program will do the following: 1. 2. 3. 4. 5. Use inotify_init to open a file descriptor Add one or more watches Wait for events Process events, then return to wait for more When no more watches are active or upon some signal, close the file descriptor, clean up, and exit.

In the next section, you'll see the events you can watch, and how they work in our sample program. Finally you'll see how the event monitoring works.

Notifications
When your application reads a notification, a sequence of one or more events is read into a buffer you provide. Events are returned in a variable length structure as shown in Listing 1. If the amount of data fills your buffer, you may need to handle the case of partial event information or a partial name for the last entry. Listing 1. The event structure for inotify
struct inotify_event { int wd; uint32_t mask; uint32_t cookie; uint32_t len; char name __flexarr; }; /* /* /* /* /* Watch descriptor. */ Watch mask. */ Cookie to synchronize two events. */ Length (including NULs) of name. */ Name. */

Note that the name field is present only if the watched item is a directory and the event is for an item in the directory, other than the directory itself. The cookie is used to correlate an IN_MOVED_FROM event with the corresponding IN_MOVED_TO event if both relate to items being watched. The event type is returned in the mask field, along with flags that may be set by the kernel. For example, the IN_ISDIR flag is set by the kernel if the event is for a directory.

Events you can watch


There are several events you can watch. Some, such as IN_DELETE_SELF apply only to the item being watched, while others such as IN_ATTRIB or IN_OPEN may apply to the watched item, or if that item is a directory, to a directory or file within it. IN_ACCESS The watched item or an entry in a watched directory was accessed. For example, an open file was read.
Monitor Linux file system events with inotify Page 3 of 17

developerWorks

ibm.com/developerWorks/

IN_MODIFY The watched item or an entry in a watched directory was modified. For example, an open file was updated. IN_ATTRIB The metadata changed on the watched item or an entry in a watched directory . For example, timestamps or permissions were changed. IN_CLOSE_WRITE A file or directory that had been open for write was closed. IN_CLOSE_NOWRITE A file or directory that had been open read-only was closed. IN_CLOSE A convenience mask that is the logical OR of the preceding two close events (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE). IN_OPEN A file or directory was opened. IN_MOVED_FROM A watched item or an entry in a watched directory was moved from the watched location. The event also includes a cookie to allow you to correlate IN_MOVED_FROM and IN_MOVED_TO. IN_MOVED_TO A file or directory was moved to a watched location. The event includes a cookie as for IN_MOVED_FROM. If a file or directory is simply renamed, you would see both events. If it was moved to or from a location that you are not watching, you will see only one event. If you move or rename a watched item, the watch continues. See IN_MOVE-SELF below. IN_MOVE A convenience mask that is the logical OR of the preceding two move events (IN_MOVED_FROM | IN_MOVED_TO). IN_CREATE Subdirectory or file was created in a watched directory. IN_DELETE Subdirectory or file was deleted in a watched directory. IN_DELETE_SELF The watched item itself was deleted. The watch is terminated and you will also receive an IN_IGNORED event. IN_MOVE_SELF The watched item itself was moved In addition to the event flags, there are several other flags that you can find in the inotify header (/usr/include/sys/inotify.h). For example, if you only want to watch for the first event, you can set the IN_ONESHOT flag when you add the watch.

A simple inotify application


Our sample application (see the Download section) follows the above general logic. We use a signal handler to catch ctrl-c (SIGINT) and reset a flag (keep_running) so
Monitor Linux file system events with inotify Page 4 of 17

ibm.com/developerWorks/

developerWorks

the application knows to terminate. The actual inotify calls are done in utility routines. Notice that we also create a queue so that events can be cleared from the underlying inotify object and then processed later. In a real application, you might want to do this in a different (and higher priority) thread than the one you use for processing the events. For this application, it simply illustrates the general principle. We use a very simple linked list of events where each of our queue entries consists of the original event plus space for a pointer to the next event in the queue. The main program The signal handler and main routine are shown in Listing 2. For this simple example, we set up a watch for each file or directory passed in on the command line, and we watch all events for each one, using the event mask IN_ALL_EVENTS. In a real application, you may want to track only file and directory creation or deletion events, so you might mask off open and close events as well as attribute changes. If you're not interested in file or directory renames and moves, you could also mask off the various move events. See the man page of inotify for more details. Listing 2. Sample main routine for inotify-test.c
/* Signal handler that simply resets a flag to cause termination */ void signal_handler (int signum) { keep_running = 0; } int main (int argc, char **argv) { /* This is the file descriptor for the inotify watch */ int inotify_fd; keep_running = 1; /* Set a ctrl-c signal handler */ if (signal (SIGINT, signal_handler) == SIG_IGN) { /* Reset to SIG_IGN (ignore) if that was the prior state */ signal (SIGINT, SIG_IGN); } /* First we open the inotify dev entry */ inotify_fd = open_inotify_fd (); if (inotify_fd > 0) { /* We will need a place to enqueue inotify events, this is needed because if you do not read events fast enough, you will miss them. This queue is probably too small if you are monitoring something like a directory with a lot of files and the directory is deleted. */ queue_t q; q = queue_create (128); /* This is the watch descriptor returned for each item we are watching. A real application might keep these for some use in the application. This sample only makes sure that none of the watch descriptors is less than 0. */

Monitor Linux file system events with inotify

Page 5 of 17

developerWorks
int wd;

ibm.com/developerWorks/

/* Watch all events (IN_ALL_EVENTS) for the directories and files passed in as arguments. Read the article for why you might want to alter this for more efficient inotify use in your app. */ int index; wd = 0; printf("\n"); for (index = 1; (index < argc) && (wd >= 0); index++) { wd = watch_dir (inotify_fd, argv[index], IN_ALL_EVENTS); } if (wd > 0) { /* Wait for events and process them until a termination condition is detected */ process_inotify_events (q, inotify_fd); } printf ("\nTerminating\n"); /* Finish up by closing the fd, destroying the queue, and returning a proper code */ close_inotify_fd (inotify_fd); queue_destroy (q); } return 0; }

Opening the file descriptor using inotify_init Listing 3 shows our simple utility function for creating an inotify instance and getting a file descriptor for it. The file descriptor is returned to the caller. If there is an error, the returned value is negative. Listing 3. Using inotify_init
/* Create an inotify instance and open a file descriptor to access it */ int open_inotify_fd () { int fd; watched_items = 0; fd = inotify_init (); if (fd < 0) { perror ("inotify_init () = "); } return fd; }

Adding a watch using inotify_add_watch Once we have a file descriptor for the inotify instance, we need to add one or more watches. You use the mask to set particular events that you want to watch. In our example, we use the mask IN_ALL_EVENTS, which watches all available events.
Monitor Linux file system events with inotify Page 6 of 17

ibm.com/developerWorks/

developerWorks

Listing 4. Using inotify_add_watch


int watch_dir (int fd, const char *dirname, unsigned long mask) { int wd; wd = inotify_add_watch (fd, dirname, mask); if (wd < 0) { printf ("Cannot add watch for \"%s\" with event mask %lX", dirname, mask); fflush (stdout); perror (" "); } else { watched_items++; printf ("Watching %s WD=%d\n", dirname, wd); printf ("Watching = %d items\n", watched_items); } return wd; }

The event processing loop Now that we have some watches set up, the next thing is to wait for events. We loop as long as there are some watches still set and our keep_running flag has not been reset by the signal handler. The loop waits for some event to happen, queues the available events, then processes the queue before returning to wait for more events. In a real application, you would probably post events to the queue in one thread, while processing them in another thread. The loop is shown in Listing 5. Listing 5. The event processing loop
int process_inotify_events (queue_t q, int fd) { while (keep_running && (watched_items > 0)) { if (event_check (fd) > 0) { int r; r = read_events (q, fd); if (r < 0) { break; } else { handle_events (q); } } } return 0; }

Waiting for events In our sample application, we wait indefinitely, and wake only if a watched event occurs or a signal interrupts processing. The code is shown in Listing 6.
Monitor Linux file system events with inotify Page 7 of 17

developerWorks Listing 6. Waiting for events or interrupts


int event_check (int fd) { fd_set rfds; FD_ZERO (&rfds); FD_SET (fd, &rfds); /* Wait until an event happens or we get interrupted by a signal that we catch */ return select (FD_SETSIZE, &rfds, NULL, NULL, NULL); }

ibm.com/developerWorks/

Reading the events When an event occurs, we read as many events as will fit in a large buffer and then put them in a queue for our event handler to process. The sample code does not handle the case where there are more events available than will fit in our 16.384-byte buffer. It needs to be able to handle a partial event at the end of the buffer. Current limits for the name length should not be a problem, but good defensive programming might check that names could not overflow the buffer. Listing 7. Reading and queuing events
int read_events (queue_t q, int fd) { char buffer[16384]; size_t buffer_i; struct inotify_event *pevent; queue_entry_t event; ssize_t r; size_t event_size, q_event_size; int count = 0; r = read (fd, buffer, 16384); if (r <= 0) return r; buffer_i = 0; while (buffer_i < r) { /* Parse events and queue them. */ pevent = (struct inotify_event *) &buffer[buffer_i]; event_size = offsetof (struct inotify_event, name) + pevent->len; q_event_size = offsetof (struct queue_entry, inot_ev.name) + pevent->len; event = malloc (q_event_size); memmove (&(event->inot_ev), pevent, event_size); queue_enqueue (event, q); buffer_i += event_size; count++; } printf ("\n%d events queued\n", count); return count; }

Processing events Finally! We have some events to process. For this application, we simply report what event occurred. If a name is present in the event structure, we report whether it is a file or directory. In the case of a move, we also report the cookie information that allows you to correlate move or rename events. Listing 8 shows part of the code,
Monitor Linux file system events with inotify Page 8 of 17

ibm.com/developerWorks/

developerWorks

including the handling of some of the events. See the Download section for the complete code. Listing 8. Processing events
void handle_event (queue_entry_t event) { /* If the event was associated with a filename, we will store it here */ char *cur_event_filename = NULL; char *cur_event_file_or_dir = NULL; /* This is the watch descriptor the event occurred on */ int cur_event_wd = event->inot_ev.wd; int cur_event_cookie = event->inot_ev.cookie; unsigned long flags; if (event->inot_ev.len) { cur_event_filename = event->inot_ev.name; } if ( event->inot_ev.mask & IN_ISDIR ) { cur_event_file_or_dir = "Dir"; } else { cur_event_file_or_dir = "File"; } flags = event->inot_ev.mask & ~(IN_ALL_EVENTS | IN_UNMOUNT | IN_Q_OVERFLOW | IN_IGNORED ); /* Perform event dependent handler routines */ /* The mask is the magic that tells us what file operation occurred */ switch (event->inot_ev.mask & (IN_ALL_EVENTS | IN_UNMOUNT | IN_Q_OVERFLOW | IN_IGNORED)) { /* File was accessed */ case IN_ACCESS: printf ("ACCESS: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, cur_event_filename, cur_event_wd); break; /* File was modified */ case IN_MODIFY: printf ("MODIFY: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, cur_event_filename, cur_event_wd); break; /* File changed attributes */ case IN_ATTRIB: printf ("ATTRIB: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, cur_event_filename, cur_event_wd); break; /* File open for writing was closed */ case IN_CLOSE_WRITE: printf ("CLOSE_WRITE: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, cur_event_filename, cur_event_wd); break; /* File open read-only was closed */ case IN_CLOSE_NOWRITE: printf ("CLOSE_NOWRITE: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, cur_event_filename, cur_event_wd); break;

Monitor Linux file system events with inotify

Page 9 of 17

developerWorks
/* File was opened */ case IN_OPEN: printf ("OPEN: %s \"%s\" on WD #%i\n", cur_event_file_or_dir, cur_event_filename, cur_event_wd); break; /* File was moved from X */ case IN_MOVED_FROM: printf ("MOVED_FROM: %s \"%s\" on WD #%i. Cookie=%d\n", cur_event_file_or_dir, cur_event_filename, cur_event_wd, cur_event_cookie); break;

ibm.com/developerWorks/

. . (other cases) . /* Watch was removed explicitly by inotify_rm_watch or automatically because file was deleted, or file system was unmounted. */ case IN_IGNORED: watched_items--; printf ("IGNORED: WD #%d\n", cur_event_wd); printf("Watching = %d items\n",watched_items); break; /* Some unknown message received */ default: printf ("UNKNOWN EVENT \"%X\" OCCURRED for file \"%s\" on WD #%i\n", event->inot_ev.mask, cur_event_filename, cur_event_wd); break; } /* If any flags were set other than IN_ISDIR, report the flags */ if (flags & (~IN_ISDIR)) { flags = event->inot_ev.mask; printf ("Flags=%lX\n", flags); } }

This simple example is designed to illustrate how inotify works and what events you can watch. Your own needs will dictate which events you watch and how you handle them.

Example usage
In this section, we create a simple, two-level directory structure with a file in the directory and then run the sample application to illustrate some of the events that inotify can monitor. We will start the inotify sample program from a terminal session, but run it in background (using &) so that output from the program is interleaved with our commands. You could also run the program in one terminal window while running commands in one or more other windows. Listing 9 shows the creation of our sample directory structure and empty file, along with the output when we initially launch the sample program.

Monitor Linux file system events with inotify

Page 10 of 17

ibm.com/developerWorks/

developerWorks

Listing 9. Creating the sample environment


ian@attic4:~/inotify-sample$ mkdir -p dir1/dir2 ian@attic4:~/inotify-sample$ touch dir1/dir2/file1 ian@attic4:~/inotify-sample$ ./inotify_test dir1/ dir1/dir2/ dir1/dir2/file1& [2] 8733 ian@attic4:~/inotify-sample$ Watching dir1/ WD=1 Watching = 1 items Watching dir1/dir2/ WD=2 Watching = 2 items Watching dir1/dir2/file1 WD=3 Watching = 3 items ian@attic4:~/inotify-sample$

In Listing 10, we show the output from listing the contents of dir2. The first event is reported for dir1, showing that something, namely dir2, in the directory being watched on watch descriptor 1 was opened. The second entry is for watch descriptor 2, showing that the item being watched (in this case, dir2) was opened. If you are watching many items in a directory tree, you will probably see this kind of dual output frequently. Listing 10. Listing the contents of dir2
ian@attic4:~/inotify-sample$ ls dir1/dir2 file1 4 events queued OPEN: Dir "dir2" on WD #1 OPEN: Dir "(null)" on WD #2 CLOSE_NOWRITE: Dir "dir2" on WD #1 CLOSE_NOWRITE: Dir "(null)" on WD #2

In Listing 11, we add some text to file1. Note again the dual open, close, and modify events for the file and its containing directory. Note also that not all of the events were read at once. Our queuing routine was called three different times with two events each time. If you run the application again and do the same things each time, you may or may not repeat this particular behavior. Listing 11. Adding text to file1
ian@attic4:~/inotify-sample$ echo "Some text" >> dir1/dir2/file1 2 events queued OPEN: File "file1" on WD #2 OPEN: File "(null)" on WD #3 2 events queued MODIFY: File "file1" on WD #2 MODIFY: File "(null)" on WD #3 2 events queued CLOSE_WRITE: File "file1" on WD #2 CLOSE_WRITE: File "(null)" on WD #3

In Listing 12, we change the attributes of file1. Once again, we have dual output for the watched item and its containing directory.
Monitor Linux file system events with inotify Page 11 of 17

developerWorks Listing 12. Changing the attributes of a file


ian@attic4:~/inotify-sample$ chmod a+w dir1/dir2/file1 2 events queued ATTRIB: File "file1" on WD #2 ATTRIB: File "(null)" on WD #3

ibm.com/developerWorks/

Now let's move file1 up a directory level into dir1. The resulting output is shown in Listing 13. This time we do not have dual entries. We actually have three entries, one for each directory and one for the file itself. Note that the cookie (569) allows us to correlate the MOVED-FROM event with the MOVED_TO event. Listing 13. Moving file1 to dir1
ian@attic4:~/inotify-sample$ mv dir1/dir2/file1 dir1 3 events queued MOVED_FROM: File "file1" on WD #2. Cookie=569 MOVED_TO: File "file1" on WD #1. Cookie=569 MOVE_SELF: File "(null)" on WD #3

Now let's create a hard link from file1 to file2. Since the number of links to the inode changes, we have an ATTRIB event on file1, and we also have a CREATE event for file2. Listing 14. Creating a hard link
ian@attic4:~/inotify-sample$ ln dir1/file1 dir1/file2 2 events queued ATTRIB: File "(null)" on WD #3 CREATE: File "file2" on WD #1

Now let's move file1 to our current directory, renaming it as file3. The current directory is not being watched, so there is no MOVED_TO event to correlate with the MOVED_FROM event. Listing 15. Moving file1 to a directory that is not being watched
ian@attic4:~/inotify-sample$ mv dir1/file1 ./file3 2 events queued MOVED_FROM: File "file1" on WD #1. Cookie=572 MOVE_SELF: File "(null)" on WD #3

At this point, dir2 is empty, so let's remove it. Note that we get an IGNORED event for watch descriptor 2, so we are now watching only two items. Listing 16. Removing dir2
ian@attic4:~/inotify-sample$ rmdir dir1/dir2 3 events queued DELETE: Dir "dir2" on WD #1 DELETE_SELF: File "(null)" on WD #2 IGNORED: WD #2 Watching = 2 items

Monitor Linux file system events with inotify

Page 12 of 17

ibm.com/developerWorks/

developerWorks

Let's remove file3. Note that we do not get an IGNORED event this time. Why not? And why do we get an ATTRIB event for file 3 (which was originally dir1/dir2/file1)? Listing 16. Deleting file3
ian@attic4:~/inotify-sample$ rm file3 1 events queued ATTRIB: File "(null)" on WD #3

Remember we created a hard link from file1 to file2. Listing 17 shows that we are still watching file2 on watch descriptor 3, even though there was no file 2 when we started! Listing 17. We are still watching file2!
ian@attic4:~/inotify-sample$ touch dir1/file2 6 events queued OPEN: File "file2" on WD #1 OPEN: File "(null)" on WD #3 ATTRIB: File "file2" on WD #1 ATTRIB: File "(null)" on WD #3 CLOSE_WRITE: File "file2" on WD #1 CLOSE_WRITE: File "(null)" on WD #3

So now let's delete dir1 and watch the cascade of events, culminating with our program terminating itself because it is no longer watching anything. Listing 18. Deleting dir1
ian@attic4:~/inotify-sample$ rm -rf dir1 8 events queued OPEN: Dir "(null)" on WD #1 ATTRIB: File "(null)" on WD #3 DELETE_SELF: File "(null)" on WD #3 IGNORED: WD #3 Watching = 1 items DELETE: File "file2" on WD #1 CLOSE_NOWRITE: Dir "(null)" on WD #1 DELETE_SELF: File "(null)" on WD #1 IGNORED: WD #1 Watching = 0 items Terminating

Possible uses of inotify


You can use inotify for many purposes. Here are some possibilities: Performance monitoring You may want to determine which files an applications opens most frequently. If you discover that a small file is repeatedly opened and closed, you might think
Monitor Linux file system events with inotify Page 13 of 17

developerWorks

ibm.com/developerWorks/

about using an in-memory version, or changing the application so that the data is shared in some other way. Meta information You may want to log additional information about files, such as the original creation time, or the id of the user who last modified the file. Security You may want to monitor all access to a particular file or directory for security reasons. Our sample code watches for all events and reports all of them. In practice, you probably want to see only a specific subset of the events, according to your needs. You may also watch for different events on different watched items For example, you may want to watch for open and close events on files, but only creation or deletion events on directories. Whenever possible, you should limit your watches to the smallest set of events that interest you.

Conclusion
When applied to such areas as performance monitoring, debugging, and automation, inotify is a powerful, highly granular mechanism for monitoring Linux file systems. Use the sample code provided in this article to start writing your own applications that respond to or record file system events in real time with minimal performance overhead.

Monitor Linux file system events with inotify

Page 14 of 17

ibm.com/developerWorks/

developerWorks

Downloads
Description
Sample code used in this article Information about download methods

Name
inotify-sample.tgz

Size
4 KB

Download method
HTTP

Monitor Linux file system events with inotify

Page 15 of 17

developerWorks

ibm.com/developerWorks/

Resources
Learn Event Management Best Practices (IBM Redbook, June 2004) broadly and deeply covers event management with a focus on event filtering, duplicate detection, correlation, notification, escalation, synchronization, trouble-ticket integration, maintenance modes, and automation. "Use autonomic computing for problem determination" (developerWorks, June 2004) describes how an autonomic system can be used to monitor events and diagnose an error condition in an IT system and provide corrective actions. In the developerWorks Linux zone, find hundreds of how-to articles and tutorials, as well as downloads, discussion forums, and a wealth other resources for Linux developers and administrators. Stay current with developerWorks technical events and webcasts focused on a variety of IBM products and IT industry topics. Attend a free developerWorks Live! briefing to get up-to-speed quickly on IBM products and tools as well as IT industry trends. Watch developerWorks on-demand demos ranging from product installation and setup demos for beginners, to advanced functionality for experienced developers. Follow developerWorks on Twitter. Get products and technologies Evaluate IBM products in the way that suits you best: Download a product trial, try a product online, use a product in a cloud environment, or spend a few hours in the SOA Sandbox learning how to implement Service Oriented Architecture efficiently. Discuss Get involved in the My developerWorks community. Connect with other developerWorks users while exploring the developer-driven blogs, forums, groups, and wikis.

Monitor Linux file system events with inotify

Page 16 of 17

ibm.com/developerWorks/

developerWorks

About the author


Ian Shields Ian Shields works on a multitude of Linux projects for the developerWorks Linux zone. He is a Senior Programmer at IBM at the Research Triangle Park, NC. He joined IBM in Canberra, Australia, as a Systems Engineer in 1973, and has since worked on communications systems and pervasive computing in Montreal, Canada, and RTP, NC. He has several patents and has published several papers. His undergraduate degree is in pure mathematics and philosophy from the Australian National University. He has an M.S. and Ph.D. in computer science from North Carolina State University. Learn more about Ian in in Ian's profile on My developerWorks. Copyright IBM Corporation 2010 (www.ibm.com/legal/copytrade.shtml) Trademarks (www.ibm.com/developerworks/ibm/trademarks/)

Monitor Linux file system events with inotify

Page 17 of 17

Вам также может понравиться