Re: inotify system call support.



On Wed, 2005-07-13 at 15:52 -0400, Robert Love wrote:

> So, inotify is now in 2.6.13-rc3.
> 
> The interface changed slightly, to use system calls.  The attached patch
> ports Beagle to the new inotify interface.

Joey had the idea of printing a message if the system call is not
defined, thus allowing us to trivially detect a non-inotify kernel and
warning the user on how to rectify.

Attached patch is updated to do just that.

	Robert Love

Index: Util/Inotify.cs
===================================================================
RCS file: /cvs/gnome/beagle/Util/Inotify.cs,v
retrieving revision 1.47
diff -u -u -r1.47 Inotify.cs
--- Util/Inotify.cs	6 Jul 2005 22:54:08 -0000	1.47
+++ Util/Inotify.cs	13 Jul 2005 20:14:23 -0000
@@ -94,7 +94,7 @@
 		}
 
 		[DllImport ("libinotifyglue")]
-		static extern void inotify_glue_init ();
+		static extern int inotify_glue_init ();
 
 		[DllImport ("libinotifyglue")]
 		static extern int inotify_glue_watch (int fd, string filename, EventType mask);
@@ -148,7 +148,7 @@
 
 		/////////////////////////////////////////////////////////////////////////////////////
 
-		static private int dev_inotify = -1;
+		static private int inotify_fd = -1;
 		static private ArrayList event_queue = new ArrayList ();
 
 		static Inotify ()
@@ -163,15 +163,13 @@
 			if (Environment.GetEnvironmentVariable ("BEAGLE_INOTIFY_VERBOSE") != null)
 				Inotify.Verbose = true;
 
-			inotify_glue_init ();
-
-			dev_inotify = Syscall.open ("/dev/inotify", OpenFlags.O_RDONLY);
-			if (dev_inotify == -1)
-				Logger.Log.Warn ("Could not open /dev/inotify");
+			inotify_fd = inotify_glue_init ();
+			if (inotify_fd == -1)
+				Logger.Log.Warn ("Could not initialize inotify");
 		}
 
 		static public bool Enabled {
-			get { return dev_inotify >= 0; }
+			get { return inotify_fd >= 0; }
 		}
 
 		/////////////////////////////////////////////////////////////////////////////////////
@@ -350,7 +348,7 @@
 					// in the wd value changing.
 					// (no need to worry about watched_by_wd being polluted with stale watches)
 					
