Link Here
|
0 |
- |
1 |
--- bin/named/server.c.orig 2020-06-10 21:01:43 UTC |
|
|
2 |
+++ bin/named/server.c |
3 |
@@ -7578,6 +7578,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 |
@@ -7592,6 +7594,8 @@ cleanup: |
13 |
*num_zonesp = 0; |
14 |
} |
15 |
|
16 |
+ UNLOCK(&view->new_zone_lock); |
17 |
+ |
18 |
return (ISC_R_SUCCESS); |
19 |
} |
20 |
|
21 |
@@ -7920,6 +7924,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 |
@@ -8028,8 +8034,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 |
@@ -8055,6 +8064,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 |
@@ -8075,6 +8087,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(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, |
61 |
@@ -8108,6 +8122,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(named_g_addparser, &zoneconf); |
69 |
} |
70 |
@@ -12566,8 +12582,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 |
@@ -12647,8 +12661,6 @@ cleanup: |
80 |
} |
81 |
*txnp = NULL; |
82 |
|
83 |
- UNLOCK(&view->new_zone_lock); |
84 |
- |
85 |
if (text != NULL) { |
86 |
isc_buffer_free(&text); |
87 |
} |
88 |
@@ -12656,6 +12668,11 @@ cleanup: |
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 |
@@ -12685,6 +12702,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 |
@@ -12812,6 +12834,13 @@ cleanup: |
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 |
@@ -12834,6 +12863,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 |
@@ -12881,6 +12916,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 |
@@ -13016,6 +13053,8 @@ cleanup: |
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 |
@@ -13225,6 +13264,7 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, d |
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 |
@@ -13378,6 +13418,7 @@ cleanup: |
166 |
if (txn != NULL) { |
167 |
(void)nzd_close(&txn, false); |
168 |
} |
169 |
+ UNLOCK(&view->new_zone_lock); |
170 |
#endif /* HAVE_LMDB */ |
171 |
|
172 |
if (zone != NULL) { |
173 |
@@ -13401,6 +13442,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, d |
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 |
@@ -13598,6 +13640,7 @@ cleanup: |
182 |
if (txn != NULL) { |
183 |
(void)nzd_close(&txn, false); |
184 |
} |
185 |
+ UNLOCK(&view->new_zone_lock); |
186 |
#endif /* HAVE_LMDB */ |
187 |
|
188 |
if (zone != NULL) { |
189 |
@@ -13761,6 +13804,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(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, |
197 |
@@ -13778,6 +13822,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 /* ifdef HAVE_LMDB */ |
207 |
result = delete_zoneconf(view, cfg->add_parser, cfg->nzf_config, |
208 |
dns_zone_getorigin(zone), |
209 |
@@ -13867,11 +13916,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 |
- } |
217 |
-#endif /* ifdef HAVE_LMDB */ |
218 |
if (raw != NULL) { |
219 |
dns_zone_detach(&raw); |
220 |
} |
221 |
--- lib/dns/include/dns/lmdb.h.orig 2020-06-10 21:01:43 UTC |
222 |
+++ lib/dns/include/dns/lmdb.h |
223 |
@@ -10,12 +10,7 @@ |
224 |
*/ |
225 |
|
226 |
#include <lmdb.h> |
227 |
-/* |
228 |
- * MDB_NOTLS is used to prevent problems after configuration is reloaded, due |
229 |
- * to the way LMDB's use of thread-local storage (TLS) interacts with the BIND9 |
230 |
- * thread model. |
231 |
- */ |
232 |
-#define DNS_LMDB_COMMON_FLAGS (MDB_CREATE | MDB_NOSUBDIR | MDB_NOTLS) |
233 |
+#define DNS_LMDB_COMMON_FLAGS (MDB_CREATE | MDB_NOSUBDIR | MDB_NOLOCK) |
234 |
#ifndef __OpenBSD__ |
235 |
#define DNS_LMDB_FLAGS (DNS_LMDB_COMMON_FLAGS) |
236 |
#else /* __OpenBSD__ */ |