Develop Software Monitoring file system activities based on inotify

Source: Internet
Author: User
Tags inotify

Learn more about inotify

Inotify is a Linux kernel feature that monitors the file system and sends related event warnings to specialized applications in a timely manner, such as delete, read, write, and uninstall operations. You can also track the source and target details of an activity.
Using inotify is simple: create a file descriptor, append one or more monitors (one monitor is a path and a group of events), and then use the read () method to obtain event information from the descriptor. Read () does not use up the entire cycle. It is blocked before the event occurs.
Better yet, because inotify works with traditional file descriptors, You can passively monitor monitors and many other input sources using conventional select () system calls. Both methods-blocking file descriptors and using select ()-avoid busy polling.
Now, let's take a closer look at inotify, write some C code, and then look at a group of command line tools that you can build and use to attach commands and scripts to file system events. Inotify does not lose control in the middle, but it can run cat and wget and strictly execute it if necessary.
To use inotify, you must have a Linux machine with 2.6.13 or a kernel update (earlier Linux kernel versions use the lower-level File Monitor dnotify ). If you do not know the kernel version, go to shell and enter uname-:
% Uname-
Linux Ubuntu-desktop 2.6.24-19-generic #1 SMP... i686 GNU/Linux
If the listed kernel version is no less than 2.6.13, your system supports inotify. You can also check the/usr/include/sys/inotify. h file of the machine. If it exists, your kernel supports inotify.
Note: FreeBSD and Mac OS X provide a kqueue similar to inotify. Enter MAN 2 kqueue on the FreeBSD machine to obtain more information.
This article is based on Ubuntu Desktop version 8.04.1 (that is, hard), which runs on Parallels Desktop version 10.5 of Mac OS X version 3.0 leopard.

Inotify C API

inotify provides three system calls to build a variety of file system monitors:
inotify_init () Create an inotify subsystem instance in the kernel, if the operation succeeds, a file descriptor is returned. If the operation fails,-1 is returned. Like other system calls, if inotify_init () fails, check errno for diagnostic information.
inotify_add_watch () is used to add a monitor. Each monitor must provide a path name and a list of related events (each event is specified by a constant, such as in_modify ). To monitor multiple events, you only need to use the logical operator between events or the pipeline line (|) operator in the-C language. If inotify_add_watch () is successful, a unique identifier is returned for the registered monitor. Otherwise,-1 is returned. Use this identifier to change or delete related monitors.
inotify_rm_watch () deletes a monitor.
you also need to call the read () and close () systems. If the descriptor is generated by inotify_init (), read () is called to wait for the warning. Assuming there is a typical file descriptor, the application will block the receipt of events, which are represented as data in the stream. The general close () generated by inotify_init () on the file descriptor deletes all activity monitors and releases all memory associated with the inotify instance (here the typical reference count warning is also used. All file descriptors associated with the instance must be disabled before the memory consumed by the monitor and inotify is released ).
this powerful tool provides three application programming interfaces (APIS) for calling, and a simple and familiar example of "all content is a file ". Now let's look at the sample application.
example application: event monitoring
List 1 is a short C program that monitors the directories of two events: File Creation and deletion.
List 1. simple inotify application, it monitors the directories for creating, deleting, and modifying events
# include
# include

# Define event_size (sizeof (struct inotify_event ))
# Define buf_len (1024 * (event_size + 16 ))