-					wd = inotify_glue_watch (dev_inotify, path, mask | base_mask);
+					wd = inotify_glue_watch (inotify_fd, path, mask | base_mask);
 					if (wd < 0) {
 						string msg = String.Format ("Attempt to watch {0} failed!", path);
 						throw new IOException (msg);
@@ -402,7 +400,7 @@
 			if (watched.Subscribers.Count > 0)
 				return;
 
-			int retval = inotify_glue_ignore (dev_inotify, watched.Wd);
+			int retval = inotify_glue_ignore (inotify_fd, watched.Wd);
 			if (retval < 0) {
 				string msg = String.Format ("Attempt to ignore {0} failed!", watched.Path);
 				throw new IOException (msg);
@@ -423,7 +421,7 @@
 				watched.Mask |= new_mask;
 
 				int new_wd;
-				new_wd = inotify_glue_watch (dev_inotify,
+				new_wd = inotify_glue_watch (inotify_fd,
 							     watched.Path,
 							     watched.Mask | base_mask);
 
@@ -489,7 +487,7 @@
 				int nr;
 
 				// Will block while waiting for events, but with a 1s timeout.
-				inotify_snarf_events (dev_inotify, 
+				inotify_snarf_events (inotify_fd, 
 						      1, 
 						      out nr,
 						      out buffer);
Index: glue/inotify-glue.c
===================================================================
RCS file: /cvs/gnome/beagle/glue/inotify-glue.c,v
retrieving revision 1.21
diff -u -u -r1.21 inotify-glue.c
--- glue/inotify-glue.c	22 Jun 2005 22:57:11 -0000	1.21
+++ glue/inotify-glue.c	13 Jul 2005 20:14:23 -0000
@@ -33,17 +33,19 @@
 #include <errno.h>
 #include <sys/ioctl.h>
 #include <sys/select.h>
+#include <sys/types.h>
 
 #include "inotify.h"
+#include "inotify-syscalls.h"
 
-#define SYSFS_PREFIX           "/sys/class/misc/inotify"
+#define PROCFS_PREFIX           "/proc/sys/fs/inotify"
 
-#define SYSFS_MAX_USER_DEVICES  SYSFS_PREFIX "/max_user_devices"
-#define SYSFS_MAX_USER_WATCHES  SYSFS_PREFIX "/max_user_watches"
-#define SYSFS_MAX_QUEUED_EVENTS SYSFS_PREFIX "/max_queued_events"
+#define PROCFS_MAX_USER_DEVICES  PROCFS_PREFIX "/max_user_instances"
+#define PROCFS_MAX_USER_WATCHES  PROCFS_PREFIX "/max_user_watches"
+#define PROCFS_MAX_QUEUED_EVENTS PROCFS_PREFIX "/max_queued_events"
 
 /* Inotify sysfs knobs, initialized to their pre-sysfs defaults */
-static int max_user_devices = 8;
+static int max_user_instances = 8;
 static int max_user_watches = 8192;
 static unsigned int max_queued_events = 256;
 
@@ -67,53 +69,50 @@
 }
 
 
-void
+int
 inotify_glue_init (void)
 {
-	static int initialized = 0;
-	if (initialized)
+	static int fd = 0;
+	if (fd)
 		return;
-	initialized = 1;
+	fd = inotify_init ();
+	if (fd < 0) {
+		int _errno = errno;
+		perror ("inotify_init");
+		switch (_errno) {
+		case ENOSYS:
+			fprintf(stderr, "Inotify not supported!  You need a "
+				"2.6.13 kernel or later with CONFIG_INOTIFY "
+				"enabled.");
+			break;
+		}
+	}
 
-	read_int (SYSFS_MAX_USER_DEVICES, &max_user_devices);
-	read_int (SYSFS_MAX_USER_WATCHES, &max_user_watches);
-	read_int (SYSFS_MAX_QUEUED_EVENTS, &max_queued_events);
+	read_int (PROCFS_MAX_USER_DEVICES, &max_user_instances);
+	read_int (PROCFS_MAX_USER_WATCHES, &max_user_watches);
+	read_int (PROCFS_MAX_QUEUED_EVENTS, &max_queued_events);
+
+	return fd;
 }
 
 
 int
 inotify_glue_watch (int fd, const char *filename, __u32 mask)
 {
-	struct inotify_watch_request iwr;
-	int file_fd, wd;
-
-	file_fd = open (filename, O_RDONLY);
-	if (file_fd < 0) {
-		perror ("open");
-		return -1;
-	}
-	iwr.fd = file_fd;
-	iwr.mask = mask;
+	int wd;
 
-	wd = ioctl (fd, INOTIFY_WATCH, &iwr);
+	wd = inotify_add_watch (fd, filename, mask);
 	if (wd < 0) {
 		int _errno = errno;
-		perror ("ioctl");
+		perror ("inotify_add_watch");
 		switch (_errno) {
 		case ENOSPC:
-			fprintf(stderr, "Maximum watch limit hit. Try adjusting /sys/class/misc/inotify/max_user_watches\n");
-			break;
-		case EFAULT:
-			fprintf(stderr, "This usually indicates an inotify version incompatibility.\n");
-			break;
-		default:
+			fprintf(stderr, "Maximum watch limit hit. "
+				"Try adjusting " PROCFS_MAX_USER_WATCHES ".\n");
 			break;
 		}
 	}
 
-	if (close (file_fd))
-		perror ("close");
-
 	return wd;
 }
 
@@ -123,9 +122,9 @@
 {
 	int ret;
 
-	ret = ioctl (fd, INOTIFY_IGNORE, &wd);
+	ret = inotify_rm_watch (fd, wd);
 	if (ret < 0)
-		perror ("ioctl");
+		perror ("inotify_rm_watch");
 
 	return ret;
 }
Index: glue/inotify-syscalls.h
===================================================================
RCS file: glue/inotify-syscalls.h
diff -N glue/inotify-syscalls.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ glue/inotify-syscalls.h	13 Jul 2005 20:14:23 -0000
@@ -0,0 +1,29 @@
+#ifndef _LINUX_INOTIFY_SYSCALLS_H
+#define _LINUX_INOTIFY_SYSCALLS_H
+
+#include <sys/syscall.h>
+
+#if defined(__i386__)
+# define __NR_inotify_init	291
+# define __NR_inotify_add_watch	292
+# define __NR_inotify_rm_watch	293
+#else
+# error "Unsupported architecture"
+#endif
+
+static inline int inotify_init (void)
+{
+	return syscall (__NR_inotify_init);
+}
+
+static inline int inotify_add_watch (int fd, const char *name, __u32 mask)
+{
+	return syscall (__NR_inotify_add_watch, fd, name, mask);
+}
+
+static inline int inotify_rm_watch (int fd, __u32 wd)
+{
+	return syscall (__NR_inotify_rm_watch, fd, wd);
+}
+
+#endif /* _LINUX_INOTIFY_SYSCALLS_H */
Index: glue/inotify.h
===================================================================
RCS file: /cvs/gnome/beagle/glue/inotify.h,v
retrieving revision 1.15
diff -u -u -r1.15 inotify.h
--- glue/inotify.h	9 May 2005 21:52:55 -0000	1.15
+++ glue/inotify.h	13 Jul 2005 20:14:23 -0000
@@ -23,16 +23,6 @@
 	char		name[0];	/* stub for possible name */
 };
 
-/*
- * struct inotify_watch_request - represents a watch request
- *
- * Pass to the inotify device via the INOTIFY_WATCH ioctl
- */
-struct inotify_watch_request {
-	int		fd;		/* fd of filename to watch */
-	__u32		mask;		/* event mask */
-};
-
 /* the following are legal, implemented events that user-space can watch for */
 #define IN_ACCESS		0x00000001	/* File was accessed */
 #define IN_MODIFY		0x00000002	/* File was modified */
@@ -67,12 +57,6 @@
 #define IN_ALL_EVENTS	(IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \
 			 IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \
 			 IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF)
-
-#define INOTIFY_IOCTL_MAGIC	'Q'
-#define INOTIFY_IOCTL_MAXNR	2
-
-#define INOTIFY_WATCH  		_IOR(INOTIFY_IOCTL_MAGIC, 1, struct inotify_watch_request)
-#define INOTIFY_IGNORE 		_IOR(INOTIFY_IOCTL_MAGIC, 2, int)
 
 #ifdef __KERNEL__
 


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