#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)
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)
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));
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");
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);
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));
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");
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);
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));
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");
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);
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);
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;
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. */
/** time taken for the task */
struct timeval time_taken;
+ /** memory used for the task */
+ size_t mem_used;
};
/**
* 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");
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 */
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. */
}
/** 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;
/** 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);
/** 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);
server:
- verbosity: 7
+ verbosity: 8
# num-threads: 1
interface: 127.0.0.1
port: @PORT@
exit 1
fi
+grep "auth zone example.com. details" unbound.log
+
exit 0