Monitor service directories for changes
authorColin Walters <walters@verbum.org>
Thu, 18 Feb 2010 20:33:28 +0000 (15:33 -0500)
committerColin Walters <walters@verbum.org>
Thu, 18 Feb 2010 20:33:28 +0000 (15:33 -0500)
It's not expected to have to manually SIGHUP the bus after installing
a new .service file.  Since our directory monitoring is already set
up to queue a full reload which includes service activation, simply
monitor the servicedirs too.

https://bugs.freedesktop.org/show_bug.cgi?id=23846

bus/bus.c
bus/dir-watch-inotify.c
bus/dir-watch-kqueue.c

index 8150df2..6495ae7 100644 (file)
--- a/bus/bus.c
+++ b/bus/bus.c
@@ -529,11 +529,39 @@ process_config_every_time (BusContext      *context,
 }
 
 static dbus_bool_t
+list_concat_new (DBusList **a,
+                 DBusList **b,
+                 DBusList **result)
+{
+  DBusList *link;
+
+  *result = NULL;
+
+  link = _dbus_list_get_first_link (a);
+  for (link = _dbus_list_get_first_link (a); link; link = _dbus_list_get_next_link (a, link))
+    {
+      if (!_dbus_list_append (result, link->data))
+        goto oom;
+    }
+  for (link = _dbus_list_get_first_link (b); link; link = _dbus_list_get_next_link (b, link))
+    {
+      if (!_dbus_list_append (result, link->data))
+        goto oom;
+    }
+
+  return TRUE;
+oom:
+  _dbus_list_clear (result);
+  return FALSE;
+}
+
+static dbus_bool_t
 process_config_postinit (BusContext      *context,
                         BusConfigParser *parser,
                         DBusError       *error)
 {
   DBusHashTable *service_context_table;
+  DBusList *watched_dirs = NULL;
 
   service_context_table = bus_config_parser_steal_service_context_table (parser);
   if (!bus_registry_set_service_context_table (context->registry,
@@ -545,8 +573,20 @@ process_config_postinit (BusContext      *context,
 
   _dbus_hash_table_unref (service_context_table);
 
-  /* Watch all conf directories */
-  bus_set_watched_dirs (context, bus_config_parser_get_conf_dirs (parser));
+  /* We need to monitor both the configuration directories and directories
+   * containing .service files.
+   */
+  if (!list_concat_new (bus_config_parser_get_conf_dirs (parser),
+                        bus_config_parser_get_service_dirs (parser),
+                        &watched_dirs))
+    {
+      BUS_SET_OOM (error);
+      return FALSE;
+    }
+
+  bus_set_watched_dirs (context, &watched_dirs);
+
+  _dbus_list_clear (&watched_dirs);
 
   return TRUE;
 }
index bb71394..c98e6fc 100644 (file)
@@ -156,8 +156,18 @@ _set_watched_dirs_internal (DBusList **directories)
           wd = inotify_add_watch (inotify_fd, new_dirs[i], IN_CLOSE_WRITE | IN_DELETE | IN_MOVED_TO | IN_MOVED_FROM);
           if (wd < 0)
             {
-              _dbus_warn ("Cannot setup inotify for '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno));
-              goto out;
+              /* Not all service directories need to exist. */
+              if (errno != ENOENT)
+                {
+                  _dbus_warn ("Cannot setup inotify for '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno));
+                  goto out;
+                }
+              else
+                {
+                  new_wds[i] = -1;
+                  new_dirs[i] = NULL;
+                  continue;
+                }
             }
           new_wds[i] = wd;
           new_dirs[i] = _dbus_strdup (new_dirs[i]);
index e7b0e2c..4a01b74 100644 (file)
@@ -204,11 +204,20 @@ bus_set_watched_dirs (BusContext *context, DBusList **directories)
           * we may need to sleep.
           */
           fd = open (new_dirs[i], O_RDONLY);
-         if (fd < 0)
+          if (fd < 0)
             {
-              _dbus_warn ("Cannot open directory '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno));
-             goto out;
-           }
+              if (errno != ENOENT)
+                {
+                  _dbus_warn ("Cannot open directory '%s'; error '%s'\n", new_dirs[i], _dbus_strerror (errno));
+                  goto out;
+                }
+              else
+                {
+                  new_fds[i] = -1;
+                  new_dirs[i] = NULL;
+                  continue;
+                }
+            }
 
           EV_SET (&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
                   NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_RENAME, 0, 0);