alloc id overflow handling.

git-svn-id: file:///svn/unbound/trunk@729 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-11-01 14:39:50 +00:00
parent 27c8952a2c
commit d2892aa5ab
8 changed files with 64 additions and 2 deletions

View file

@ -101,3 +101,9 @@ struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname),
log_assert(0); log_assert(0);
return 0; return 0;
} }
void
worker_alloc_cleanup(void* ATTR_UNUSED(arg))
{
log_assert(0);
}

View file

@ -938,6 +938,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
server_stats_init(&worker->stats); server_stats_init(&worker->stats);
alloc_init(&worker->alloc, &worker->daemon->superalloc, alloc_init(&worker->alloc, &worker->daemon->superalloc,
worker->thread_num); worker->thread_num);
alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
worker->env = *worker->daemon->env; worker->env = *worker->daemon->env;
worker->env.worker = worker; worker->env.worker = worker;
worker->env.send_packet = &worker_send_packet; worker->env.send_packet = &worker_send_packet;
@ -1044,3 +1045,11 @@ worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
} }
return e; return e;
} }
void
worker_alloc_cleanup(void* arg)
{
struct worker* worker = (struct worker*)arg;
slabhash_clear(&worker->env.rrset_cache->table);
slabhash_clear(worker->env.msg_cache);
}

View file

@ -214,4 +214,7 @@ int worker_handle_reply(struct comm_point* c, void* arg, int error,
int worker_handle_service_reply(struct comm_point* c, void* arg, int error, int worker_handle_service_reply(struct comm_point* c, void* arg, int error,
struct comm_reply* reply_info); struct comm_reply* reply_info);
/** cleanup the cache to remove all rrset IDs from it, arg is worker */
void worker_alloc_cleanup(void* arg);
#endif /* DAEMON_WORKER_H */ #endif /* DAEMON_WORKER_H */

View file

@ -5,6 +5,8 @@
that checking the passwd entry still works. that checking the passwd entry still works.
- minor touch up of clear() hashtable function. - minor touch up of clear() hashtable function.
- VERB_DETAIL prints out what chdir, username, chroot is being done. - VERB_DETAIL prints out what chdir, username, chroot is being done.
- when id numbers run out, caches are cleared, as in design notes.
Tested with a mock setup with very few bits in id, it worked.
31 October 2007: Wouter 31 October 2007: Wouter
- cache-max-ttl config option. - cache-max-ttl config option.

View file

@ -43,6 +43,7 @@
#include "util/alloc.h" #include "util/alloc.h"
#include "util/regional.h" #include "util/regional.h"
#include "util/data/packed_rrset.h" #include "util/data/packed_rrset.h"
#include "util/fptr_wlist.h"
/** custom size of cached regional blocks */ /** custom size of cached regional blocks */
#define ALLOC_REG_SIZE 16384 #define ALLOC_REG_SIZE 16384
@ -109,6 +110,8 @@ alloc_init(struct alloc_cache* alloc, struct alloc_cache* super,
alloc->max_reg_blocks = 100; alloc->max_reg_blocks = 100;
alloc->num_reg_blocks = 0; alloc->num_reg_blocks = 0;
alloc->reg_list = NULL; alloc->reg_list = NULL;
alloc->cleanup = NULL;
alloc->cleanup_arg = NULL;
if(alloc->super) if(alloc->super)
prealloc_blocks(alloc, alloc->max_reg_blocks); prealloc_blocks(alloc, alloc->max_reg_blocks);
if(!alloc->super) { if(!alloc->super) {
@ -165,8 +168,10 @@ alloc_get_id(struct alloc_cache* alloc)
{ {
uint64_t id = alloc->next_id++; uint64_t id = alloc->next_id++;
if(id == alloc->last_id) { if(id == alloc->last_id) {
/* TODO: clear the rrset cache */ log_warn("rrset alloc: out of 64bit ids. Clearing cache.");
log_warn("Out of ids. Clearing cache."); fptr_whitelist_alloc_cleanup(alloc->cleanup);
(*alloc->cleanup)(alloc->cleanup_arg);
/* start back at first number */ /* like in alloc_init*/ /* start back at first number */ /* like in alloc_init*/
alloc->next_id = (uint64_t)alloc->thread_num; alloc->next_id = (uint64_t)alloc->thread_num;
alloc->next_id <<= THRNUM_SHIFT; /* in steps for comp. */ alloc->next_id <<= THRNUM_SHIFT; /* in steps for comp. */
@ -317,6 +322,14 @@ alloc_reg_release(struct alloc_cache* alloc, struct regional* r)
alloc->num_reg_blocks++; alloc->num_reg_blocks++;
} }
void
alloc_set_id_cleanup(struct alloc_cache* alloc, void (*cleanup)(void*),
void* arg)
{
alloc->cleanup = cleanup;
alloc->cleanup_arg = arg;
}
/** global debug value to keep track of total memory mallocs */ /** global debug value to keep track of total memory mallocs */
size_t unbound_mem_alloc = 0; size_t unbound_mem_alloc = 0;
/** global debug value to keep track of total memory frees */ /** global debug value to keep track of total memory frees */

View file

@ -84,6 +84,10 @@ struct alloc_cache {
uint64_t next_id; uint64_t next_id;
/** last id number possible */ /** last id number possible */
uint64_t last_id; uint64_t last_id;
/** what function to call to cleanup when last id is reached */
void (*cleanup)(void*);
/** user arg for cleanup */
void* cleanup_arg;
/** how many regional blocks to keep back max */ /** how many regional blocks to keep back max */
size_t max_reg_blocks; size_t max_reg_blocks;
@ -162,4 +166,14 @@ struct regional* alloc_reg_obtain(struct alloc_cache* alloc);
*/ */
void alloc_reg_release(struct alloc_cache* alloc, struct regional* r); void alloc_reg_release(struct alloc_cache* alloc, struct regional* r);
/**
* Set cleanup on ID overflow callback function. This should remove all
* RRset ID references from the program. Clear the caches.
* @param alloc: the alloc
* @param cleanup: the callback function, called as cleanup(arg).
* @param arg: user argument to callback function.
*/
void alloc_set_id_cleanup(struct alloc_cache* alloc, void (*cleanup)(void*),
void* arg);
#endif /* UTIL_ALLOC_H */ #endif /* UTIL_ALLOC_H */

View file

@ -294,3 +294,10 @@ fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id))
else if(fptr == &val_get_mem) return 1; else if(fptr == &val_get_mem) return 1;
return 0; return 0;
} }
int
fptr_whitelist_alloc_cleanup(void (*fptr)(void*))
{
if(fptr == &worker_alloc_cleanup) return 1;
return 0;
}

View file

@ -264,4 +264,12 @@ int fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate,
*/ */
int fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id)); int fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id));
/**
* Check function pointer whitelist for alloc clear on id overflow call values.
*
* @param fptr: function pointer to check.
* @return false if not in whitelist.
*/
int fptr_whitelist_alloc_cleanup(void (*fptr)(void*));
#endif /* UTIL_FPTR_WLIST_H */ #endif /* UTIL_FPTR_WLIST_H */