Link Here
|
0 |
- |
1 |
--- bin/named/server.c.orig 2020-06-10 18:00:37 UTC |
|
|
2 |
+++ bin/named/server.c |
3 |
@@ -6797,6 +6797,8 @@ count_newzones(dns_view_t *view, ns_cfgctx_t *nzcfg, i |
4 |
"for view '%s'", |
5 |
view->new_zone_db, view->name); |
6 |
|
7 |
+ LOCK(&view->new_zone_lock); |
8 |
+ |
9 |
CHECK(nzd_count(view, &n)); |
10 |
|
11 |
*num_zonesp = n; |
12 |
@@ -6811,6 +6813,8 @@ count_newzones(dns_view_t *view, ns_cfgctx_t *nzcfg, i |
13 |
if (result != ISC_R_SUCCESS) |
14 |
*num_zonesp = 0; |
15 |
|
16 |
+ UNLOCK(&view->new_zone_lock); |
17 |
+ |
18 |
return (ISC_R_SUCCESS); |
19 |
} |
20 |
|
21 |
@@ -7116,6 +7120,8 @@ typedef isc_result_t (*newzone_cfg_cb_t)(const cfg_obj |
22 |
* Immediately interrupt processing if an error is encountered while |
23 |
* transforming NZD data into a zone configuration object or if "callback" |
24 |
* returns an error. |
25 |
+ * |
26 |
+ * Caller must hold 'view->new_zone_lock'. |
27 |
*/ |
28 |
static isc_result_t |
29 |
for_all_newzone_cfgs(newzone_cfg_cb_t callback, cfg_obj_t *config, |
30 |
@@ -7228,8 +7234,11 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config |
31 |
return (ISC_R_SUCCESS); |
32 |
} |
33 |
|
34 |
+ LOCK(&view->new_zone_lock); |
35 |
+ |
36 |
result = nzd_open(view, MDB_RDONLY, &txn, &dbi); |
37 |
if (result != ISC_R_SUCCESS) { |
38 |
+ UNLOCK(&view->new_zone_lock); |
39 |
return (ISC_R_SUCCESS); |
40 |
} |
41 |
|
42 |
@@ -7256,6 +7265,9 @@ configure_newzones(dns_view_t *view, cfg_obj_t *config |
43 |
} |
44 |
|
45 |
(void) nzd_close(&txn, false); |
46 |
+ |
47 |
+ UNLOCK(&view->new_zone_lock); |
48 |
+ |
49 |
return (result); |
50 |
} |
51 |
|
52 |
@@ -7277,6 +7289,8 @@ get_newzone_config(dns_view_t *view, const char *zonen |
53 |
|
54 |
INSIST(zoneconfig != NULL && *zoneconfig == NULL); |
55 |
|
56 |
+ LOCK(&view->new_zone_lock); |
57 |
+ |
58 |
CHECK(nzd_open(view, MDB_RDONLY, &txn, &dbi)); |
59 |
|
60 |
isc_log_write(ns_g_lctx, |
61 |
@@ -7310,6 +7324,8 @@ get_newzone_config(dns_view_t *view, const char *zonen |
62 |
cleanup: |
63 |
(void) nzd_close(&txn, false); |
64 |
|
65 |
+ UNLOCK(&view->new_zone_lock); |
66 |
+ |
67 |
if (zoneconf != NULL) { |
68 |
cfg_obj_destroy(ns_g_addparser, &zoneconf); |
69 |
} |
70 |
@@ -11638,8 +11654,6 @@ nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone |
71 |
|
72 |
nzd_setkey(&key, dns_zone_getorigin(zone), namebuf, sizeof(namebuf)); |
73 |
|
74 |
- LOCK(&view->new_zone_lock); |
75 |
- |
76 |
if (zconfig == NULL) { |
77 |
/* We're deleting the zone from the database */ |
78 |
status = mdb_del(*txnp, dbi, &key, NULL); |
79 |
@@ -11739,8 +11753,6 @@ nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone |
80 |
} |
81 |
*txnp = NULL; |
82 |
|
83 |
- UNLOCK(&view->new_zone_lock); |
84 |
- |
85 |
if (text != NULL) { |
86 |
isc_buffer_free(&text); |
87 |
} |
88 |
@@ -11748,6 +11760,11 @@ nzd_save(MDB_txn **txnp, MDB_dbi dbi, dns_zone_t *zone |
89 |
return (result); |
90 |
} |
91 |
|
92 |
+/* |
93 |
+ * Check whether the new zone database for 'view' can be opened for writing. |
94 |
+ * |
95 |
+ * Caller must hold 'view->new_zone_lock'. |
96 |
+ */ |
97 |
static isc_result_t |
98 |
nzd_writable(dns_view_t *view) { |
99 |
isc_result_t result = ISC_R_SUCCESS; |
100 |
@@ -11779,6 +11796,11 @@ nzd_writable(dns_view_t *view) { |
101 |
return (result); |
102 |
} |
103 |
|
104 |
+/* |
105 |
+ * Open the new zone database for 'view' and start a transaction for it. |
106 |
+ * |
107 |
+ * Caller must hold 'view->new_zone_lock'. |
108 |
+ */ |
109 |
static isc_result_t |
110 |
nzd_open(dns_view_t *view, unsigned int flags, MDB_txn **txnp, MDB_dbi *dbi) { |
111 |
int status; |
112 |
@@ -11909,6 +11931,13 @@ nzd_env_reopen(dns_view_t *view) { |
113 |
return (result); |
114 |
} |
115 |
|
116 |
+/* |
117 |
+ * If 'commit' is true, commit the new zone database transaction pointed to by |
118 |
+ * 'txnp'; otherwise, abort that transaction. |
119 |
+ * |
120 |
+ * Caller must hold 'view->new_zone_lock' for the view that the transaction |
121 |
+ * pointed to by 'txnp' was started for. |
122 |
+ */ |
123 |
static isc_result_t |
124 |
nzd_close(MDB_txn **txnp, bool commit) { |
125 |
isc_result_t result = ISC_R_SUCCESS; |
126 |
@@ -11931,6 +11960,12 @@ nzd_close(MDB_txn **txnp, bool commit) { |
127 |
return (result); |
128 |
} |
129 |
|
130 |
+/* |
131 |
+ * Count the zones configured in the new zone database for 'view' and store the |
132 |
+ * result in 'countp'. |
133 |
+ * |
134 |
+ * Caller must hold 'view->new_zone_lock'. |
135 |
+ */ |
136 |
static isc_result_t |
137 |
nzd_count(dns_view_t *view, int *countp) { |
138 |
isc_result_t result; |
139 |
@@ -11979,6 +12014,8 @@ migrate_nzf(dns_view_t *view) { |
140 |
MDB_val key, data; |
141 |
ns_dzarg_t dzarg; |
142 |
|
143 |
+ LOCK(&view->new_zone_lock); |
144 |
+ |
145 |
/* |
146 |
* If NZF file doesn't exist, or NZD DB exists and already |
147 |
* has data, return without attempting migration. |
148 |
@@ -12122,6 +12159,8 @@ migrate_nzf(dns_view_t *view) { |
149 |
result = nzd_close(&txn, commit); |
150 |
} |
151 |
|
152 |
+ UNLOCK(&view->new_zone_lock); |
153 |
+ |
154 |
if (text != NULL) { |
155 |
isc_buffer_free(&text); |
156 |
} |
157 |
@@ -12325,6 +12364,7 @@ do_addzone(ns_server_t *server, ns_cfgctx_t *cfg, dns_ |
158 |
MDB_dbi dbi; |
159 |
|
160 |
UNUSED(zoneconf); |
161 |
+ LOCK(&view->new_zone_lock); |
162 |
#endif /* HAVE_LMDB */ |
163 |
|
164 |
/* Zone shouldn't already exist */ |
165 |
@@ -12465,6 +12505,7 @@ do_addzone(ns_server_t *server, ns_cfgctx_t *cfg, dns_ |
166 |
#else /* HAVE_LMDB */ |
167 |
if (txn != NULL) |
168 |
(void) nzd_close(&txn, false); |
169 |
+ UNLOCK(&view->new_zone_lock); |
170 |
#endif /* HAVE_LMDB */ |
171 |
|
172 |
if (zone != NULL) |
173 |
@@ -12488,6 +12529,7 @@ do_modzone(ns_server_t *server, ns_cfgctx_t *cfg, dns_ |
174 |
#else /* HAVE_LMDB */ |
175 |
MDB_txn *txn = NULL; |
176 |
MDB_dbi dbi; |
177 |
+ LOCK(&view->new_zone_lock); |
178 |
#endif /* HAVE_LMDB */ |
179 |
|
180 |
/* Zone must already exist */ |
181 |
@@ -12667,6 +12709,7 @@ do_modzone(ns_server_t *server, ns_cfgctx_t *cfg, dns_ |
182 |
#else /* HAVE_LMDB */ |
183 |
if (txn != NULL) |
184 |
(void) nzd_close(&txn, false); |
185 |
+ UNLOCK(&view->new_zone_lock); |
186 |
#endif /* HAVE_LMDB */ |
187 |
|
188 |
if (zone != NULL) |
189 |
@@ -12816,6 +12859,7 @@ rmzone(isc_task_t *task, isc_event_t *event) { |
190 |
if (added && cfg != NULL) { |
191 |
#ifdef HAVE_LMDB |
192 |
/* Make sure we can open the NZD database */ |
193 |
+ LOCK(&view->new_zone_lock); |
194 |
result = nzd_open(view, 0, &txn, &dbi); |
195 |
if (result != ISC_R_SUCCESS) { |
196 |
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, |
197 |
@@ -12834,6 +12878,11 @@ rmzone(isc_task_t *task, isc_event_t *event) { |
198 |
"delete zone configuration: %s", |
199 |
isc_result_totext(result)); |
200 |
} |
201 |
+ |
202 |
+ if (txn != NULL) { |
203 |
+ (void)nzd_close(&txn, false); |
204 |
+ } |
205 |
+ UNLOCK(&view->new_zone_lock); |
206 |
#else |
207 |
result = delete_zoneconf(view, cfg->add_parser, |
208 |
cfg->nzf_config, |
209 |
@@ -12926,10 +12975,6 @@ rmzone(isc_task_t *task, isc_event_t *event) { |
210 |
} |
211 |
} |
212 |
|
213 |
-#ifdef HAVE_LMDB |
214 |
- if (txn != NULL) |
215 |
- (void) nzd_close(&txn, false); |
216 |
-#endif |
217 |
if (raw != NULL) |
218 |
dns_zone_detach(&raw); |
219 |
dns_zone_detach(&zone); |
220 |
--- lib/dns/include/dns/view.h.orig 2020-06-10 18:00:37 UTC |
221 |
+++ lib/dns/include/dns/view.h |
222 |
@@ -240,12 +240,7 @@ struct dns_view { |
223 |
|
224 |
#ifdef HAVE_LMDB |
225 |
#include <lmdb.h> |
226 |
-/* |
227 |
- * MDB_NOTLS is used to prevent problems after configuration is reloaded, due |
228 |
- * to the way LMDB's use of thread-local storage (TLS) interacts with the BIND9 |
229 |
- * thread model. |
230 |
- */ |
231 |
-#define DNS_LMDB_COMMON_FLAGS (MDB_CREATE | MDB_NOSUBDIR | MDB_NOTLS) |
232 |
+#define DNS_LMDB_COMMON_FLAGS (MDB_CREATE | MDB_NOSUBDIR | MDB_NOLOCK) |
233 |
#ifndef __OpenBSD__ |
234 |
#define DNS_LMDB_FLAGS (DNS_LMDB_COMMON_FLAGS) |
235 |
#else /* __OpenBSD__ */ |