From 556d5407e2fdb82d18aa6bf6758491474619f265 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Fri, 26 Sep 2008 13:02:34 +0000 Subject: [PATCH] remote control tests. git-svn-id: file:///svn/unbound/trunk@1270 be551aaa-1e26-0410-a405-d3ace91eadb9 --- daemon/remote.c | 2 +- doc/Changelog | 5 +++++ services/localzone.c | 17 +++++------------ smallapp/unbound-control.c | 13 +++++++++---- testdata/09-unbound-control.tpkg | Bin 4467 -> 7157 bytes 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index cc7082a20..74c5d4262 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -939,9 +939,9 @@ do_zone_remove(SSL* ssl, struct worker* worker, char* arg) nmlabs, LDNS_RR_CLASS_IN))) { /* present in tree */ local_zones_del_zone(worker->daemon->local_zones, z); - free(nm); } lock_quick_unlock(&worker->daemon->local_zones->lock); + free(nm); send_ok(ssl); } diff --git a/doc/Changelog b/doc/Changelog index bf2791dc4..099ee3e26 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,8 @@ +26 September 2008: Wouter + - tests for remote-control. + - small memory leak in exception during remote control fixed. + - fixup for lock checking but not unchecking in remote control. + 23 September 2008: Wouter - Msg cache is loaded. A cache load enables cache responses. - unbound-control flush [name], flush_type and flush_zone. diff --git a/services/localzone.c b/services/localzone.c index 289d3435e..a7452ea39 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -144,8 +144,8 @@ parse_dname(const char* str, uint8_t** res, size_t* len, int* labs) /** create a new localzone */ static struct local_zone* -local_zone_create(struct local_zones* zones, uint8_t* nm, size_t len, - int labs, enum localzone_type t, uint16_t dclass) +local_zone_create(uint8_t* nm, size_t len, int labs, + enum localzone_type t, uint16_t dclass) { struct local_zone* z = (struct local_zone*)calloc(1, sizeof(*z)); if(!z) { @@ -165,13 +165,7 @@ local_zone_create(struct local_zones* zones, uint8_t* nm, size_t len, } rbtree_init(&z->data, &local_data_cmp); lock_protect(&z->lock, &z->parent, sizeof(*z)-sizeof(rbnode_t)); - lock_protect(&zones->lock, &z->node, sizeof(z->node)); - lock_protect(&zones->lock, &z->parent, sizeof(z->parent)); - lock_protect(&zones->lock, &z->name, sizeof(z->name)); - lock_protect(&zones->lock, &z->namelen, sizeof(z->namelen)); - lock_protect(&zones->lock, &z->namelabs, sizeof(z->namelabs)); - lock_protect(&zones->lock, &z->dclass, sizeof(z->dclass)); - (void)zones; /* avoid argument unused warning if no lock checks */ + /* also the zones->lock protects node, parent, name*, class */ return z; } @@ -180,7 +174,7 @@ static struct local_zone* lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len, int labs, enum localzone_type t, uint16_t c) { - struct local_zone* z = local_zone_create(zones, nm, len, labs, t, c); + struct local_zone* z = local_zone_create(nm, len, labs, t, c); if(!z) { log_err("out of memory"); return NULL; @@ -1180,8 +1174,7 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones, enum localzone_type tp) { /* create */ - struct local_zone* z = local_zone_create(zones, name, len, labs, tp, - dclass); + struct local_zone* z = local_zone_create(name, len, labs, tp, dclass); if(!z) return NULL; lock_rw_wrlock(&z->lock); diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index 050a6d5b5..9d39334cd 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -58,10 +58,10 @@ usage() printf(" -s ip[@port] server address, if omitted config is used.\n"); printf(" -h show this usage help.\n"); printf("Commands:\n"); - printf(" start start server; runs unbound(8)\n"); - printf(" stop stops the server\n"); - printf(" reload reloads the server\n"); - printf(" stats print statistics\n"); + printf(" start start server; runs unbound(8)\n"); + printf(" stop stops the server\n"); + printf(" reload reloads the server\n"); + printf(" stats print statistics\n"); printf(" verbosity [number] change logging detail\n"); printf(" local_zone [name] [type] add new local zone\n"); printf(" local_zone_remove [name] remove local zone and its contents\n"); @@ -302,6 +302,11 @@ int main(int argc, char* argv[]) int c, ret; char* cfgfile = CONFIGFILE; char* svr = NULL; +#ifdef USE_THREAD_DEBUG + /* stop the file output from unbound-control, overwites the servers */ + extern int check_locking_order; + check_locking_order = 0; +#endif /* USE_THREAD_DEBUG */ log_ident_set("unbound-control"); log_init(NULL, 0, NULL); checklock_start(); diff --git a/testdata/09-unbound-control.tpkg b/testdata/09-unbound-control.tpkg index b75f18cd43a79e8b4a1b865a77d09e9c4510b906..92bf70528ce3d5c7865c85f6e7ac66b4bf3f1b56 100644 GIT binary patch literal 7157 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 F002k5;T-?~