]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
alloc id overflow handling.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 1 Nov 2007 14:39:50 +0000 (14:39 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 1 Nov 2007 14:39:50 +0000 (14:39 +0000)
git-svn-id: file:///svn/unbound/trunk@729 be551aaa-1e26-0410-a405-d3ace91eadb9

checkconf/worker_cb.c
daemon/worker.c
daemon/worker.h
doc/Changelog
util/alloc.c
util/alloc.h
util/fptr_wlist.c
util/fptr_wlist.h

index 29eaff96ce3492f996cdfd6253cebf913baf0564..7f14450172179a09fa41f3e38e8d6d06a1fa1e18 100644 (file)
@@ -101,3 +101,9 @@ struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname),
        log_assert(0);
        return 0;
 }
+
+void 
+worker_alloc_cleanup(void* ATTR_UNUSED(arg))
+{
+       log_assert(0);
+}
index 80a92f92778e703fd008d79301993abb0595dae5..64ee700a3cfa115909e8719265b7827c3347e35a 100644 (file)
@@ -938,6 +938,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
        server_stats_init(&worker->stats);
        alloc_init(&worker->alloc, &worker->daemon->superalloc, 
                worker->thread_num);
+       alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
        worker->env = *worker->daemon->env;
        worker->env.worker = worker;
        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;
 }
+
+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);
+}
index abf0b58fe7a4ca211060c1af349cabcf0fb7378f..94d1c65e6199d61c3da38c898f2ef908c5a7ff61 100644 (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, 
        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 */
index 8709e9410505ee3a5800400a45b6cac21c14bba5..e3afd7d9bcb22b1b518c7e12a0fec3197e322497 100644 (file)
@@ -5,6 +5,8 @@
          that checking the passwd entry still works.
        - minor touch up of clear() hashtable function.
        - 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
        - cache-max-ttl config option.
index 113f6a737c4f0ca20a9e2738a6030503e72944bf..19a51ba27251d17a53b59716f36b4a01f101a809 100644 (file)
@@ -43,6 +43,7 @@
 #include "util/alloc.h"
 #include "util/regional.h"
 #include "util/data/packed_rrset.h"
+#include "util/fptr_wlist.h"
 
 /** custom size of cached regional blocks */
 #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->num_reg_blocks = 0;
        alloc->reg_list = NULL;
+       alloc->cleanup = NULL;
+       alloc->cleanup_arg = NULL;
        if(alloc->super)
                prealloc_blocks(alloc, alloc->max_reg_blocks);
        if(!alloc->super) {
@@ -165,8 +168,10 @@ alloc_get_id(struct alloc_cache* alloc)
 {
        uint64_t id = alloc->next_id++;
        if(id == alloc->last_id) {
-               /* TODO: clear the rrset cache */
-               log_warn("Out of ids. Clearing cache.");
+               log_warn("rrset alloc: out of 64bit ids. Clearing cache.");
+               fptr_whitelist_alloc_cleanup(alloc->cleanup);
+               (*alloc->cleanup)(alloc->cleanup_arg);
+
                /* start back at first number */        /* like in alloc_init*/
                alloc->next_id = (uint64_t)alloc->thread_num;   
                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++;
 }
 
+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 */
 size_t unbound_mem_alloc = 0;
 /** global debug value to keep track of total memory frees */
index 8bba43e5de2035a778c038bbd0fa831b8d88ef2b..6b54a9dfc59eb6d8b13018bab9958cfac08de25c 100644 (file)
@@ -84,6 +84,10 @@ struct alloc_cache {
        uint64_t next_id;
        /** last id number possible */
        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 */
        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);
 
+/**
+ * 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 */
index d90be69dfd21e8df072ae99dd71fecec5d69db8b..ac67b6e532257d403eb64df0b45937290a3efc56 100644 (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;
        return 0;
 }
+
+int 
+fptr_whitelist_alloc_cleanup(void (*fptr)(void*))
+{
+       if(fptr == &worker_alloc_cleanup) return 1;
+       return 0;
+}
index 89e3672b0c9d1ea4758eeb7b54eeccaaab14ac69..b3cebef688eb4def3787f45af2abab64f85ba638 100644 (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));
 
+/**
+ * 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 */