]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- auth-load-thread, print thread details in log at high verbosity, 8.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 11 Aug 2026 14:23:03 +0000 (16:23 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Tue, 11 Aug 2026 14:23:03 +0000 (16:23 +0200)
services/authload.c
services/authload.h
services/authzone.c
services/authzone.h
testdata/auth_load.tdir/auth_load.conf
testdata/auth_load.tdir/auth_load.test

index 16d36e4c7108a23d52189b8a3a8c9a35cd593f78..ae0066c72abb093b02e5be4a6984b17013d719c0 100644 (file)
 #include "util/timeval_func.h"
 #include "util/data/dname.h"
 
+/** Get memory use of buffer. */
+static size_t
+buffer_get_mem(struct sldns_buffer* buf)
+{
+       if(!buf) return 0;
+       return sizeof(*buf) + (buf->_data?buf->_capacity:0);
+}
+
 /** Auth load notification to string, for descriptive purposes. */
 static const char*
 auth_load_notification_to_string(enum auth_load_notification_type status)
@@ -311,6 +319,30 @@ auth_zone_delete_proxy(struct auth_zone* z)
        free(z);
 }
 
+/** Calculate memory use of the authload thread for this task.
+ * The size of the task struct, with the data chunks, and the proxy auth zone
+ * structure that is created while the other auth zone is used for queries,
+ * and other added memory.
+ */
+static void
+auth_load_calc_mem(struct auth_load_task* task, struct auth_zone* z,
+       size_t other)
+{
+       size_t m = 0;
+       if(verbosity < 8) {
+               task->mem_used = 0;
+               return;
+       }
+       m += other;
+       m += sizeof(*task);
+       m += task->namelen;
+       m += getmem_str(task->host);
+       m += getmem_str(task->file);
+       m += task->chunks_total;
+       m += auth_zone_get_mem(z);
+       task->mem_used = m;
+}
+
 /** Swap the final zone contents with the live zone */
 static void
 auth_load_swap_zone(struct auth_load_thread* thr, struct auth_zone* proxyz)
@@ -347,6 +379,7 @@ auth_load_process_http(struct auth_load_thread* thr)
        struct auth_load_task* task = thr->task;
        struct sldns_buffer* scratch_buffer;
        struct auth_zone* z;
+       size_t scratch_mem;
 
        scratch_buffer = sldns_buffer_new(sldns_buffer_capacity(
                thr->task->worker->env.scratch_buffer));
@@ -354,6 +387,7 @@ auth_load_process_http(struct auth_load_thread* thr)
                log_err("out of memory");
                return 0;
        }
+       scratch_mem = buffer_get_mem(scratch_buffer);
        z = auth_zone_create_proxy(task->name, task->namelen, task->dclass);
        if(!z) {
                log_err("out of memory");
@@ -393,6 +427,7 @@ auth_load_process_http(struct auth_load_thread* thr)
                return 0;
        }
 
+       auth_load_calc_mem(task, z, scratch_mem);
        auth_load_swap_zone(thr, z);
        auth_zone_delete_proxy(z);
        sldns_buffer_free(scratch_buffer);
@@ -482,6 +517,7 @@ auth_load_process_ixfr(struct auth_load_thread* thr)
        struct auth_load_task* task = thr->task;
        struct sldns_buffer* scratch_buffer;
        struct auth_zone* z;
+       size_t scratch_mem;
 
        scratch_buffer = sldns_buffer_new(sldns_buffer_capacity(
                thr->task->worker->env.scratch_buffer));
@@ -489,6 +525,7 @@ auth_load_process_ixfr(struct auth_load_thread* thr)
                log_err("out of memory");
                return 0;
        }
+       scratch_mem = buffer_get_mem(scratch_buffer);
        z = auth_zone_create_proxy(task->name, task->namelen, task->dclass);
        if(!z) {
                log_err("out of memory");
@@ -520,6 +557,7 @@ auth_load_process_ixfr(struct auth_load_thread* thr)
                return 0;
        }
 
+       auth_load_calc_mem(task, z, scratch_mem);
        auth_load_swap_zone(thr, z);
        auth_zone_delete_proxy(z);
        sldns_buffer_free(scratch_buffer);
