OK, two problems. Problem number one seems to have been introduced with the LocalSocket option. In fact, that config value is ignored in favor of its key, the literal "LocalSocket". So the plugin creates the socket as "LocalSocket", connects to the pdns control socket and sends the data. When the pdns control socket attempts to send data back, it finds no socket called "LocalSocket" as it's in a different working directory. Of course, this shouldn't cause collectd to hang. That's the second problem. The plugin's socket has no recv timeout. Since it was able to connect and send data successfully, it waits indefinitely for a response that's not coming.
Both problems are fixed in the attached patch, which I made against the squeeze debian source. I've tested the resulting package successfully in a lenny environment, both with and without a chrooted pdns_recursor. Luke Heberling
--- collectd-4.6.3.broken/src/powerdns.c 2009-06-02 02:17:47.000000000 -0700 +++ collectd-4.6.3/src/powerdns.c 2009-07-27 16:44:32.000000000 -0700 @@ -380,6 +380,16 @@ static int powerdns_get_data_dgram (list break; } + struct timeval timeout; + timeout.tv_sec=5; + timeout.tv_usec=0; + status = setsockopt (sd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof (timeout)); + if (status != 0) + { + FUNC_ERROR ("setsockopt"); + break; + } + status = connect (sd, (struct sockaddr *) &item->sockaddr, sizeof (item->sockaddr)); if (status != 0) @@ -911,11 +921,18 @@ static int powerdns_config (oconfig_item powerdns_config_add_server (option); else if (strcasecmp ("LocalSocket", option->key) == 0) { - char *temp = strdup (option->key); - if (temp == NULL) - return (1); - sfree (local_sockpath); - local_sockpath = temp; + if ((option->values_num != 1) || (option->values[0].type != OCONFIG_TYPE_STRING)) + { + WARNING ("powerdns plugin: `%s' needs exactly one string argument.", ci->key); + } + else + { + char *temp = strdup (option->values[0].value.string); + if (temp == NULL) + return (1); + sfree (local_sockpath); + local_sockpath = temp; + } } else {