From: Stefanos Harhalakis <v13@it.teithe.gr>
To: linux-hotplug@vger.kernel.org
Subject: udev patch
Date: Sat, 09 Dec 2006 18:04:06 +0000 [thread overview]
Message-ID: <200612092004.09587.v13@it.teithe.gr> (raw)
[-- 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
next reply other threads:[~2006-12-09 18:04 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-09 18:04 Stefanos Harhalakis [this message]
2006-12-09 19:42 ` udev patch Bryan Kadzban
2006-12-10 13:53 ` Stefanos Harhalakis
2006-12-10 19:01 ` Bryan Kadzban
2006-12-14 19:10 ` Marco d'Itri
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200612092004.09587.v13@it.teithe.gr \
--to=v13@it.teithe.gr \
--cc=linux-hotplug@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).