]> err.no Git - systemd/commitdiff
move default rules from /etc/udev/rules.d/ to /lib/udev/rules.d/
authorKay Sievers <kay.sievers@vrfy.org>
Fri, 18 Jul 2008 13:56:03 +0000 (15:56 +0200)
committerKay Sievers <kay.sievers@vrfy.org>
Fri, 18 Jul 2008 13:56:03 +0000 (15:56 +0200)
None of these rules is supposed to be changed by users, so move
them out of /etc. Custom rules, and automatically generated rules
stay in /etc. All rules are still processed in lexical order,
regardless which directory they live in.

50 files changed:
Makefile
extras/cdrom_id/Makefile
extras/edd_id/Makefile
extras/fstab_import/Makefile
extras/rule_generator/Makefile
rules/debian/50-udev.rules [moved from etc/udev/debian/50-udev.rules with 100% similarity]
rules/debian/60-persistent-input.rules [moved from etc/udev/debian/60-persistent-input.rules with 100% similarity]
rules/debian/60-persistent-storage-tape.rules [moved from etc/udev/debian/60-persistent-storage-tape.rules with 100% similarity]
rules/debian/60-persistent-storage.rules [moved from etc/udev/debian/60-persistent-storage.rules with 100% similarity]
rules/debian/60-persistent-v4l.rules [moved from etc/udev/debian/60-persistent-v4l.rules with 100% similarity]
rules/debian/75-cd-aliases-generator.rules [moved from etc/udev/debian/75-cd-aliases-generator.rules with 100% similarity]
rules/debian/75-persistent-net-generator.rules [moved from etc/udev/debian/75-persistent-net-generator.rules with 100% similarity]
rules/debian/80-drivers.rules [moved from etc/udev/debian/80-drivers.rules with 100% similarity]
rules/debian/91-permissions.rules [moved from etc/udev/debian/91-permissions.rules with 100% similarity]
rules/debian/95-late.rules [moved from etc/udev/debian/95-late.rules with 100% similarity]
rules/frugalware/50-udev-default.rules [moved from etc/udev/frugalware/50-udev-default.rules with 100% similarity]
rules/frugalware/64-device-mapper.rules [moved from etc/udev/frugalware/64-device-mapper.rules with 100% similarity]
rules/gentoo/30-kernel-compat.rules [moved from etc/udev/gentoo/30-kernel-compat.rules with 100% similarity]
rules/gentoo/40-gentoo.rules [moved from etc/udev/gentoo/40-gentoo.rules with 100% similarity]
rules/gentoo/40-video.rules [moved from etc/udev/gentoo/40-video.rules with 100% similarity]
rules/gentoo/65-permissions.rules [moved from etc/udev/gentoo/65-permissions.rules with 100% similarity]
rules/gentoo/90-network.rules [moved from etc/udev/gentoo/90-network.rules with 100% similarity]
rules/packages/40-alsa.rules [moved from etc/udev/packages/40-alsa.rules with 100% similarity]
rules/packages/40-ia64.rules [moved from etc/udev/packages/40-ia64.rules with 100% similarity]
rules/packages/40-pilot-links.rules [moved from etc/udev/packages/40-pilot-links.rules with 100% similarity]
rules/packages/40-ppc.rules [moved from etc/udev/packages/40-ppc.rules with 100% similarity]
rules/packages/40-s390.rules [moved from etc/udev/packages/40-s390.rules with 100% similarity]
rules/packages/40-zaptel.rules [moved from etc/udev/packages/40-zaptel.rules with 100% similarity]
rules/packages/64-device-mapper.rules [moved from etc/udev/packages/64-device-mapper.rules with 100% similarity]
rules/packages/64-md-raid.rules [moved from etc/udev/packages/64-md-raid.rules with 100% similarity]
rules/redhat/40-redhat.rules [moved from etc/udev/redhat/40-redhat.rules with 100% similarity]
rules/redhat/95-pam-console.rules [moved from etc/udev/redhat/95-pam-console.rules with 100% similarity]
rules/rules.d/50-udev-default.rules [moved from etc/udev/rules.d/50-udev-default.rules with 100% similarity]
rules/rules.d/60-persistent-input.rules [moved from etc/udev/rules.d/60-persistent-input.rules with 100% similarity]
rules/rules.d/60-persistent-storage-tape.rules [moved from etc/udev/rules.d/60-persistent-storage-tape.rules with 100% similarity]
rules/rules.d/60-persistent-storage.rules [moved from etc/udev/rules.d/60-persistent-storage.rules with 100% similarity]
rules/rules.d/60-persistent-v4l.rules [moved from etc/udev/rules.d/60-persistent-v4l.rules with 100% similarity]
rules/rules.d/80-drivers.rules [moved from etc/udev/rules.d/80-drivers.rules with 100% similarity]
rules/rules.d/95-udev-late.rules [moved from etc/udev/rules.d/95-udev-late.rules with 100% similarity]
rules/slackware/udev.rules [moved from etc/udev/slackware/udev.rules with 100% similarity]
rules/suse/40-suse.rules [moved from etc/udev/suse/40-suse.rules with 100% similarity]
rules/suse/64-device-mapper.rules [moved from etc/udev/suse/64-device-mapper.rules with 100% similarity]
test/udev-test.pl
udev.7
udev.conf [moved from etc/udev/udev.conf with 93% similarity]
udev.h
udev.xml
udev_config.c
udev_rules_parse.c
udevd.c

