From 23f64ea0dcd7f5b7094ae6ade2a002fb7dde1466 Mon Sep 17 00:00:00 2001 From: Brian Wellington Date: Wed, 6 Dec 2000 01:08:41 +0000 Subject: [PATCH] 594. [func] sdb drivers are now assumed to not be thread-safe unless the DNS_SDBFLAG_THREADSAFE flag is supplied. (also make the dirdb.c driver specify DNS_SDBFLAG_THREADSAFE) --- CHANGES | 3 +++ contrib/sdb/dir/dirdb.c | 5 +++-- contrib/sdb/dirdb.c | 5 +++-- lib/dns/include/dns/sdb.h | 7 ++++++- lib/dns/sdb.c | 25 ++++++++++++++++++++++++- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 99d045a322..8e3b4979ee 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,7 @@ + 594. [func] sdb drivers are now assumed to not be thread-safe + unless the DNS_SDBFLAG_THREADSAFE flag is supplied. + 593. [bug] If a secure zone was missing all its NXTs and a dynamic update was attempted, the server entered an infinite loop. diff --git a/contrib/sdb/dir/dirdb.c b/contrib/sdb/dir/dirdb.c index 93ec287360..009b61896f 100644 --- a/contrib/sdb/dir/dirdb.c +++ b/contrib/sdb/dir/dirdb.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dirdb.c,v 1.6 2000/12/06 00:59:06 bwelling Exp $ */ +/* $Id: dirdb.c,v 1.7 2000/12/06 01:08:37 bwelling Exp $ */ #include @@ -178,7 +178,8 @@ static dns_sdbmethods_t dirdb_methods = { isc_result_t dirdb_init(void) { unsigned int flags; - flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA; + flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA | + DNS_SDBFLAG_THREADSAFE; return (dns_sdb_register("dir", &dirdb_methods, ns_g_mctx, flags, ns_g_mctx, &dirdb)); } diff --git a/contrib/sdb/dirdb.c b/contrib/sdb/dirdb.c index 93ec287360..009b61896f 100644 --- a/contrib/sdb/dirdb.c +++ b/contrib/sdb/dirdb.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dirdb.c,v 1.6 2000/12/06 00:59:06 bwelling Exp $ */ +/* $Id: dirdb.c,v 1.7 2000/12/06 01:08:37 bwelling Exp $ */ #include @@ -178,7 +178,8 @@ static dns_sdbmethods_t dirdb_methods = { isc_result_t dirdb_init(void) { unsigned int flags; - flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA; + flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA | + DNS_SDBFLAG_THREADSAFE; return (dns_sdb_register("dir", &dirdb_methods, ns_g_mctx, flags, ns_g_mctx, &dirdb)); } diff --git a/lib/dns/include/dns/sdb.h b/lib/dns/include/dns/sdb.h index 86c9871b59..28ef49c6f4 100644 --- a/lib/dns/include/dns/sdb.h +++ b/lib/dns/include/dns/sdb.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.h,v 1.10 2000/11/16 23:10:19 gson Exp $ */ +/* $Id: sdb.h,v 1.11 2000/12/06 01:08:39 bwelling Exp $ */ #ifndef DNS_SDB_H #define DNS_SDB_H 1 @@ -90,6 +90,7 @@ ISC_LANG_BEGINDECLS #define DNS_SDBFLAG_RELATIVEOWNER 0x00000001U #define DNS_SDBFLAG_RELATIVERDATA 0x00000002U +#define DNS_SDBFLAG_THREADSAFE 0x00000004U isc_result_t dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, @@ -144,6 +145,10 @@ dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, * include relative names. Otherwise, all names in the rdata string must * be absolute. Be aware that if relative names are allowed, any * absolute names must contain a trailing dot. + * + * If flags includes DNS_SDBFLAG_THREADSAFE, the driver must be able to + * handle multiple lookups in parallel. Otherwise, calls into the driver + * are serialized. */ void diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index 9792980740..01ace98949 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.c,v 1.20 2000/12/01 01:22:43 marka Exp $ */ +/* $Id: sdb.c,v 1.21 2000/12/06 01:08:38 bwelling Exp $ */ #include @@ -114,6 +114,20 @@ typedef struct sdb_rdatasetiter { /* This is a reasonable value */ #define SDB_DEFAULT_TTL (60 * 60 * 24) +#define MAYBE_LOCK(sdb) \ + do { \ + unsigned int flags = sdb->implementation->flags; \ + if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \ + LOCK(&sdb->lock); \ + } while (0) + +#define MAYBE_UNLOCK(sdb) \ + do { \ + unsigned int flags = sdb->implementation->flags; \ + if ((flags & DNS_SDBFLAG_THREADSAFE) == 0) \ + UNLOCK(&sdb->lock); \ + } while (0) + static int dummy; static isc_result_t dns_sdb_create(isc_mem_t *mctx, dns_name_t *origin, @@ -193,6 +207,9 @@ dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, REQUIRE(methods->lookup != NULL); REQUIRE(mctx != NULL); REQUIRE(sdbimp != NULL && *sdbimp == NULL); + REQUIRE((flags & ~(DNS_SDBFLAG_RELATIVEOWNER | + DNS_SDBFLAG_RELATIVERDATA | + DNS_SDBFLAG_THREADSAFE)) == 0); imp = isc_mem_get(mctx, sizeof(dns_sdbimplementation_t)); if (imp == NULL) @@ -663,14 +680,18 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, isorigin = dns_name_equal(name, &sdb->common.origin); + MAYBE_LOCK(sdb); result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, node); + MAYBE_UNLOCK(sdb); if (result != ISC_R_SUCCESS && !isorigin) { destroynode(node); return (result); } if (isorigin && imp->methods->authority != NULL) { + MAYBE_LOCK(sdb); result = imp->methods->authority(sdb->zone, sdb->dbdata, node); + MAYBE_UNLOCK(sdb); if (result != ISC_R_SUCCESS) { destroynode(node); return (result); @@ -937,7 +958,9 @@ createiterator(dns_db_t *db, isc_boolean_t relative_names, sdbiter->current = NULL; sdbiter->origin = NULL; + MAYBE_LOCK(sdb); result = imp->methods->allnodes(sdb->zone, sdb->dbdata, sdbiter); + MAYBE_UNLOCK(sdb); if (result != ISC_R_SUCCESS) { dbiterator_destroy((dns_dbiterator_t **)&sdbiter); return (result);