@@ -533,6 +571,7 @@ auth_load_process_axfr(struct auth_load_thread* thr)
        struct auth_load_task* task = thr->task;
        struct sldns_buffer* scratch_buffer;
        struct auth_zone* z;
+       size_t scratch_mem;
 
        scratch_buffer = sldns_buffer_new(sldns_buffer_capacity(
                thr->task->worker->env.scratch_buffer));
@@ -540,6 +579,7 @@ auth_load_process_axfr(struct auth_load_thread* thr)
                log_err("out of memory");
                return 0;
        }
+       scratch_mem = buffer_get_mem(scratch_buffer);
        z = auth_zone_create_proxy(task->name, task->namelen, task->dclass);
        if(!z) {
                log_err("out of memory");
@@ -563,6 +603,7 @@ auth_load_process_axfr(struct auth_load_thread* thr)
                return 0;
        }
 
+       auth_load_calc_mem(task, z, scratch_mem);
        auth_load_swap_zone(thr, z);
        auth_zone_delete_proxy(z);
        sldns_buffer_free(scratch_buffer);
@@ -683,6 +724,7 @@ worker_auth_load_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits),
        struct module_env* env = &thr->task->worker->env;
        int ixfr_fail;
        struct timeval time_taken;
+       size_t mem_used, chunks_total;
 
        log_assert(thr->commpair[0] >= 0);
        ret = recv(thr->commpair[0], &recv_item, 1, 0);
@@ -735,6 +777,8 @@ worker_auth_load_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits),
        lock_rw_unlock(&thr->task->worker->env.auth_zones->lock);
        ixfr_fail = thr->task->ixfr_fail;
        time_taken = thr->task->time_taken;
+       mem_used = thr->task->mem_used;
+       chunks_total = thr->task->chunks_total;
        if(thr->task->on_http) {
                chunk_list = thr->task->chunks_first;
                thr->task->chunks_first = NULL;
@@ -746,7 +790,7 @@ worker_auth_load_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits),
        auth_load_thread_delete(thr);
        auth_load_info_release_thread(env);
        xfr_process_load_end_transfer(xfr, env, recv_item, ixfr_fail,
-               &time_taken, chunk_list);
+               &time_taken, mem_used, chunks_total, chunk_list);
 }
 
 /** Attach worker to the auth load thread. */