index 075389b6ead1c9aba809459ccd59460a11f75617..ed2b381d07234e1d35f5ed346f4fc2376e5d2c28 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -190,9 +190,7 @@ udev_version.h:
        $(E) "  GENHDR  " $@
        $(Q) echo "/* Generated by make. */" > $@
        $(Q) echo \#define UDEV_VERSION         \"$(VERSION)\" >> $@
-       $(Q) echo \#define UDEV_ROOT            \"$(udevdir)\" >> $@
        $(Q) echo \#define UDEV_CONFIG_FILE     \"$(configdir)/udev.conf\" >> $@
-       $(Q) echo \#define UDEV_RULES_DIR       \"$(configdir)/rules.d\" >> $@
 
 # man pages
 %.8 %.7: %.xml
@@ -220,15 +218,12 @@ clean:
 .PHONY: clean
 
 install-config:
+       $(INSTALL) -d $(DESTDIR)$(libudevdir)/rules.d
        $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d
        @ if [ ! -r $(DESTDIR)$(configdir)/udev.conf ]; then \
-               $(INSTALL_DATA) etc/udev/udev.conf $(DESTDIR)$(configdir); \
+               $(INSTALL_DATA) udev.conf $(DESTDIR)$(configdir); \
        fi
-       @ for i in etc/udev/rules.d/*.rules; do \
-               if [ ! -r $(DESTDIR)$(configdir)/rules.d/$$(basename $$i) ]; then \
-                       $(INSTALL_DATA) $$i $(DESTDIR)$(configdir)/rules.d; \
-               fi \
-       done
+       cp rules/rules.d/* $(DESTDIR)$(libudevdir)/rules.d
        @ extras="$(EXTRAS)"; for target in $$extras; do \
                $(MAKE) -C $$target $@ || exit 1; \
        done;
index caab2beaf5451be43180a182f1eedd5fcb786f58..ec03d1fce21f550f2f6f5929a7184aed8797d2d2 100644 (file)
@@ -51,13 +51,13 @@ clean:
 install-bin: all
        $(INSTALL) -d $(DESTDIR)$(libudevdir)
        $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
-       $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d
-       $(INSTALL_DATA) 60-cdrom_id.rules $(DESTDIR)$(configdir)/rules.d/60-cdrom_id.rules
+       $(INSTALL) -d $(DESTDIR)$(libudevdir)/rules.d
+       $(INSTALL_DATA) 60-cdrom_id.rules $(DESTDIR)$(libudevdir)/rules.d/60-cdrom_id.rules
 .PHONY: install-bin
 
 uninstall-bin:
        - rm $(DESTDIR)$(libudevdir)/$(PROG)
-       - rm $(DESTDIR)$(configdir)/rules.d/60-cdrom_id.rules
+       - rm $(DESTDIR)$(libudevdir)/rules.d/60-cdrom_id.rules
 .PHONY: uninstall-bin
 
 install-man:
index f17a5b8c6536226f08d744bda9e1cd3b327227f2..0126b859eecbc5ae238a6bc59ffd525f6bc1a2e0 100644 (file)
@@ -51,13 +51,13 @@ clean:
 install-bin: all
        $(INSTALL) -d $(DESTDIR)$(libudevdir)
        $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
-       $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d/
-       $(INSTALL_DATA) 61-persistent-storage-edd.rules $(DESTDIR)$(configdir)/rules.d/61-persistent-storage-edd.rules
+       $(INSTALL) -d $(DESTDIR)$(libudevdir)/rules.d/
+       $(INSTALL_DATA) 61-persistent-storage-edd.rules $(DESTDIR)$(libudevdir)/rules.d/61-persistent-storage-edd.rules
 .PHONY: install-bin
 
 uninstall-bin:
        - rm $(DESTDIR)$(libudevdir)/$(PROG)
-       - rm $(DESTDIR)$(configdir)/rules.d/61-persistent-storage-edd.rules
+       - rm $(DESTDIR)$(libudevdir)/rules.d/61-persistent-storage-edd.rules
 .PHONY: uninstall-bin
 
 install-man:
index 23448f321736d3a4e602711f26b08b5a7d4ba601..3f65aa3f64642d4a57a1759bb98310a900205e85 100644 (file)
@@ -50,12 +50,12 @@ clean:
 
 install-bin: all
        $(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
-       $(INSTALL_DATA) 79-fstab_import.rules $(DESTDIR)$(configdir)/rules.d/79-fstab_import.rules
+       $(INSTALL_DATA) 79-fstab_import.rules $(DESTDIR)$(libudevdir)/rules.d/79-fstab_import.rules
 .PHONY: install-bin
 
 uninstall-bin:
        - rm $(DESTDIR)$(libudevdir)/$(PROG)
-       - rm $(DESTDIR)$(configdir)/rules.d/79-fstab_import.rules
+       - rm $(DESTDIR)$(libudevdir)/rules.d/79-fstab_import.rules
 .PHONY: uninstall-bin
 
 install-man:
index d6f1265eb97116b832c2a995ed7b6a1624040808..e236ca77f0c0a70d5e6e1517a3f70b3601f078a5 100644 (file)
@@ -41,11 +41,11 @@ install-bin: all
        $(INSTALL_DATA) rule_generator.functions $(DESTDIR)$(libudevdir)/rule_generator.functions
        $(INSTALL_SCRIPT) write_cd_rules $(DESTDIR)$(libudevdir)/write_cd_rules
        $(INSTALL_SCRIPT) write_net_rules $(DESTDIR)$(libudevdir)/write_net_rules
-       $(INSTALL) -d  $(DESTDIR)$(configdir)/rules.d
+       $(INSTALL) -d  $(DESTDIR)$(libudevdir)/rules.d
        $(INSTALL_DATA) 75-cd-aliases-generator.rules \
-               $(DESTDIR)$(configdir)/rules.d/75-cd-aliases-generator.rules
+               $(DESTDIR)$(libudevdir)/rules.d/75-cd-aliases-generator.rules
        $(INSTALL_DATA) 75-persistent-net-generator.rules \
-               $(DESTDIR)$(configdir)/rules.d/75-persistent-net-generator.rules
+               $(DESTDIR)$(libudevdir)/rules.d/75-persistent-net-generator.rules
 .PHONY: install-bin
 
 uninstall-bin:
index 72b4aef6bc67b49065535f5b3a9da28e3e63682d..f7f68a1416593a31ee6fac980b5781323ba1ac77 100755 (executable)
@@ -23,7 +23,7 @@ use strict;
 my $PWD                = $ENV{PWD};
 my $sysfs      = "sys/";
 my $udev_bin   = "../test-udev";
-my $udev_root  = "udev-root/"; # !!! directory will be removed !!!
+my $udev_root  = "udev-root/";
 my $udev_conf  = "udev-test.conf";
 my $udev_rules = "udev-test.rules";
 
@@ -1847,12 +1847,12 @@ if (!($<==0)) {
 }
 
 # prepare
-make_udev_root ();
+make_udev_root();
 
 # create config file
 open CONF, ">$udev_conf" || die "unable to create config file: $udev_conf";
 print CONF "udev_root=\"$udev_root\"\n";
-print CONF "udev_rules=\"$udev_rules\"\n";
+print CONF "udev_rules=\"$PWD\"\n";
 print CONF "udev_log=\"info\"\n";
 close CONF;
 
diff --git a/udev.7 b/udev.7
index 4bf625df6ddb2a5b2805381c8d8e22d47e6d0538..c4ca28603d4b7c09d558f7b9d9ed8b230575403c 100644 (file)
--- a/udev.7
+++ b/udev.7
@@ -25,8 +25,10 @@ and receives uevents directly from the kernel if a device is added or removed fr
 If udev receives a device event, it matches its configured rules against the available device attributes provided in sysfs to identify the device\. Rules that match may provide additional device information or specify a device node name and multiple symlink names and instruct udev to run additional programs as part of the device event handling\.
 .SH "CONFIGURATION"
 .PP
-All udev configuration files are placed in
-\fI/etc/udev/*\fR\. Every file consists of a set of lines of text\. All empty lines or lines beginning with \'#\' will be ignored\.
+udev configuration files are placed in
+\fI/etc/udev/\fR
+and
+\fI/lib/udev/\fR\. All empty lines, or lines beginning with \'#\' will be ignored\.
 .SS "Configuration file"
 .PP
 udev expects its main configuration file at
@@ -38,13 +40,6 @@ Specifies where to place the device nodes in the filesystem\. The default value
 \fI/dev\fR\.
 .RE
 .PP
-\fBudev_rules\fR
-.RS 4
-The name of the udev rules file or directory to look for files with the suffix
-\fI\.rules\fR\. Multiple rule files are read in lexical order\. The default value is
-\fI/etc/udev/rules\.d\fR\.
-.RE
-.PP
 \fBudev_log\fR
 .RS 4
 The logging priority\. Valid values are the numerical syslog priorities or their textual representations:
@@ -55,9 +50,11 @@ and
 .RE
 .SS "Rules files"
 .PP
-The udev rules are read from the files located in the
-\fI/etc/udev/rules\.d\fR
-directory or at the location specified value in the configuration file\. Every line in the rules file contains at least one key value pair\. There are two kind of keys, match and assignment keys\. If all match keys are matching against its value, the rule gets applied and the assign keys get the specified value assigned\.
+The udev rules are read from the files located in the default rules directory
+\fI/lib/udev/rules\.d/\fR, the custom rules directory
+\fI/etc/udev/rules\.d/\fR
+and the temporary rules directory
+\fI/dev/\.udev/rules\.d/\fR\. All rule files are sorted and processed in lexical order, regardless in which of these directories they live\. Every line in the rules file contains at least one key value pair\. There are two kind of keys, match and assignment keys\. If all match keys are matching against its value, the rule gets applied and the assign keys get the specified value assigned\.
 .PP
 A matching rule may specify the name of the device node, add a symlink pointing to the node, or run a specified program as part of the event handling\. If no matching rule is found, the default device node name is used\.
 .PP
similarity index 93%
rename from etc/udev/udev.conf
rename to udev.conf
index e6ef0814bfa48384bceaa015fd0d46cbe67539ee..998b4a7d18bc91c9e820861d377d024865db42a3 100644 (file)
+++ b/udev.conf
@@ -1,7 +1,4 @@
-# udev.conf
-
 # The initial syslog(3) priority: "err", "info", "debug" or its
 # numerical equivalent. For runtime debugging, the daemons internal
 # state can be changed with: "udevadm control --log_priority=<value>".
 udev_log="err"
-
diff --git a/udev.h b/udev.h
index e1b7ac0d8ac85b6a94c58f4a8dbad8eeba6ed692..5ecef4abbda3ae17778b0ac9f3f077e934555c6c 100644 (file)
--- a/udev.h
+++ b/udev.h
 #define READ_END                               0
 #define WRITE_END                              1
 
+#define UDEV_ROOT                              "/dev"
 #define DB_DIR                                 ".udev/db"
 #define DB_NAME_INDEX_DIR                      ".udev/names"
+#define RULES_LIB_DIR                          "/lib/udev/rules.d"
 #define RULES_DYN_DIR                          ".udev/rules.d"
+#define RULES_ETC_DIR                          "/etc/udev/rules.d"
 
 struct udev_rules;
 
index e1986799686f366645f1da45f33f7cd01e6e7aaf..c740c0d80705c22b9167f80f1fb93a9b9e148264 100644 (file)
--- a/udev.xml
+++ b/udev.xml
@@ -40,9 +40,9 @@
       </refsect1>
 
       <refsect1><title>CONFIGURATION</title>
-        <para>All udev configuration files are placed in <filename>/etc/udev/*</filename>.
-        Every file consists of a set of lines of text. All empty lines or lines beginning
-        with '#' will be ignored.</para>
+        <para>udev configuration files are placed in <filename>/etc/udev/</filename>
+        and <filename>/lib/udev/</filename>. All empty lines, or lines beginning with
+        '#' will be ignored.</para>
 
         <refsect2><title>Configuration file</title>
           <para>udev expects its main configuration file at <filename>/etc/udev/udev.conf</filename>.
               </listitem>
             </varlistentry>
 
-            <varlistentry>
-              <term><option>udev_rules</option></term>
-              <listitem>
-                <para>The name of the udev rules file or directory to look for files
-                with the suffix <filename>.rules</filename>. Multiple rule files are
-                read in lexical order. The default value is
-                <filename>/etc/udev/rules.d</filename>.</para>
-              </listitem>
-            </varlistentry>
-
             <varlistentry>
               <term><option>udev_log</option></term>
               <listitem>
 
         <refsect2><title>Rules files</title>
           <para>The udev rules are read from the files located in the
-          <filename>/etc/udev/rules.d</filename> directory or at the location specified
-          value in the configuration file. Every line in the rules file contains at least
+          default rules directory <filename>/lib/udev/rules.d/</filename>,
+          the custom rules directory <filename>/etc/udev/rules.d/</filename>
+          and the temporary rules directory <filename>/dev/.udev/rules.d/</filename>.
+          All rule files are sorted and processed in lexical order, regardless
+          in which of these directories they live. Every line in the rules file contains at least
           one key value pair. There are two kind of keys, match and assignment keys.
           If all match keys are matching against its value, the rule gets applied and the
           assign keys get the specified value assigned.</para>
index 42190945fc18b7ace35e86deb4b094d8a5eeb574..55f0361dd2ae46c5bce0703878d176c11c44d496 100644 (file)
@@ -164,9 +164,9 @@ void udev_config_init(void)
 {
        const char *env;
 
-       strcpy(udev_root, UDEV_ROOT);
        strcpy(udev_config_filename, UDEV_CONFIG_FILE);
-       strcpy(udev_rules_dir, UDEV_RULES_DIR);
+       strcpy(udev_root, UDEV_ROOT);
+       udev_rules_dir[0] = '\0';
        udev_log_priority = LOG_ERR;
        udev_run = 1;
 
@@ -195,6 +195,6 @@ void udev_config_init(void)
 
        dbg("UDEV_CONFIG_FILE='%s'\n", udev_config_filename);
        dbg("udev_root='%s'\n", udev_root);
-       dbg("udev_rules='%s'\n", udev_rules_dir);
+       dbg("udev_rules_dir='%s'\n", udev_rules_dir);
        dbg("udev_log=%d\n", udev_log_priority);
 }
index bdaf55bd4851a21b82890067da8c422dbf5ff175..999af3b85e1ceaf3978656779f8168b8943936f1 100644 (file)
@@ -727,53 +727,53 @@ int udev_rules_init(struct udev_rules *rules, int resolve_names)
        struct stat statbuf;
        char filename[PATH_MAX];
        LIST_HEAD(name_list);
-       LIST_HEAD(dyn_list);
+       LIST_HEAD(sort_list);
        struct name_entry *name_loop, *name_tmp;
-       struct name_entry *dyn_loop, *dyn_tmp;
+       struct name_entry *sort_loop, *sort_tmp;
        int retval = 0;
 
        memset(rules, 0x00, sizeof(struct udev_rules));
        rules->resolve_names = resolve_names;
 
-       /* read main config from single file or all files in a directory */
-       if (stat(udev_rules_dir, &statbuf) != 0)
-               return -1;
-       if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
-               dbg("parse single rules file '%s'\n", udev_rules_dir);
-               name_list_add(&name_list, udev_rules_dir, 1);
+       if (udev_rules_dir[0] != '\0') {
+               /* custom rules location for testing */
+               add_matching_files(&name_list, udev_rules_dir, RULESFILE_SUFFIX);
        } else {
-               dbg("parse rules directory '%s'\n", udev_rules_dir);
-               retval = add_matching_files(&name_list, udev_rules_dir, RULESFILE_SUFFIX);
-       }
-
-       /* read dynamic rules directory */
-       strlcpy(filename, udev_root, sizeof(filename));
-       strlcat(filename, "/"RULES_DYN_DIR, sizeof(filename));
-       if (stat(filename, &statbuf) != 0) {
-               create_path(filename);
-               selinux_setfscreatecon(filename, NULL, S_IFDIR|0755);
-               mkdir(filename, 0755);
-               selinux_resetfscreatecon();
-       }
-       add_matching_files(&dyn_list, filename, RULESFILE_SUFFIX);
+               /* read default rules */
+               add_matching_files(&name_list, RULES_LIB_DIR, RULESFILE_SUFFIX);
+
+               /* read user/custom rules */
+               add_matching_files(&sort_list, RULES_ETC_DIR, RULESFILE_SUFFIX);
+
+               /* read dynamic/temporary rules */
+               strlcpy(filename, udev_root, sizeof(filename));
+               strlcat(filename, "/"RULES_DYN_DIR, sizeof(filename));
+               if (stat(filename, &statbuf) != 0) {
+                       create_path(filename);
+                       selinux_setfscreatecon(filename, NULL, S_IFDIR|0755);
+                       mkdir(filename, 0755);
+                       selinux_resetfscreatecon();
+               }
+               add_matching_files(&sort_list, filename, RULESFILE_SUFFIX);
 
