resolved: dump cache and zone contents to syslog on SIGUSR1
authorLennart Poettering <lennart@poettering.net>
Wed, 26 Aug 2015 07:41:45 +0000 (09:41 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 26 Aug 2015 07:41:45 +0000 (09:41 +0200)
src/resolve/resolved-dns-cache.c
src/resolve/resolved-dns-cache.h
src/resolve/resolved-dns-scope.c
src/resolve/resolved-dns-scope.h
src/resolve/resolved-dns-zone.c
src/resolve/resolved-dns-zone.h
src/resolve/resolved-manager.c
src/resolve/resolved-manager.h
src/resolve/resolved.c

index 7ee0983..ef6b69c 100644 (file)
@@ -620,3 +620,54 @@ int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_
         /* There's a conflict */
         return 1;
 }
+
+void dns_cache_dump(DnsCache *cache, FILE *f) {
+        Iterator iterator;
+        DnsCacheItem *i;
+        int r;
+
+        if (!cache)
+                return;
+
+        if (!f)
+                f = stdout;
+
+        HASHMAP_FOREACH(i, cache->by_key, iterator) {
+                DnsCacheItem *j;
+
+                LIST_FOREACH(by_key, j, i) {
+                        _cleanup_free_ char *t = NULL;
+
+                        fputc('\t', f);
+
+                        if (j->rr) {
+                                r = dns_resource_record_to_string(j->rr, &t);
+                                if (r < 0) {
+                                        log_oom();
+                                        continue;
+                                }
+
+                                fputs(t, f);
+                                fputc('\n', f);
+                        } else {
+                                r = dns_resource_key_to_string(j->key, &t);
+                                if (r < 0) {
+                                        log_oom();
+                                        continue;
+                                }
+
+                                fputs(t, f);
+                                fputs(" -- ", f);
+                                fputs(j->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN", f);
+                                fputc('\n', f);
+                        }
+                }
+        }
+}
+
+bool dns_cache_is_empty(DnsCache *cache) {
+        if (!cache)
+                return true;
+
+        return hashmap_isempty(cache->by_key);
+}
index fd583a7..1225e58 100644 (file)
@@ -43,3 +43,6 @@ int dns_cache_put(DnsCache *c, DnsQuestion *q, int rcode, DnsAnswer *answer, uns
 int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **answer);
 
 int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address);
+
+void dns_cache_dump(DnsCache *cache, FILE *f);
+bool dns_cache_is_empty(DnsCache *cache);
index eaa0993..9e6f595 100644 (file)
@@ -812,3 +812,35 @@ void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p) {
                 dns_scope_notify_conflict(scope, p->answer->items[i].rr);
         }
 }
+
+void dns_scope_dump(DnsScope *s, FILE *f) {
+        assert(s);
+
+        if (!f)
+                f = stdout;
+
+        fputs("[Scope protocol=", f);
+        fputs(dns_protocol_to_string(s->protocol), f);
+
+        if (s->link) {
+                fputs(" interface=", f);
+                fputs(s->link->name, f);
+        }
+
+        if (s->family != AF_UNSPEC) {
+                fputs(" family=", f);
+                fputs(af_to_name(s->family), f);
+        }
+
+        fputs("]\n", f);
+
+        if (!dns_zone_is_empty(&s->zone)) {
+                fputs("ZONE:\n", f);
+                dns_zone_dump(&s->zone, f);
+        }
+
+        if (!dns_cache_is_empty(&s->cache)) {
+                fputs("CACHE:\n", f);
+                dns_cache_dump(&s->cache, f);
+        }
+}
index 88fb822..b75f212 100644 (file)
@@ -89,3 +89,5 @@ DnsTransaction *dns_scope_find_transaction(DnsScope *scope, DnsResourceKey *key,
 
 int dns_scope_notify_conflict(DnsScope *scope, DnsResourceRecord *rr);
 void dns_scope_check_conflicts(DnsScope *scope, DnsPacket *p);
+
+void dns_scope_dump(DnsScope *s, FILE *f);
index fc212f4..674bb6a 100644 (file)
@@ -636,3 +636,40 @@ void dns_zone_verify_all(DnsZone *zone) {
                         dns_zone_item_verify(j);
         }
 }