index c76c835699760382ea77820cecc82d4617e242e7..f501c3d517cbd7e6c1489ce1e6c738c4157a37d0 100644 (file)
@@ -158,6 +158,8 @@ struct auth_load_task {
 
        /** time taken for the task */
        struct timeval time_taken;
+       /** memory used for the task */
+       size_t mem_used;
 };
 
 /**
index 0822f62a4fe2a05fd6dab9ae9aac40e82a853302..5ca4e4dbadc694a8d478d40b01090f1b3d58992b 100644 (file)
@@ -6434,7 +6434,8 @@ process_list_end_transfer(struct auth_xfer* xfr, struct module_env* env)
  * ends holding xfr lock. */
 static int
 xfr_process_loaded_transfer(struct auth_xfer* xfr, struct module_env* env,
-       int* gone, struct timeval* time_taken)
+       int* gone, struct timeval* time_taken, size_t mem_used,
+       size_t chunks_total)
 {
        struct auth_zone* z = NULL;
        verbose(VERB_ALGO, "xfr_process_loaded_transfer");
@@ -6517,9 +6518,39 @@ xfr_process_loaded_transfer(struct auth_xfer* xfr, struct module_env* env,
                dname_str(xfr->name, zname);
                verbose(VERB_QUERY, "auth zone %s updated to serial %u",
                        zname, (unsigned)xfr->serial);
-               verbose(VERB_ALGO, "auth zone %s processing time was %d.%6.6ds",
-                       zname, (int)time_taken->tv_sec,
-                       (int)time_taken->tv_usec);
+               if(verbosity >= 8) {
+                       char taskline[1024];
+                       if(xfr->task_transfer->master->http) {
+                               snprintf(taskline, sizeof(taskline),
+                                       "http transfer from %s/%s of %lu "
+                                       "bytes serial %u",
+                                       xfr->task_transfer->master->host,
+                                       xfr->task_transfer->master->file,
+                                       (unsigned long)chunks_total,
+                                       (unsigned)xfr->serial);
+                       } else if(xfr->task_transfer->on_ixfr &&
+                               !xfr->task_transfer->on_ixfr_is_axfr) {
+                               snprintf(taskline, sizeof(taskline),
+                                       "IXFR transfer from %s of %lu "
+                                       "bytes serial %u",
+                                       xfr->task_transfer->master->host,
+                                       (unsigned long)chunks_total,
+                                       (unsigned)xfr->serial);
+                       } else {
+                               snprintf(taskline, sizeof(taskline),
+                                       "AXFR transfer from %s of %lu "
+                                       "bytes serial %u",
+                                       xfr->task_transfer->master->host,
+                                       (unsigned long)chunks_total,
+                                       (unsigned)xfr->serial);
+                       }
+                       verbose(VERB_ALGO, "auth zone %s details %s thread "
+                               "time was %d.%6.6ds and used %lu bytes of "
+                               "memory", zname, taskline,
+                               (int)time_taken->tv_sec,
+                               (int)time_taken->tv_usec,
+                               (unsigned long)mem_used);
+               }
        }
        verbose(VERB_ALGO, "xfr_process_loaded_transfer: write after update");
        /* see if we need to write to a zonefile */
@@ -6530,14 +6561,16 @@ xfr_process_loaded_transfer(struct auth_xfer* xfr, struct module_env* env,
 
 void xfr_process_load_end_transfer(struct auth_xfer* xfr,
        struct module_env* env, uint8_t status, int ixfr_fail,
-       struct timeval* time_taken, struct auth_chunk* chunk_list)
+       struct timeval* time_taken, size_t mem_used, size_t chunks_total,
+       struct auth_chunk* chunk_list)
 {
        /* Chunks are put here for the auth zone write for the http case. */
        verbose(VERB_ALGO, "xfr_process_load_end_transfer");
        xfr->task_transfer->chunks_first = chunk_list;
        if(status) {
                int gone = 0;
-               if(!xfr_process_loaded_transfer(xfr, env, &gone, time_taken)) {
+               if(!xfr_process_loaded_transfer(xfr, env, &gone, time_taken,
+                       mem_used, chunks_total)) {
                        status = 0;
                        if(gone) {
                                /* the zone is gone from the authzones. */
@@ -9157,7 +9190,7 @@ auth_data_get_mem(struct auth_data* node)
 }
 
 /** Get memory usage of auth zone */
-static size_t
+size_t
 auth_zone_get_mem(struct auth_zone* z)
 {
        size_t m = sizeof(*z) + z->namelen;
index e653a8fc32bd27b6e49c51bd1e14e6b13f9d3a78..8a964db928debbbaf1f0fd25ada51723337ef670 100644 (file)
@@ -858,6 +858,9 @@ int chunkline_count_parens(struct sldns_buffer* buf, size_t start);
 /** Clear data in auth zone */
 void auth_zone_clear_data(struct auth_zone* z);
 
+/** Get memory usage of auth zone */
+size_t auth_zone_get_mem(struct auth_zone* z);
+
 /** create domain with the given name */
 struct auth_data* az_domain_create(struct auth_zone* z, uint8_t* nm,
        size_t nmlen);
@@ -868,7 +871,8 @@ void auth_data_del(rbnode_type* n, void* arg);
 /** Handle the end of an auth load task. */
 void xfr_process_load_end_transfer(struct auth_xfer* xfr,
        struct module_env* env, uint8_t status, int ixfr_fail,
-       struct timeval* time_taken, struct auth_chunk* chunk_list);
+       struct timeval* time_taken, size_t mem_used, size_t chunks_total,
+       struct auth_chunk* chunk_list);
 
 /** Log preview of http transfer */
 void xfr_http_preview(const char* file, struct auth_chunk* chunk_list);
index 3a93cddf10719ef2ad5ae32b7379533b4825ada6..e62faad1015c1e351c967d47334cfbbd5f444d0f 100644 (file)
@@ -1,5 +1,5 @@
 server:
-       verbosity: 7
+       verbosity: 8
        # num-threads: 1
        interface: 127.0.0.1
        port: @PORT@
index c14b463c38d243652a820672a985d7f4e0248476..e30285c6c8c6b0e6fc7b2040850af1819555f3cd 100644 (file)
@@ -45,4 +45,6 @@ else
        exit 1
 fi
 
+grep "auth zone example.com. details" unbound.log
+
 exit 0