-       /* sort dynamic rules files by basename into list of files */
-       list_for_each_entry_safe(dyn_loop, dyn_tmp, &dyn_list, node) {
-               const char *dyn_base = strrchr(dyn_loop->name, '/');
+               /* sort all rules files by basename into list of files */
+               list_for_each_entry_safe(sort_loop, sort_tmp, &sort_list, node) {
+                       const char *sort_base = strrchr(sort_loop->name, '/');
 
-               if (dyn_base == NULL)
-                       continue;
+                       if (sort_base == NULL)
+                               continue;
 
-               list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) {
-                       const char *name_base = strrchr(name_loop->name, '/');
+                       list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) {
+                               const char *name_base = strrchr(name_loop->name, '/');
 
-                       if (name_base == NULL)
-                               continue;
+                               if (name_base == NULL)
+                                       continue;
 
-                       if (strcmp(name_base, dyn_base) > 0)
-                               break;
+                               if (strcmp(name_base, sort_base) > 0)
+                                       break;
+                       }
+                       list_move_tail(&sort_loop->node, &name_loop->node);
                }
-               list_move_tail(&dyn_loop->node, &name_loop->node);
        }
 
        /* parse list of files */
diff --git a/udevd.c b/udevd.c
index d6977e9655de8442195c8ba98b9c728c3c452abc..0827a5ceb32551b41520caa4414c82b774b1483f 100644 (file)
--- a/udevd.c
+++ b/udevd.c
@@ -1142,14 +1142,23 @@ int main(int argc, char *argv[], char *envp[])
        /* watch rules directory */
        inotify_fd = inotify_init();
        if (inotify_fd >= 0) {
-               char filename[PATH_MAX];
-
-               inotify_add_watch(inotify_fd, udev_rules_dir, IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
-
-               /* watch dynamic rules directory */
-               strlcpy(filename, udev_root, sizeof(filename));
-               strlcat(filename, "/"RULES_DYN_DIR, sizeof(filename));
-               inotify_add_watch(inotify_fd, filename, IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
+               if (udev_rules_dir[0] != '\0') {
+                       inotify_add_watch(inotify_fd, udev_rules_dir,
+                                         IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
+               } else {
+                       char filename[PATH_MAX];
+
+                       inotify_add_watch(inotify_fd, RULES_LIB_DIR,
+                                         IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
+                       inotify_add_watch(inotify_fd, RULES_ETC_DIR,
+                                         IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
+
+                       /* watch dynamic rules directory */
+                       strlcpy(filename, udev_root, sizeof(filename));
+                       strlcat(filename, "/"RULES_DYN_DIR, sizeof(filename));
+                       inotify_add_watch(inotify_fd, 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 rules file changes\n");
        else