]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- fast-reload, reload views.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 5 Apr 2024 12:28:40 +0000 (14:28 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 5 Apr 2024 12:28:40 +0000 (14:28 +0200)
Makefile.in
daemon/remote.c
respip/respip.c
respip/respip.h
services/localzone.c
services/localzone.h
services/view.c
services/view.h
util/config_file.c
util/config_file.h

index 79379d8d131586cc128f42baf0fb567c6a5de8a6..eb9fce66a4cdcbcfb4bf9e04fe63f7d80f2680ee 100644 (file)
@@ -866,7 +866,7 @@ view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(s
  $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
  $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/respip/respip.h
 rpz.lo rpz.o: $(srcdir)/services/rpz.c config.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
  $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
  $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
index 12214a005c288d37192788409d02a7d831c578a9..95b1bb229362f58c2bed694641e94e9309567256 100644 (file)
@@ -3767,6 +3767,8 @@ fr_init_time(struct timeval* time_start, struct timeval* time_read,
  * are kept in here. They can then be deleted.
  */
 struct fast_reload_construct {
+       /** construct for views */
+       struct views* views;
        /** construct for forwards */
        struct iter_forwards* fwds;
        /** construct for stubs */
@@ -3821,6 +3823,7 @@ fr_construct_clear(struct fast_reload_construct* ct)
                return;
        forwards_delete(ct->fwds);
        hints_delete(ct->hints);
+       views_delete(ct->views);
        /* Delete the log identity here so that the global value is not
         * reset by config_delete. */
        if(ct->oldcfg && ct->oldcfg->log_identity) {
@@ -3830,14 +3833,6 @@ fr_construct_clear(struct fast_reload_construct* ct)
        config_delete(ct->oldcfg);
 }
 
-/** get memory for string */
-static size_t
-getmem_str(char* str)
-{
-       if(!str) return 0;
-       return strlen(str)+1;
-}
-
 /** get memory for strlist */
 static size_t
 getmem_config_strlist(struct config_strlist* p)
@@ -4074,6 +4069,7 @@ fr_printmem(struct fast_reload_thread* fr,
        size_t mem = 0;
        if(fr_poll_for_quit(fr))
                return 1;
+       mem += views_get_mem(ct->views);
        mem += forwards_get_mem(ct->fwds);
        mem += hints_get_mem(ct->hints);
        mem += sizeof(*ct->oldcfg);
@@ -4091,8 +4087,21 @@ static int
 fr_construct_from_config(struct fast_reload_thread* fr,
        struct config_file* newcfg, struct fast_reload_construct* ct)
 {
-       if(!(ct->fwds = forwards_create()))
+       if(!(ct->views = views_create())) {
+               fr_construct_clear(ct);
+               return 0;
+       }
+       if(!views_apply_cfg(ct->views, newcfg)) {
+               fr_construct_clear(ct);
                return 0;
+       }
+       if(fr_poll_for_quit(fr))
+               return 1;
+
+       if(!(ct->fwds = forwards_create())) {
+               fr_construct_clear(ct);
+               return 0;
+       }
        if(!forwards_apply_cfg(ct->fwds, newcfg)) {
                fr_construct_clear(ct);
                return 0;
@@ -4516,6 +4525,8 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
        log_assert(ct->hints);
 
        /* Grab big locks to satisfy lock conditions. */
+       lock_rw_wrlock(&ct->views->lock);
+       lock_rw_wrlock(&daemon->views->lock);
        lock_rw_wrlock(&ct->fwds->lock);
        lock_rw_wrlock(&ct->hints->lock);
        lock_rw_wrlock(&env->fwds->lock);
@@ -4552,10 +4563,13 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
         * towards the state machine for query resolution. */
        forwards_swap_tree(env->fwds, ct->fwds);
        hints_swap_tree(env->hints, ct->hints);
+       views_swap_tree(daemon->views, ct->views);
 
        /* Set globals with new config. */
        config_apply(env->cfg);
 
+       lock_rw_unlock(&ct->views->lock);
+       lock_rw_unlock(&daemon->views->lock);
        lock_rw_unlock(&env->fwds->lock);
        lock_rw_unlock(&env->hints->lock);
        lock_rw_unlock(&ct->fwds->lock);
index 942e082b957729cef95083d62d9dc01f8b14f8f3..d698954b6c9db5f23068d302bec82f8056713862 100644 (file)
@@ -1326,3 +1326,12 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
                (actionstr) ? actionstr : "inform", srcip, port);
        log_nametypeclass(NO_VERBOSE, txt, qname, qtype, qclass);
 }
+
+size_t respip_set_get_mem(struct respip_set* set)
+{
+       size_t m = sizeof(*set);
+       lock_rw_rdlock(&set->lock);
+       m += regional_get_mem(set->region);
+       lock_rw_unlock(&set->lock);
+       return m;
+}
index e4ab5cc9cce376dd84ef95062cdff5a0e540ffa5..f43052e22fd5e19d3b9339deae2f7c1a546fe381 100644 (file)
@@ -302,4 +302,9 @@ respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node);
 
 struct ub_packed_rrset_key*
 respip_copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region);
+
+/** Get memory usage of respip set tree. The routine locks and unlocks the
+ * set for reading. */
+size_t respip_set_get_mem(struct respip_set* set);
+
 #endif /* RESPIP_RESPIP_H */
index 51056c8ffef4a7388e45a83913fb0bbc275ac462..ec11230541899faf2b62120f70e3108dc92e8191 100644 (file)
@@ -2203,3 +2203,26 @@ void local_zones_del_data(struct local_zones* zones,
 
        lock_rw_unlock(&z->lock);
 }
+
+/** Get memory usage for local_zone */
+static size_t
+local_zone_get_mem(struct local_zone* z)
+{
+       size_t m = sizeof(*z);
+       lock_rw_rdlock(&z->lock);
+       m += z->namelen + z->taglen + regional_get_mem(z->region);
+       lock_rw_unlock(&z->lock);
+       return m;
+}
+
+size_t local_zones_get_mem(struct local_zones* zones)
+{
+       struct local_zone* z;
+       size_t m = sizeof(*zones);
+       lock_rw_rdlock(&zones->lock);
+       RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
+               m += local_zone_get_mem(z);
+       }
+       lock_rw_unlock(&zones->lock);
+       return m;
+}
index 4456893ee1124b1a329726459c7de7e50607c5f4..7a51ec59d74186c5b40455997ef0b6562bb1f4e0 100644 (file)
@@ -641,4 +641,9 @@ local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
  */
 struct local_data* 
 local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs);
+
+/** Get memory usage for local_zones tree. The routine locks and unlocks
+ * the tree for reading. */
+size_t local_zones_get_mem(struct local_zones* zones);
+
 #endif /* SERVICES_LOCALZONE_H */
index 72f3643184ee4275375e7a28b19160dfa37a671c..4ecd52d494b3a7f7af2dcc0ab5ebe7832fcfc2d7 100644 (file)
@@ -43,6 +43,7 @@
 #include "services/view.h"
 #include "services/localzone.h"
 #include "util/config_file.h"
+#include "respip/respip.h"
 
 int 
 view_cmp(const void* v1, const void* v2)
@@ -66,11 +67,6 @@ views_create(void)
        return v;
 }
 