+
+void dns_zone_dump(DnsZone *zone, FILE *f) {
+        Iterator iterator;
+        DnsZoneItem *i;
+        int r;
+
+        if (!zone)
+                return;
+
+        if (!f)
+                f = stdout;
+
+        HASHMAP_FOREACH(i, zone->by_key, iterator) {
+                DnsZoneItem *j;
+
+                LIST_FOREACH(by_key, j, i) {
+                        _cleanup_free_ char *t = NULL;
+
+                        r = dns_resource_record_to_string(j->rr, &t);
+                        if (r < 0) {
+                                log_oom();
+                                continue;
+                        }
+
+                        fputc('\t', f);
+                        fputs(t, f);
+                        fputc('\n', f);
+                }
+        }
+}
+
+bool dns_zone_is_empty(DnsZone *zone) {
+        if (!zone)
+                return true;
+
+        return hashmap_isempty(zone->by_key);
+}
index 7185126..495d17c 100644 (file)
@@ -78,3 +78,6 @@ int dns_zone_verify_conflicts(DnsZone *zone, DnsResourceKey *key);
 void dns_zone_verify_all(DnsZone *zone);
 
 void dns_zone_item_probe_stop(DnsZoneItem *i);
+
+void dns_zone_dump(DnsZone *zone, FILE *f);
+bool dns_zone_is_empty(DnsZone *zone);
index fb2a06b..1407c63 100644 (file)
@@ -430,6 +430,31 @@ static int manager_watch_hostname(Manager *m) {
         return 0;
 }
 
+static int manager_sigusr1(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
+        _cleanup_free_ char *buffer = NULL;
+        _cleanup_fclose_ FILE *f = NULL;
+        Manager *m = userdata;
+        size_t size = 0;
+        DnsScope *scope;
+
+        assert(s);
+        assert(si);
+        assert(m);
+
+        f = open_memstream(&buffer, &size);
+        if (!f)
+                return log_oom();
+
+        LIST_FOREACH(scopes, scope, m->dns_scopes)
+                dns_scope_dump(scope, f);
+
+        if (fflush_and_check(f) < 0)
+                return log_oom();
+
+        log_dump(LOG_INFO, buffer);
+        return 0;
+}
+
 int manager_new(Manager **ret) {
         _cleanup_(manager_freep) Manager *m = NULL;
         int r;
@@ -480,6 +505,8 @@ int manager_new(Manager **ret) {
         if (r < 0)
                 return r;
 
+        (void) sd_event_add_signal(m->event, &m->sigusr1_event_source, SIGUSR1, manager_sigusr1, m);
+
         *ret = m;
         m = NULL;
 
@@ -527,6 +554,8 @@ Manager *manager_free(Manager *m) {
         sd_event_source_unref(m->bus_retry_event_source);
         sd_bus_unref(m->bus);
 
+        sd_event_source_unref(m->sigusr1_event_source);
+
         sd_event_unref(m->event);
 
         dns_resource_key_unref(m->llmnr_host_ipv4_key);
index 6f7972b..fe7fe99 100644 (file)
@@ -102,6 +102,8 @@ struct Manager {
 
         /* Watch for system suspends */
         sd_bus_slot *prepare_for_sleep_slot;
+
+        sd_event_source *sigusr1_event_source;
 };
 
 /* Manager */
index 0af5545..32e61af 100644 (file)
@@ -71,7 +71,7 @@ int main(int argc, char *argv[]) {
         if (r < 0)
                 goto finish;
 
-        assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
+        assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGUSR1, -1) >= 0);
 
         r = manager_new(&m);
         if (r < 0) {