linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* udev patch
@ 2006-12-09 18:04 Stefanos Harhalakis
  2006-12-09 19:42 ` Bryan Kadzban
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Stefanos Harhalakis @ 2006-12-09 18:04 UTC (permalink / raw)
  To: linux-hotplug


[-- Attachment #1.1.1: Type: text/plain, Size: 1107 bytes --]

Hi there,

  Currently udev does not reread changed rule files when using symlinks. 
Debian uses the symlink approach resulting to something like this:

 020_permissions.rules -> ../permissions.rules
 025_libgphoto2.rules -> ../libgphoto2.rules

  Because udev uses inotify on the rules directory it cannot detect changes to 
the destination file of a link. The attached patch solves this problem by 
using inotify on the directory where each symlink destination resides.

  I've tried using inotify on the destination filenames but this doesn't work 
as expected. For example vi will unlink and recreate the files. This means 
that the symlink will not point anywere for some time which is enough for 
udev to loose the destination. After that the link needs to be rechecked 
which is not possible (and efficient).

  Please consider the attached patch since it removes the need  
of 'udevcontrol reload_rules' when working with symlinks. 

  If I have to set a license for the patch the it is GPLv2.

Thanks in advance
Harhalakis Stefanos

p.s. CC replies
p.s.2. Be gentle :-)

[-- Attachment #1.1.2: patch-inotify_links.diff --]
[-- Type: text/x-diff, Size: 3852 bytes --]

diff -ru udev-103.orig/udevd.c udev-103/udevd.c
--- udev-103.orig/udevd.c	2006-10-20 15:43:35.000000000 +0300
+++ udev-103/udevd.c	2006-12-09 19:42:09.432522000 +0200
@@ -929,6 +929,100 @@
 	}
 }
 
+static void check_link(const char *filename)
+{
+	struct stat	stats;
+	struct stat	lstats;
+	char		fn[PATH_SIZE+1];
+	char		fn2[PATH_SIZE*2+3];
+	char		*p;
+	ssize_t		sz;
+
+	if (lstat(filename, &lstats) != 0)
+	{
+		err("could not read '%s': %s", filename, strerror(errno));
+		return;
+	}
+
+	/* Check if it is a link */
+	if (!S_ISLNK(lstats.st_mode))
+		return;
+
+	/* Get the destination */
+	dbg("found link: %s", filename);
+	sz=readlink(filename, fn, PATH_SIZE);
+	if (sz>=PATH_SIZE)
+	{
+		err("oversized link destination of '%s'", filename);
+		return;
+	}
+
+	fn[sz]=0;
+
+	/* Form the full destination path */
+	if (fn[0]=='/')
+	{
+		strcpy(fn2, fn);
+	} else
+	{
+		snprintf(fn2, PATH_SIZE*2+2, "%s/%s", udev_rules_filename, fn);
+		fn2[PATH_SIZE*2+2]=0;
+	}
+
+	/* Check if destination if a file */
+	stat(fn2, &stats);
+	if (!S_ISREG(stats.st_mode))
+		return;
+
+	/* Find the parent directory */
+	p=fn2+strlen(fn2);
+
+	while (p>=fn2)
+	{
+		if (*p=='/')
+		{
+			*p=0;
+			break;
+		}
+		p--;
+	}
+
+	if (p==fn2)
+		err("failed to get parrent directory of '%s'", fn2);
+
+	dbg("adding notify for:'%s'", fn2);
+	inotify_add_watch(inotify_fd, fn2, IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
+}
+
+static void start_inotify(void)
+{
+	struct name_entry	*name_loop, *name_tmp;
+
+	/* watch rules directory */
+	inotify_fd = inotify_init();
+	if (inotify_fd >= 0)
+	{
+		inotify_add_watch(inotify_fd, udev_rules_filename, IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
+	} else if (errno == ENOSYS)
+	{
+		err("the kernel does not support inotify, udevd can't monitor configuration file changes");
+		return;
+	} else
+	{
+		err("inotify_init failed: %s", strerror(errno));
+		return;
+	}
+
+	LIST_HEAD(name_list);
+
+	add_matching_files(&name_list, udev_rules_filename, RULEFILE_SUFFIX);
+	list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) {
+		check_link(name_loop->name);
+		list_del(&name_loop->node);
+		free(name_loop);
+	}
+}
+
 int main(int argc, char *argv[], char *envp[])
 {
 	int retval;
@@ -1101,14 +1195,7 @@
 	sigaction(SIGCHLD, &act, NULL);
 	sigaction(SIGHUP, &act, NULL);
 
-	/* watch rules directory */
-	inotify_fd = inotify_init();
-	if (inotify_fd >= 0)
-		inotify_add_watch(inotify_fd, udev_rules_filename, IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
-	else if (errno == ENOSYS)
-		err("the kernel does not support inotify, udevd can't monitor configuration file changes");
-	else
-		err("inotify_init failed: %s", strerror(errno));
+	start_inotify();
 
 	/* maximum limit of forked childs */
 	value = getenv("UDEVD_MAX_CHILDS");
@@ -1145,15 +1232,15 @@
 	if (debug_trace)
 		putenv("DEBUG=1");
 
-	maxfd = udevd_sock;
-	maxfd = UDEV_MAX(maxfd, uevent_netlink_sock);
-	maxfd = UDEV_MAX(maxfd, signal_pipe[READ_END]);
-	maxfd = UDEV_MAX(maxfd, inotify_fd);
-
 	while (!udev_exit) {
 		struct udevd_uevent_msg *msg;
 		int fdcount;
 
+		maxfd = udevd_sock;
+		maxfd = UDEV_MAX(maxfd, uevent_netlink_sock);
+		maxfd = UDEV_MAX(maxfd, signal_pipe[READ_END]);
+		maxfd = UDEV_MAX(maxfd, inotify_fd);
+
 		FD_ZERO(&readfds);
 		FD_SET(signal_pipe[READ_END], &readfds);
 		FD_SET(udevd_sock, &readfds);
@@ -1209,6 +1296,12 @@
 		/* rules changed, set by inotify or a HUP signal */
 		if (reload_config) {
 			reload_config = 0;
+			/* Restart inotify to handle possible file changes */
+			if (inotify_fd>0)
+			{
+				close(inotify_fd);
+				start_inotify();
+			}
 			udev_rules_cleanup(&rules);
 			udev_rules_init(&rules, 1);
 		}

[-- Attachment #1.2: Type: application/pgp-signature, Size: 189 bytes --]

[-- Attachment #2: Type: text/plain, Size: 347 bytes --]

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

[-- Attachment #3: Type: text/plain, Size: 226 bytes --]

_______________________________________________
Linux-hotplug-devel mailing list  http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-12-14 19:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-09 18:04 udev patch Stefanos Harhalakis
2006-12-09 19:42 ` Bryan Kadzban
2006-12-10 13:53 ` Stefanos Harhalakis
2006-12-10 19:01 ` Bryan Kadzban
2006-12-14 19:10 ` Marco d'Itri

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).