-/* \noop (ignore this comment for doxygen)
- * This prototype is defined in in respip.h, but we want to avoid
- * unnecessary dependencies */
-void respip_set_delete(struct respip_set *set);
-
 void 
 view_delete(struct view* v)
 {
@@ -247,3 +243,36 @@ void views_print(struct views* v)
        /* TODO implement print */
        (void)v;
 }
+
+size_t views_get_mem(struct views* vs)
+{
+       struct view* v;
+       size_t m = sizeof(struct views);
+       lock_rw_rdlock(&vs->lock);
+       RBTREE_FOR(v, struct view*, &vs->vtree) {
+               m += view_get_mem(v);
+       }
+       lock_rw_unlock(&vs->lock);
+       return m;
+}
+
+size_t view_get_mem(struct view* v)
+{
+       size_t m = sizeof(*v);
+       lock_rw_rdlock(&v->lock);
+       m += getmem_str(v->name);
+       m += local_zones_get_mem(v->local_zones);
+       m += respip_set_get_mem(v->respip_set);
+       lock_rw_unlock(&v->lock);
+       return m;
+}
+
+void views_swap_tree(struct views* vs, struct views* data)
+{
+       rbnode_type* oldroot = vs->vtree.root;
+       size_t oldcount = vs->vtree.count;
+       vs->vtree.root = data->vtree.root;
+       vs->vtree.count = data->vtree.count;
+       data->vtree.root = oldroot;
+       data->vtree.count = oldcount;
+}
index 17778100474bbbbbc865a821439ac88a3a787204..b0eebf0029ef492e87397aee696cd2f08a26732e 100644 (file)
@@ -54,7 +54,8 @@ struct respip_set;
  * Views storage, shared.
  */
 struct views {
-       /** lock on the view tree */
+       /** lock on the view tree. When locking order, the views lock
+        * is before the forwards,hints,anchors lock. */
        lock_rw_type lock;
        /** rbtree of struct view */
        rbtree_type vtree;
@@ -134,4 +135,27 @@ void views_print(struct views* v);
  */
 struct view* views_find_view(struct views* vs, const char* name, int write);
 
+/**
+ * Calculate memory usage of views.
+ * @param vs: the views tree. The routine locks and unlocks the structure
+ *     for reading.
+ * @return memory in bytes.
+ */
+size_t views_get_mem(struct views* vs);
+
+/**
+ * Calculate memory usage of view.
+ * @param v: the view. The routine locks and unlocks the structure for reading.
+ * @return memory in bytes.
+ */
+size_t view_get_mem(struct view* v);
+
+/**
+ * Swap internal tree with preallocated entries. Caller should manage
+ * the locks.
+ * @param vs: views tree
+ * @param data: preallocated information.
+ */
+void views_swap_tree(struct views* vs, struct views* data);
+
 #endif /* SERVICES_VIEW_H */
index 26185da0203cef408a9908ac6adf12de57ef6c12..90a4b6e4b5bd02640c9111fb34318ebb04a41f1c 100644 (file)
@@ -2722,3 +2722,10 @@ if_is_dnscrypt(const char* ifname, const char* port, int dnscrypt_port)
        return 0;
 #endif
 }
+
+size_t
+getmem_str(char* str)
+{
+       if(!str) return 0;
+       return strlen(str)+1;
+}
index 491109833e4b3a6e2761d9ca332e32d8184b6a7c..0739e0a52fd250b19870ada1ffbbadb82e53a772 100644 (file)
@@ -1373,4 +1373,7 @@ int if_is_dnscrypt(const char* ifname, const char* port, int dnscrypt_port);
 #define LINUX_IP_LOCAL_PORT_RANGE_PATH "/proc/sys/net/ipv4/ip_local_port_range"
 #endif
 
+/** get memory for string */
+size_t getmem_str(char* str);
+
 #endif /* UTIL_CONFIG_FILE_H */