[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: File change notification


Javier Fernandez-Ivern wrote:

> R$B|d(Biger Klaehn wrote:
>
>> I have been wondering for some time why there is no decent file 
>> change notification mechanism in linux. Is there some deep 
>> philosophical reason for this, or is it just that nobody has found 
>> the time to implement it? If it is the latter, I am willing to 
>> implement it as long there is a chance to get this accepted into the 
>> mainstream kernel.
>
>
> Well, there's fam.  But AFAIK that's all done in user space, and your 
> approach would be significantly more efficient (as a matter of fact, 
> fam could be modified to use your change device as a first level of 
> notification.)
>
Fam is a user space library that has some nice features such as network 
transparent change notification. It currently uses the dnotify mechanism 
if the underlying kernel supports it, but as I mentioned the dnotify 
mechanism requires an open file handle and works only for single 
directories. If the underlying os does not support dnotify, fam resorts 
to polling for file changes (yuk!).

When I have the basics worked out for the new mechanism, one thing I 
would like to do is to modify the fam library to use it. That would be a 
good way to test it, and it would also immediately benefit the big 
desktop environments which use fam.

> I'll be interested in testing this, or (if you wish) help get it done. 
> I'm a kernel hacking newbie at the moment, but I have tinkered around 
> enough with the VFS to be able to work on this.  Up to you.
>
Any help is appreciated. At the moment I am quite happy about what is 
being logged, but I am not sure how to best expose this to the 
interested user space processes. A device was the easiest way, and so 
that is what I used. Other possibilities would be a file in /proc or 
something completely different. I got the impression that dbus might be 
useful for this, but I have no idea how to use it.

If you want to help me, just apply the patch and see wether it works for 
you. You could also take a look at the code and see if you see something 
completely broken.

best regards and a happy new year,

    R$B|d(Biger

p.s. I attached a small test program. It just reads the contents of the 
/dev/inotify device and prints them in (somewhat) human readable form. 
For example to watch for changes in .txt files I would use inotify_test 
| grep txt. This would print out a line whenever a txt file anywhere on 
a system has been created or changed.
/*
 * Inode notification for Linux
 *
 * Copyright (C) 2003,2004 R$B|d(Biger Klaehn
 */

#define IN_ACCESS	0x00000001	/* Node accessed */
#define IN_MODIFY	0x00000002	/* Node modified */
#define IN_CREATE	0x00000004	/* Node created */
#define IN_DELETE	0x00000008	/* Node removed */
#define IN_RENAME	0x00000010	/* Node renamed */
#define IN_ATTRIB	0x00000020	/* Node changed attibutes */
#define DNAME_LEN 32

typedef struct
{
	unsigned long event;
	unsigned long file_ino;
	unsigned long src_ino;
	unsigned long dst_ino;
	unsigned char name[DNAME_LEN];
} in_info;
#include <stdio.h>
#include "inotify.h"

void geteventname(unsigned long event,char *buffer,int n) 
{
	unsigned long events[6]=
	{
		IN_ACCESS,
		IN_MODIFY,
		IN_CREATE,
		IN_DELETE,
		IN_RENAME,
		IN_ATTRIB
	};
	const char *names[6]=
	{
		"IN_ACCESS",
		"IN_MODIFY",
		"IN_CREATE",
		"IN_DELETE",
		"IN_RENAME",
		"IN_ATTRIB"
	};
	int i;
	strncpy(buffer,"",n);
	for(i=0;i<6;i++)
	{
		if(event&events[i])
		{
			if(strlen(buffer)>0)
				strncat(buffer,"|",n);
			strncat(buffer,names[i],n);
		}
	}
}

int main()
{
	FILE *file;
	in_info info;
	int len;
	char eventname[256];
	file=fopen("/dev/inotify","rb");
	if(!file)
	{
		printf("Error: could not open /dev/inotify!\n");
		return -1;
	}

	while(1)
	{
		len=fread(&info,1,sizeof(info),file);
		if(len==sizeof(info)) {
			info.name[DNAME_LEN-1]=0;
			geteventname(info.event,eventname,255);	
			printf("%s %lu %lu %lu %s\n",
				eventname,
				info.file_ino,
				info.src_ino,
				info.dst_ino,
				info.name);
		}

		usleep(200);
	}
	fclose(file);
}

$B$3$N>pJs$,$"$J$?$NC5$7$F$$$?$b$N$+$I$&$+A*Br$7$F$/$@$5$$!#(B
yes/$B$^$5$K$3$l$@!*(B   no/$B0c$&$J$!(B   part/$B0lIt8+$D$+$C$?(B   try/$B$3$l$G;n$7$F$_$k(B

$B$"$J$?$,C5$7$F$$$?>pJs$O$I$N$h$&$J$3$H$+!"$4<+M3$K5-F~2<$5$$!#FC$K!V$^$5$K$3$l$@!*!W$H8@$&>l9g$O5-F~$r$*4j$$$7$^$9!#(B
$BNc(B:$B!VJ#?t$N%^%7%s$+$i(BCATV$B7PM3$G(Bipmasquerade$B$rMxMQ$7$F(BWeb$B$r;2>H$7$?$$>l9g$N@_Dj$K$D$$$F!W(B
Follow-Ups: References: