problems with distcc + zeroconf

shawn <[email protected]> Wed, 16 May 2012 21:51:03 -0700
Newsgroups gmane.comp.compilers.distcc
Message-ID <1337230263.2396.28.camel@shawn-ssd>
Distcc + avahi developers,

After upgrading to svn distcc, zeroconf does now work, however it has
some issues, which seem to be woorse when using more threads (-j13 etc)

while it does distribute, occasionally the hosts file is empty, and then
it slowly compiles locally:


distcc[12745] (dcc_parse_hosts)
Warning: /home/shawn/.distcc/zeroconf/hosts contained no hosts; can't
distribute work
distcc[12745] (dcc_zeroconf_add_hosts) CRITICAL! failed to parse host
file.

distcc[12745] (dcc_build_somewhere) Warning: failed to distribute,
running locally instead


I tried to fix this problem, but I need some more input, as I am not
positive what the problem is, nor if my approach is appropriate. (or
even how to debug effectively might be nice---some-but not all-tests i
did with distcc seemed to not even trigger these functions in gdb)

also: attacked typo patch that got bounced the first time
-- 
-Shawn Landden

__
distcc mailing list            http://distcc.samba.org/
To unsubscribe or change options:
https://lists.samba.org/mailman/listinfo/distcc
0001-attempt-to-address-race-condition-issues-by-using-in.patch (text/x-patch, 4.1 KB)
From 94e9f67875c7ef33c04b83b7255cd45060ce34fd Mon Sep 17 00:00:00 2001
From: Shawn Landden <[email protected]>
Date: Wed, 16 May 2012 21:43:43 -0700
Subject: [PATCH] attempt to address race condition issues by using inotify

---
 src/zeroconf.c |   59 ++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/src/zeroconf.c b/src/zeroconf.c
index f802d68..bd15460 100644
--- a/src/zeroconf.c
+++ b/src/zeroconf.c
@@ -33,6 +33,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <limits.h>
+#include <sys/inotify.h>
 
 #include <avahi-common/domain.h>
 #include <avahi-common/error.h>
@@ -49,7 +50,7 @@
 
 /* How long shall the background daemon be idle before it terminates itself?
  * (in seconds) */
-#define MAX_IDLE_TIME 20
+#define MAX_IDLE_TIME 40
 
 /* Maxium size of host file to load */
 #define MAX_FILE_SIZE (1024*100)
@@ -138,6 +139,8 @@ static int write_hosts(struct daemon_data *d) {
     int r = 0;
     assert(d);
 
+    remove_duplicate_services(d);
+
     rs_log_info("writing zeroconf data.\n");
 
     if (generic_lock(d->fd, 1, 1, 1) < 0) {
@@ -150,13 +153,6 @@ static int write_hosts(struct daemon_data *d) {
         return -1;
     }
 
-    if (ftruncate(d->fd, 0) < 0) {
-        rs_log_crit("ftruncate() failed: %s\n", strerror(errno));
-        return -1;
-    }
-
-    remove_duplicate_services(d);
-
     for (h = d->hosts; h; h = h->next) {
         char t[256], a[AVAHI_ADDRESS_STR_MAX];
 
@@ -168,6 +164,11 @@ static int write_hosts(struct daemon_data *d) {
 	else
 	    snprintf(t, sizeof(t), "%s:%u/%i\n", avahi_address_snprint(a, sizeof(a), &h->address), h->port, d->n_slots * h->n_cpus);
 
+        if (ftruncate(d->fd, 0) < 0) {
+                rs_log_crit("ftruncate() failed: %s\n", strerror(errno));
+                return -1;
+        }
+
         if (dcc_writex(d->fd, t, strlen(t)) != 0) {
             rs_log_crit("write() failed: %s\n", strerror(errno));
             goto finish;
@@ -539,6 +540,36 @@ static int get_zeroconf_dir(char **dir_ret) {
     }
 }
 
+static int wait_for_hosts(char *host_file, int host_fd);
+
+/* Use inotify to wait for daemon to populate hosts file */
+int wait_for_hosts(char *host_file, int host_fd) {
+    int inotify_fd = -1, wd = -1;
+    struct stat st;
+    char inotify_buf[16 * sizeof(struct inotify_event)];
+
+    if ((inotify_fd = inotify_init()) < 0) {
+        rs_log_crit("inotify_init() failed: %s\n", strerror(errno));
+        return -1;
+    }
+    if ((wd = (inotify_add_watch (inotify_fd, host_file, IN_MODIFY))) < 0) {
+        rs_log_crit("inotify_add_watch() failed: %s\n", strerror(errno));
+        return -1;
+    }
+    do {if (read(inotify_fd, &inotify_buf, sizeof(inotify_buf)) < 0) {
+            rs_log_crit("read() failed: %s\n", strerror(errno));
+            return -1;
+        }
+
+        if (fstat(host_fd, &st) < 0) {
+            rs_log_crit("stat() failed: %s\n", strerror(errno));
+            return -1;
+        }
+    } while (st.st_size == 0);
+
+    return 0;
+}
+
 /* Get the host list from zeroconf */
 int dcc_zeroconf_add_hosts(struct dcc_hostdef **ret_list, int *ret_nhosts, int n_slots, struct dcc_hostdef **ret_prev) {
     char *host_file = NULL, *lock_file = NULL, *s = NULL;
@@ -611,11 +642,6 @@ int dcc_zeroconf_add_hosts(struct dcc_hostdef **ret_list, int *ret_nhosts, int n
             }
             _exit(daemon_proc(host_file, lock_file, n_slots));
         }
-
-        /* Parent */
-
-        /* Wait some time for initial host gathering */
-        usleep(1000000);         /* 1000 ms */
     }
 
     /* Open host list read-only */
@@ -636,7 +662,10 @@ int dcc_zeroconf_add_hosts(struct dcc_hostdef **ret_list, int *ret_nhosts, int n
         goto finish;
     }
 
-    if (st.st_size >= MAX_FILE_SIZE) {
+    if (st.st_size == 0) {
+        if (wait_for_hosts(host_file, host_fd) < 0)
+            goto finish;
+    } else if (st.st_size >= MAX_FILE_SIZE) {
         rs_log_crit("file too large.\n");
         goto finish;
     }
@@ -670,4 +699,4 @@ finish:
     free(s);
 
     return r;
-}
+}
\ No newline at end of file
-- 
1.7.9.5
0001-zeroconf-fix-typo.patch (text/x-patch, 710 B)
From f818dce5f21d0fb3bab02c53745d806a976ef2ad Mon Sep 17 00:00:00 2001
From: Shawn Landden <[email protected]>
Date: Wed, 16 May 2012 21:40:58 -0700
Subject: [PATCH] zeroconf: fix typo

---
 src/zeroconf.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/zeroconf.c b/src/zeroconf.c
index 652cc1d..f802d68 100644
--- a/src/zeroconf.c
+++ b/src/zeroconf.c
@@ -47,7 +47,8 @@
 #include "trace.h"
 #include "exitcode.h"
 
-/* How long shall the background daemon be idle before i terminates itself? */
+/* How long shall the background daemon be idle before it terminates itself?
+ * (in seconds) */
 #define MAX_IDLE_TIME 20
 
 /* Maxium size of host file to load */
-- 
1.7.9.5