Int main (INT argc, char ** argv)
{
Int length, I = 0;
Int FD;
Int WD;
Char buffer [buf_len];

FD = inotify_init ();

If (FD <0 ){
Perror ("inotify_init ");
}

WD = inotify_add_watch (FD, "/home/strike ",
In_modify | in_create | in_delete );
Length = read (FD, buffer, buf_len );

If (length <0 ){
Perror ("read ");
}

While (I <length) {struct inotify_event * event = (struct inotify_event *) & buffer [I]; If (Event-> Len ){
If (Event-> mask & in_create ){
If (Event-> mask & in_isdir ){
Printf ("the directory % s was created. \ n", event-> name );
}
Else {
Printf ("the file % s was created. \ n", event-> name );
}
}
Else if (Event-> mask & in_delete ){
If (Event-> mask & in_isdir ){
Printf ("the directory % s was deleted. \ n", event-> name );
}
Else {
Printf ("the file % s was deleted. \ n", event-> name );
}
}
Else if (Event-> mask & in_modify ){
If (Event-> mask & in_isdir ){
Printf ("the directory % s was modified. \ n", event-> name );
}
Else {
Printf ("the file % s was modified. \ n", event-> name );
}
}
}
I + = event_size + Event-> Len;
}

(Void) inotify_rm_watch (FD, WD );
(Void) Close (FD );

Exit (0 );
}
This application uses FD = inotify_init (); To create an inotify instance, add a monitor to Monitor modifications, new files, and corrupted files in/home/strike (by WD = inotify_add_watch (...) ). The read () method is blocked until one or more warnings arrive. Warning details-each file and each event-are sent in the form of a byte stream; therefore, the loop in the application replaces byte flow with a series of event structures.
In the/usr/include/sys/inotify. H. file, you can find the definition of the event structure, which is a C structure, as shown in Listing 2.
List 2. Definitions of event Structures
Struct inotify_event
{
Int WD;/* The watch descriptor */
Uint32_t mask;/* Watch mask */
Uint32_t cookie;/* a cookie to tie two events together */
Uint32_t Len;/* the length of the filename found in the Name field */
Char name _ flexarr;/* the name of the file, padding to the end with nuls */
}
The WD field is the monitor associated with the event. If each inotify has more than one instance, you can use this field to determine how to continue the subsequent processing. The mask FIELD consists of several parts, which indicate what happened. Test each part separately.
When you move a file from one directory to another, you can use cookies to bind two events together. Inotify generates two mobile events-for the source and target directories respectively-and binds them together by setting cookies. To monitor a mobile operation, you must specify in_moved_from or in_moved_to, or use a short in_move command to monitor two operations. Use in_moved_from and in_moved_to to test the event type.
Finally, name and Len contain the name of the file (but not the path) and the length of the name of the affected file.
Build sample application code
To build the code, change the directory/home/strike to your home directory, save the code to a file, and then call the C compiler-GCC in most Linux systems. Then, run the executable file, as shown in listing 3.
Listing 3. Run the executable file
% CC-O watcher. c
%./Watcher
When the monitor program is running, open the second terminal window and use touch, cat, and RM to change the content of the main directory, as shown in Listing 4. After that, restart your new application.
Listing 4. Using touch, cat, and RM
% Cd $ home
% Touch a B c
The file a was created.
The file B was created.
The file C was created.

%./Watcher &
% RM A B C
The file a was deleted.
The file B was deleted.
The file C was deleted.

%./Watcher &
% Touch a B c
The file a was created.
The file B was created.
The file C was created.

%./Watcher &
% CAT/etc/passwd>
The file a was modified.

%./Watcher &
% Mkdir d
The Directory D was created.
Try other available monitoring tags. To capture changes to permissions, add in_attrib to the mask.
Tips for using inotify
You can also use select (), pselect (), Poll (), and epoll () to avoid blocking. It is useful if you want to use monitoring as part of the main event processing loop of a graphic application, or as part of the daemon that monitors other input connections. Add the inotify descriptor to this set of descriptors for concurrent monitoring. Listing 5 shows the standard form of select.
Listing 5. Standard Form of select ()
Int return_value;
Fd_set descriptors;
Struct timeval time_to_wait;

Fd_zero (& descriptors );
Fd_set (..., & descriptors );
Fd_set (FD, & descriptors );

...

Time_to_wait. TV _sec = 3;
Time. to_waittv_usec = 0;

Return_value = select (FD + 1, & descriptors, null, null, & time_to_wait );

If (return_value <0 ){
/* Error */
}

Else if (! Return_value ){
/* Timeout */
}

Else if (fd_isset (FD, & descriptors )){
/* Process the inotify events */
...
}

Else if...
The Select () method suspends the program during time_to_wait. However, if any file descriptor of this group of descriptors is active during this delay, the execution program will be resumed immediately. Otherwise, the call times out, allowing the application to execute other processes, such as responding to mouse or Keyboard Events in the graphical user interface (GUI) tool.
The following are other tips for using inotify:
If a file or directory under monitoring is deleted, ITS Monitor is also automatically deleted (after the deletion event is triggered ).
If you monitor files or directories on an unmounted file system, the monitor receives an unmount event before deleting all affected monitors.
Add the in_oneshot flag to the monitor tag and set a one-time warning. The warning will be deleted after it is sent.
To modify an event, you must provide the same path name and different tags. The new monitor replaces the old monitor.
Considering its practicality, it is impossible to exhaust the monitor of any inotify instance. However, you may exhaust the space of the event queue, depending on the frequency of processing the event. An in_q_overflow event occurs when the queue overflows.
The close () method destroys inotify instances and all associated monitors, and clears all wait events in the queue.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.