|
Lines 67-73
Link Here
|
| 67 |
#include <sys/types.h> |
67 |
#include <sys/types.h> |
| 68 |
#include <sys/file.h> |
68 |
#include <sys/file.h> |
| 69 |
#include <sys/stat.h> |
69 |
#include <sys/stat.h> |
| 70 |
#include <db.h> |
70 |
#include <lmdb.h> |
| 71 |
#include <stdbool.h> |
71 |
#include <stdbool.h> |
| 72 |
#include <assert.h> |
72 |
#include <assert.h> |
| 73 |
|
73 |
|
|
Lines 91-100
Link Here
|
| 91 |
|
91 |
|
| 92 |
CacheMasterEntry cache_master_entry; |
92 |
CacheMasterEntry cache_master_entry; |
| 93 |
|
93 |
|
| 94 |
DB *dbp; |
94 |
MDB_env *env; |
| 95 |
#ifdef WITH_DB42 |
95 |
MDB_dbi dbi; |
| 96 |
DB_ENV *dbenvp; |
|
|
| 97 |
#endif |
| 98 |
static FILE *lock_fp=NULL; |
96 |
static FILE *lock_fp=NULL; |
| 99 |
|
97 |
|
| 100 |
static struct filter cache_filter; |
98 |
static struct filter cache_filter; |
|
Lines 110-126
Link Here
|
| 110 |
} |
108 |
} |
| 111 |
} |
109 |
} |
| 112 |
|
110 |
|
| 113 |
#ifdef WITH_DB42 |
111 |
static void cache_error_message(int rv, char *msg) |
| 114 |
static void cache_panic_call(DB_ENV *dbenvp, int errval) |
|
|
| 115 |
{ |
112 |
{ |
| 116 |
exit(1); |
113 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
|
|
114 |
"database error: %s: %s (%d)\n", |
| 115 |
msg, mdb_strerror(rv), rv); |
| 117 |
} |
116 |
} |
| 118 |
#endif |
|
|
| 119 |
|
117 |
|
| 120 |
static void cache_error_message(const char *errpfx, char *msg) |
118 |
int mdb_message_func(const char *msg, void *ctx) { |
| 121 |
{ |
119 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, |
| 122 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
120 |
"%s\n", msg); |
| 123 |
"database error: %s", msg); |
121 |
return 0; |
| 124 |
} |
122 |
} |
| 125 |
|
123 |
|
| 126 |
int cache_lock(void) |
124 |
int cache_lock(void) |
|
Lines 130-136
Link Here
|
| 130 |
|
128 |
|
| 131 |
assert(!lock_fp); |
129 |
assert(!lock_fp); |
| 132 |
|
130 |
|
| 133 |
rv = snprintf(lock_file, PATH_MAX, "%s/cache.db.lock", cache_dir); |
131 |
rv = snprintf(lock_file, PATH_MAX, "%s/cache.lock", cache_dir); |
| 134 |
if (rv < 0 || rv >= PATH_MAX) |
132 |
if (rv < 0 || rv >= PATH_MAX) |
| 135 |
abort(); |
133 |
abort(); |
| 136 |
|
134 |
|
|
Lines 155-219
Link Here
|
| 155 |
int cache_init(void) |
153 |
int cache_init(void) |
| 156 |
{ |
154 |
{ |
| 157 |
int rv; |
155 |
int rv; |
| 158 |
char file[PATH_MAX]; |
156 |
char mdb_dir[PATH_MAX]; |
|
|
157 |
MDB_txn *txn; |
| 159 |
|
158 |
|
| 160 |
snprintf(file, PATH_MAX, "%s/cache.db", cache_dir); |
159 |
snprintf(mdb_dir, PATH_MAX, "%s/cache", cache_dir); |
| 161 |
|
160 |
|
| 162 |
#ifdef WITH_DB42 |
161 |
if ((rv = mdb_env_create(&env)) != 0) { |
| 163 |
if ((rv = db_env_create(&dbenvp, 0)) != 0) { |
|
|
| 164 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
162 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 165 |
"creating database environment failed"); |
163 |
"creating environment handle failed"); |
|
|
164 |
cache_error_message(rv, "mdb_env_create"); |
| 166 |
return rv; |
165 |
return rv; |
| 167 |
} |
166 |
} |
| 168 |
dbenvp->set_errcall(dbenvp, cache_error_message); |
167 |
if ((rv = mdb_env_set_mapsize(env, 1992294400)) != 0) { |
| 169 |
dbenvp->set_paniccall(dbenvp, cache_panic_call); |
|
|
| 170 |
if ((rv = dbenvp->open(dbenvp, cache_dir, DB_CREATE | DB_INIT_MPOOL | |
| 171 |
/*DB_INIT_LOCK | */DB_INIT_LOG | DB_INIT_TXN | |
| 172 |
DB_RECOVER, 0600)) != 0) { |
| 173 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
168 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 174 |
"opening database environment failed"); |
169 |
"setting mdb mapsize failed"); |
| 175 |
dbenvp->err(dbenvp, rv, "%s", "environment"); |
170 |
cache_error_message(rv, "mdb_env_set_mapsize"); |
| 176 |
return rv; |
171 |
return rv; |
| 177 |
} |
172 |
} |
| 178 |
if ((rv = db_create(&dbp, dbenvp, 0)) != 0) { |
173 |
if ((rv = mdb_env_open(env, mdb_dir, MDB_NORDAHEAD, 0600)) != 0) { |
| 179 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
174 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 180 |
"creating database handle failed"); |
175 |
"opening database failed"); |
|
|
176 |
cache_error_message(rv, "mdb_env_open"); |
| 181 |
return rv; |
177 |
return rv; |
| 182 |
} |
178 |
} |
| 183 |
if ((rv = dbp->open(dbp, NULL, "cache.db", NULL, DB_BTREE, |
179 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_init)"); |
| 184 |
DB_CREATE | DB_CHKSUM | DB_AUTO_COMMIT, |
180 |
if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) { |
| 185 |
0600)) != 0) { |
181 |
cache_error_message(rv, "mdb_txn_begin"); |
| 186 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
182 |
mdb_env_close(env); |
| 187 |
"opening database failed"); |
|
|
| 188 |
dbp->err(dbp, rv, "open"); |
| 189 |
// FIXME: free dbp |
| 190 |
return rv; |
183 |
return rv; |
| 191 |
} |
184 |
} |
| 192 |
#else |
185 |
if ((rv = mdb_open(txn, NULL, 0, &dbi)) != 0) { |
| 193 |
if ((rv = db_create(&dbp, NULL, 0)) != 0) { |
186 |
cache_error_message(rv, "mdb_open"); |
| 194 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
187 |
mdb_txn_abort(txn); |
| 195 |
"creating database handle failed"); |
188 |
mdb_env_close(env); |
| 196 |
return rv; |
189 |
return rv; |
| 197 |
} |
190 |
} |
| 198 |
if ((rv = dbp->open(dbp, file, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) { |
191 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_init)"); |
| 199 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
192 |
if ((rv = mdb_txn_commit(txn)) != 0) { |
| 200 |
"opening database failed"); |
193 |
cache_error_message(rv, "mdb_txn_commit"); |
| 201 |
dbp->err(dbp, rv, "open"); |
194 |
mdb_dbi_close(env, dbi); |
| 202 |
// FIXME: free dbp |
195 |
mdb_env_close(env); |
| 203 |
return rv; |
196 |
return rv; |
| 204 |
} |
197 |
} |
| 205 |
dbp->set_errcall(dbp, cache_error_message); |
198 |
|
| 206 |
#endif |
|
|
| 207 |
setup_cache_filter(); |
199 |
setup_cache_filter(); |
| 208 |
return 0; |
200 |
return 0; |
| 209 |
} |
201 |
} |
| 210 |
|
202 |
|
| 211 |
void cache_sync(void) { |
|
|
| 212 |
if (!INIT_ONLY && dbp) { |
| 213 |
dbp->sync(dbp, 0); |
| 214 |
} |
| 215 |
} |
| 216 |
|
| 217 |
int cache_set_schema_id(const NotifierID value) |
203 |
int cache_set_schema_id(const NotifierID value) |
| 218 |
{ |
204 |
{ |
| 219 |
int rv, fd, len; |
205 |
int rv, fd, len; |
|
Lines 297-379
Link Here
|
| 297 |
|
283 |
|
| 298 |
int cache_get_master_entry(CacheMasterEntry *master_entry) |
284 |
int cache_get_master_entry(CacheMasterEntry *master_entry) |
| 299 |
{ |
285 |
{ |
| 300 |
DBT key, data; |
286 |
MDB_txn *txn; |
|
|
287 |
MDB_cursor *cursor; |
| 288 |
MDB_val key, data; |
| 301 |
int rv; |
289 |
int rv; |
| 302 |
|
290 |
|
| 303 |
memset(&key, 0, sizeof(DBT)); |
291 |
memset(&key, 0, sizeof(MDB_val)); |
| 304 |
memset(&data, 0, sizeof(DBT)); |
292 |
memset(&data, 0, sizeof(MDB_val)); |
| 305 |
|
293 |
|
| 306 |
key.data=MASTER_KEY; |
294 |
key.mv_data=MASTER_KEY; |
| 307 |
key.size=MASTER_KEY_SIZE; |
295 |
key.mv_size=MASTER_KEY_SIZE; |
| 308 |
data.flags = DB_DBT_REALLOC; |
|
|
| 309 |
|
296 |
|
| 310 |
if ((rv=dbp->get(dbp, NULL, &key, &data, 0)) == DB_NOTFOUND) |
297 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_get_master_entry)"); |
|
|
298 |
if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) { |
| 299 |
cache_error_message(rv, "mdb_txn_begin"); |
| 311 |
return rv; |
300 |
return rv; |
|
|
301 |
} |
| 302 |
if ((rv = mdb_cursor_open(txn, dbi, &cursor)) != 0) { |
| 303 |
cache_error_message(rv, "mdb_cursor_open"); |
| 304 |
mdb_txn_abort(txn); |
| 305 |
return rv; |
| 306 |
} |
| 307 |
if ((rv = mdb_cursor_get(cursor, &key, &data, MDB_SET_KEY)) == MDB_NOTFOUND) { |
| 308 |
mdb_cursor_close(cursor); |
| 309 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_get_master_entry)"); |
| 310 |
mdb_txn_abort(txn); |
| 311 |
return rv; |
| 312 |
} |
| 312 |
else if (rv != 0) { |
313 |
else if (rv != 0) { |
| 313 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
314 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 314 |
"reading master entry from database failed"); |
315 |
"reading master entry from database failed"); |
| 315 |
dbp->err(dbp, rv, "get"); |
316 |
cache_error_message(rv, "mdb_get"); |
|
|
317 |
mdb_cursor_close(cursor); |
| 318 |
mdb_txn_abort(txn); |
| 316 |
return rv; |
319 |
return rv; |
| 317 |
} |
320 |
} |
|
|
321 |
mdb_cursor_close(cursor); |
| 322 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_get_master_entry)"); |
| 323 |
mdb_txn_abort(txn); |
| 318 |
|
324 |
|
| 319 |
if (data.size != sizeof(CacheMasterEntry)) { |
325 |
if (data.mv_size != sizeof(CacheMasterEntry)) { |
| 320 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
326 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 321 |
"master entry has unexpected length"); |
327 |
"master entry has unexpected length"); |
| 322 |
return 1; |
328 |
return 1; |
| 323 |
} |
329 |
} |
| 324 |
|
330 |
|
| 325 |
memcpy(master_entry, data.data, sizeof(CacheMasterEntry)); |
331 |
memcpy(master_entry, data.mv_data, sizeof(CacheMasterEntry)); |
| 326 |
free(data.data); |
|
|
| 327 |
|
332 |
|
| 328 |
return 0; |
333 |
return 0; |
| 329 |
} |
334 |
} |
| 330 |
|
335 |
|
| 331 |
int cache_update_master_entry(CacheMasterEntry *master_entry, DB_TXN *dbtxnp) |
336 |
/* The dbtxnp argument is only used when WITH_DB42 is defined - useless? */ |
|
|
337 |
int cache_update_master_entry(CacheMasterEntry *master_entry, MDB_txn *dbtxnp) |
| 332 |
{ |
338 |
{ |
| 333 |
DBT key, data; |
339 |
MDB_txn *txn = dbtxnp; |
|
|
340 |
MDB_val key, data; |
| 334 |
int rv; |
341 |
int rv; |
| 335 |
int flags; |
342 |
int flags; |
| 336 |
|
343 |
|
| 337 |
memset(&key, 0, sizeof(DBT)); |
344 |
memset(&key, 0, sizeof(MDB_val)); |
| 338 |
memset(&data, 0, sizeof(DBT)); |
345 |
memset(&data, 0, sizeof(MDB_val)); |
| 339 |
|
346 |
|
| 340 |
key.data=MASTER_KEY; |
347 |
key.mv_data=MASTER_KEY; |
| 341 |
key.size=MASTER_KEY_SIZE; |
348 |
key.mv_size=MASTER_KEY_SIZE; |
| 342 |
|
349 |
|
| 343 |
data.data=(void*)master_entry; |
350 |
data.mv_data=(void*)master_entry; |
| 344 |
data.size=sizeof(CacheMasterEntry); |
351 |
data.mv_size=sizeof(CacheMasterEntry); |
| 345 |
|
352 |
|
| 346 |
#ifdef WITH_DB42 |
353 |
flags = 0; |
| 347 |
if (dbtxnp == NULL) |
|
|
| 348 |
flags = DB_AUTO_COMMIT; |
| 349 |
else |
| 350 |
#endif |
| 351 |
flags = 0; |
| 352 |
|
354 |
|
| 353 |
if ((rv=dbp->put(dbp, dbtxnp, &key, &data, flags)) != 0) { |
355 |
if (!dbtxnp) { |
|
|
356 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_update_master_entry)"); |
| 357 |
} |
| 358 |
if (!dbtxnp && (rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) { |
| 359 |
cache_error_message(rv, "mdb_txn_begin"); |
| 360 |
return rv; |
| 361 |
} |
| 362 |
if ((rv = mdb_put(txn, dbi, &key, &data, flags)) != 0) { |
| 354 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
363 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 355 |
"storing master entry in database failed"); |
364 |
"storing master entry in database failed"); |
| 356 |
dbp->err(dbp, rv, "put"); |
365 |
cache_error_message(rv, "mdb_put"); |
|
|
366 |
mdb_txn_abort(txn); |
| 357 |
return rv; |
367 |
return rv; |
| 358 |
} |
368 |
} |
|
|
369 |
if (!dbtxnp) { |
| 370 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_update_master_entry)"); |
| 371 |
} |
| 372 |
if (!dbtxnp && (rv = mdb_txn_commit(txn)) != 0) { |
| 373 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 374 |
"storing master entry in database failed"); |
| 375 |
cache_error_message(rv, "mdb_txn_commit"); |
| 376 |
return rv; |
| 377 |
} |
| 359 |
|
378 |
|
| 360 |
cache_sync(); |
|
|
| 361 |
|
| 362 |
return 0; |
379 |
return 0; |
| 363 |
} |
380 |
} |
| 364 |
|
381 |
|
| 365 |
DB_TXN* cache_new_transaction(NotifierID id, char *dn) |
382 |
MDB_txn *cache_new_transaction(NotifierID id, char *dn) |
| 366 |
{ |
383 |
{ |
| 367 |
#ifdef WITH_DB42 |
384 |
#ifdef WITH_DB42 |
| 368 |
DB_TXN *dbtxnp; |
385 |
int rv; |
|
|
386 |
MDB_txn *txn; |
| 369 |
CacheMasterEntry master_entry; |
387 |
CacheMasterEntry master_entry; |
| 370 |
NotifierID *old_id; |
388 |
NotifierID *old_id; |
| 371 |
|
389 |
|
| 372 |
dbenvp->txn_begin(dbenvp, NULL, &dbtxnp, 0); |
390 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_new_transaction)"); |
|
|
391 |
if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) { |
| 392 |
cache_error_message(rv, "mdb_txn_begin"); |
| 393 |
return NULL; |
| 394 |
} |
| 373 |
|
395 |
|
| 374 |
if (id != 0) { |
396 |
if (id != 0) { |
| 375 |
if (cache_get_master_entry(&master_entry) != 0) { |
397 |
if (cache_get_master_entry(&master_entry) != 0) { |
| 376 |
dbtxnp->abort(dbtxnp); |
398 |
mdb_txn_abort(txn); |
| 377 |
return NULL; |
399 |
return NULL; |
| 378 |
} |
400 |
} |
| 379 |
|
401 |
|
|
Lines 386-403
Link Here
|
| 386 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
408 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 387 |
"New ID (%ld) is not greater than old" |
409 |
"New ID (%ld) is not greater than old" |
| 388 |
" ID (%ld): %s", id, *old_id, dn); |
410 |
" ID (%ld): %s", id, *old_id, dn); |
| 389 |
dbtxnp->abort(dbtxnp); |
411 |
mdb_txn_abort(txn); |
| 390 |
return NULL; |
412 |
return NULL; |
| 391 |
} else |
413 |
} else |
| 392 |
*old_id = id; |
414 |
*old_id = id; |
| 393 |
|
415 |
|
| 394 |
if (cache_update_master_entry(&master_entry, dbtxnp) != 0) { |
416 |
if (cache_update_master_entry(&master_entry, txn) != 0) { |
| 395 |
dbtxnp->abort(dbtxnp); |
417 |
mdb_txn_abort(txn); |
| 396 |
return NULL; |
418 |
return NULL; |
| 397 |
} |
419 |
} |
| 398 |
} |
420 |
} |
| 399 |
|
421 |
|
| 400 |
return dbtxnp; |
422 |
return txn; |
| 401 |
#else |
423 |
#else |
| 402 |
return NULL; |
424 |
return NULL; |
| 403 |
#endif |
425 |
#endif |
|
Lines 410-423
Link Here
|
| 410 |
cache_delete_entry do nothing (at least if WITH_DB42 is undefined) */ |
432 |
cache_delete_entry do nothing (at least if WITH_DB42 is undefined) */ |
| 411 |
inline int cache_update_entry(NotifierID id, char *dn, CacheEntry *entry) |
433 |
inline int cache_update_entry(NotifierID id, char *dn, CacheEntry *entry) |
| 412 |
{ |
434 |
{ |
| 413 |
DBT key, data; |
435 |
MDB_txn *txn; |
| 414 |
DB_TXN *dbtxnp; |
436 |
MDB_val key, data; |
| 415 |
int rv = 0; |
437 |
int rv = 0; |
| 416 |
|
438 |
|
| 417 |
memset(&key, 0, sizeof(DBT)); |
439 |
memset(&key, 0, sizeof(MDB_val)); |
| 418 |
memset(&data, 0, sizeof(DBT)); |
440 |
memset(&data, 0, sizeof(MDB_val)); |
| 419 |
|
441 |
|
| 420 |
if ((rv=unparse_entry(&data.data, &data.size, entry)) != 0) { |
442 |
if ((rv=unparse_entry(&data.mv_data, &data.mv_size, entry)) != 0) { |
| 421 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
443 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 422 |
"unparsing entry failed"); |
444 |
"unparsing entry failed"); |
| 423 |
return rv; |
445 |
return rv; |
|
Lines 426-465
Link Here
|
| 426 |
|
448 |
|
| 427 |
signals_block(); |
449 |
signals_block(); |
| 428 |
#ifdef WITH_DB42 |
450 |
#ifdef WITH_DB42 |
| 429 |
dbtxnp = cache_new_transaction(id, dn); |
451 |
txn = cache_new_transaction(id, dn); |
| 430 |
if (dbtxnp == NULL) { |
452 |
if (txn == NULL) { |
| 431 |
signals_unblock(); |
453 |
signals_unblock(); |
| 432 |
free(data.data); |
|
|
| 433 |
return 1; |
454 |
return 1; |
| 434 |
} |
455 |
} |
| 435 |
#else |
456 |
#else |
| 436 |
dbtxnp = NULL; |
457 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_update_entry)"); |
|
|
458 |
if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) { |
| 459 |
cache_error_message(rv, "mdb_txn_begin"); |
| 460 |
signals_unblock(); |
| 461 |
return rv; |
| 462 |
} |
| 437 |
#endif |
463 |
#endif |
| 438 |
|
464 |
|
| 439 |
key.data=dn; |
465 |
key.mv_data=dn; |
| 440 |
key.size=strlen(dn)+1; |
466 |
key.mv_size=strlen(dn)+1; |
| 441 |
|
467 |
|
| 442 |
if ((rv=dbp->put(dbp, dbtxnp, &key, &data, 0)) != 0) { |
468 |
if ((rv = mdb_put(txn, dbi, &key, &data, 0)) != 0) { |
| 443 |
signals_unblock(); |
469 |
signals_unblock(); |
| 444 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
470 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 445 |
"storing entry in database failed: %s", dn); |
471 |
"storing entry in database failed: %s", dn); |
| 446 |
dbp->err(dbp, rv, "put"); |
472 |
cache_error_message(rv, "mdb_put"); |
| 447 |
#ifdef WITH_DB42 |
473 |
mdb_txn_abort(txn); |
| 448 |
dbtxnp->abort(dbtxnp); |
|
|
| 449 |
#endif |
| 450 |
free(data.data); |
| 451 |
return rv; |
474 |
return rv; |
| 452 |
} |
475 |
} |
| 453 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %d bytes for %s", data.size, dn); |
476 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %zu bytes for %s", data.mv_size, dn); |
| 454 |
|
477 |
|
| 455 |
|
478 |
|
| 456 |
#ifdef WITH_DB42 |
479 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_update_entry)"); |
| 457 |
dbtxnp->commit(dbtxnp, 0); |
480 |
if ((rv = mdb_txn_commit(txn)) != 0) { |
| 458 |
#endif |
481 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 459 |
cache_sync(); |
482 |
"storing updated entry in database failed"); |
|
|
483 |
cache_error_message(rv, "mdb_txn_commit"); |
| 484 |
return rv; |
| 485 |
} |
| 486 |
|
| 460 |
signals_unblock(); |
487 |
signals_unblock(); |
| 461 |
|
488 |
|
| 462 |
free(data.data); |
|
|
| 463 |
return rv; |
489 |
return rv; |
| 464 |
} |
490 |
} |
| 465 |
|
491 |
|
|
Lines 482-518
Link Here
|
| 482 |
|
508 |
|
| 483 |
int cache_delete_entry(NotifierID id, char *dn) |
509 |
int cache_delete_entry(NotifierID id, char *dn) |
| 484 |
{ |
510 |
{ |
| 485 |
DB_TXN *dbtxnp; |
511 |
MDB_txn *txn; |
| 486 |
DBT key; |
512 |
MDB_val key; |
| 487 |
int rv; |
513 |
int rv; |
| 488 |
|
514 |
|
| 489 |
memset(&key, 0, sizeof(DBT)); |
515 |
memset(&key, 0, sizeof(MDB_val)); |
| 490 |
|
516 |
|
| 491 |
key.data=dn; |
517 |
key.mv_data=dn; |
| 492 |
key.size=strlen(dn)+1; |
518 |
key.mv_size=strlen(dn)+1; |
| 493 |
|
519 |
|
| 494 |
signals_block(); |
520 |
signals_block(); |
| 495 |
#ifdef WITH_DB42 |
521 |
#ifdef WITH_DB42 |
| 496 |
dbtxnp = cache_new_transaction(id, dn); |
522 |
txn = cache_new_transaction(id, dn); |
| 497 |
if (dbtxnp == NULL) { |
523 |
if (txn == NULL) { |
| 498 |
signals_unblock(); |
524 |
signals_unblock(); |
| 499 |
return 1; |
525 |
return 1; |
| 500 |
} |
526 |
} |
| 501 |
#else |
527 |
#else |
| 502 |
dbtxnp = NULL; |
528 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_delete_entry)"); |
|
|
529 |
if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) { |
| 530 |
cache_error_message(rv, "mdb_txn_begin"); |
| 531 |
return rv; |
| 532 |
} |
| 503 |
#endif |
533 |
#endif |
| 504 |
|
534 |
|
| 505 |
if ((rv=dbp->del(dbp, dbtxnp, &key, 0)) != 0 && rv != DB_NOTFOUND) { |
535 |
if ((rv = mdb_del(txn, dbi, &key, 0)) != 0 && rv != MDB_NOTFOUND) { |
| 506 |
signals_unblock(); |
536 |
signals_unblock(); |
| 507 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
537 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 508 |
"removing from database failed: %s", dn); |
538 |
"removing from database failed: %s", dn); |
| 509 |
dbp->err(dbp, rv, "del"); |
539 |
cache_error_message(rv, "mdb_del"); |
|
|
540 |
mdb_txn_abort(txn); |
| 541 |
return rv; |
| 510 |
} |
542 |
} |
| 511 |
|
543 |
|
| 512 |
#ifdef WITH_DB42 |
544 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_delete_entry)"); |
| 513 |
dbtxnp->commit(dbtxnp, 0); |
545 |
if ((rv = mdb_txn_commit(txn)) != 0) { |
| 514 |
#endif |
546 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 515 |
cache_sync(); |
547 |
"storing entry removal from database failed"); |
|
|
548 |
cache_error_message(rv, "mdb_txn_commit"); |
| 549 |
return rv; |
| 550 |
} |
| 516 |
signals_unblock(); |
551 |
signals_unblock(); |
| 517 |
|
552 |
|
| 518 |
return rv; |
553 |
return rv; |
|
Lines 551-593
Link Here
|
| 551 |
|
586 |
|
| 552 |
int cache_get_entry(char *dn, CacheEntry *entry) |
587 |
int cache_get_entry(char *dn, CacheEntry *entry) |
| 553 |
{ |
588 |
{ |
| 554 |
DBT key, data; |
589 |
MDB_txn *txn; |
|
|
590 |
MDB_val key, data; |
| 555 |
int rv = 0; |
591 |
int rv = 0; |
| 556 |
|
592 |
|
| 557 |
memset(&key, 0, sizeof(DBT)); |
593 |
memset(&key, 0, sizeof(MDB_val)); |
| 558 |
memset(&data, 0, sizeof(DBT)); |
594 |
memset(&data, 0, sizeof(MDB_val)); |
| 559 |
memset(entry, 0, sizeof(CacheEntry)); |
595 |
memset(entry, 0, sizeof(CacheEntry)); |
| 560 |
|
596 |
|
| 561 |
key.data=dn; |
597 |
key.mv_data=dn; |
| 562 |
key.size=strlen(dn)+1; |
598 |
key.mv_size=strlen(dn)+1; |
| 563 |
data.flags = DB_DBT_REALLOC; |
|
|
| 564 |
|
599 |
|
|
|
600 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_get_entry)"); |
| 601 |
if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) { |
| 602 |
cache_error_message(rv, "mdb_txn_begin"); |
| 603 |
return rv; |
| 604 |
} |
| 565 |
signals_block(); |
605 |
signals_block(); |
| 566 |
rv=dbp->get(dbp, NULL, &key, &data, 0); |
606 |
rv = mdb_get(txn, dbi, &key, &data); |
| 567 |
signals_unblock(); |
607 |
signals_unblock(); |
|
|
608 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_get_entry)"); |
| 609 |
mdb_txn_abort(txn); |
| 568 |
|
610 |
|
| 569 |
if (rv != 0 && rv != DB_NOTFOUND) { |
611 |
if (rv != 0 && rv != MDB_NOTFOUND) { |
| 570 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
612 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 571 |
"reading %s from database failed", dn); |
613 |
"reading %s from database failed", dn); |
| 572 |
dbp->err(dbp, rv, "get"); |
614 |
cache_error_message(rv, "mdb_get"); |
| 573 |
return rv; |
615 |
return rv; |
| 574 |
} else if (rv == DB_NOTFOUND) { |
616 |
} else if (rv == MDB_NOTFOUND) { |
| 575 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "no cache entry found for %s", |
617 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "no cache entry found for %s", |
| 576 |
dn); |
618 |
dn); |
| 577 |
return rv; |
619 |
return rv; |
| 578 |
} |
620 |
} |
| 579 |
|
621 |
|
| 580 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %d bytes for %s", |
622 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %zu bytes for %s", |
| 581 |
data.size, dn); |
623 |
data.mv_size, dn); |
| 582 |
|
624 |
|
| 583 |
if ((rv=parse_entry(data.data, data.size, entry)) != 0) { |
625 |
if ((rv=parse_entry(data.mv_data, data.mv_size, entry)) != 0) { |
| 584 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
626 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 585 |
"parsing entry failed"); |
627 |
"parsing entry failed"); |
| 586 |
free(data.data); |
|
|
| 587 |
exit(1); |
628 |
exit(1); |
| 588 |
} |
629 |
} |
| 589 |
|
630 |
|
| 590 |
free(data.data); |
|
|
| 591 |
return rv; |
631 |
return rv; |
| 592 |
} |
632 |
} |
| 593 |
|
633 |
|
|
Lines 604-610
Link Here
|
| 604 |
} |
644 |
} |
| 605 |
|
645 |
|
| 606 |
rv = cache_get_entry(lower_dn, entry); |
646 |
rv = cache_get_entry(lower_dn, entry); |
| 607 |
if (rv == DB_NOTFOUND && mixedcase ) { |
647 |
if (rv == MDB_NOTFOUND && mixedcase ) { |
| 608 |
// try again with original dn |
648 |
// try again with original dn |
| 609 |
rv = cache_get_entry(dn, entry); |
649 |
rv = cache_get_entry(dn, entry); |
| 610 |
} |
650 |
} |
|
Lines 613-720
Link Here
|
| 613 |
return rv; |
653 |
return rv; |
| 614 |
} |
654 |
} |
| 615 |
|
655 |
|
| 616 |
int cache_first_entry(DBC **cur, char **dn, CacheEntry *entry) |
656 |
int cache_first_entry(MDB_cursor **cursor, char **dn, CacheEntry *entry) |
| 617 |
{ |
657 |
{ |
|
|
658 |
MDB_txn *txn; |
| 618 |
int rv; |
659 |
int rv; |
| 619 |
|
660 |
|
| 620 |
if ((rv=dbp->cursor(dbp, NULL, cur, 0)) != 0) { |
661 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_first_entry)"); |
| 621 |
dbp->err(dbp, rv, "cursor"); |
662 |
if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) { |
|
|
663 |
cache_error_message(rv, "mdb_txn_begin"); |
| 622 |
return rv; |
664 |
return rv; |
| 623 |
} |
665 |
} |
|
|
666 |
if ((rv = mdb_cursor_open(txn, dbi, cursor)) != 0) { |
| 667 |
cache_error_message(rv, "mdb_cursor_open"); |
| 668 |
mdb_txn_abort(txn); |
| 669 |
return rv; |
| 670 |
} |
| 624 |
|
671 |
|
| 625 |
return cache_next_entry(cur, dn, entry); |
672 |
/* |
|
|
673 |
// mdb_reader_list(env, &mdb_message_func, NULL); |
| 674 |
MDB_envinfo stat; |
| 675 |
MDB_env *env = mdb_txn_env(txn); |
| 676 |
mdb_env_info(env, &stat); |
| 677 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "LAST COMMITTED TXN: %zu", stat.me_last_txnid); |
| 678 |
*/ |
| 679 |
|
| 680 |
return cache_next_entry(cursor, dn, entry); |
| 626 |
} |
681 |
} |
| 627 |
|
682 |
|
| 628 |
int cache_print_entries(char *dn) |
683 |
int cache_print_entries(char *dn) |
| 629 |
{ |
684 |
{ |
| 630 |
DBT key, data; |
685 |
MDB_txn *txn; |
| 631 |
DBC *cur; |
686 |
MDB_val key, data; |
| 632 |
memset(&key, 0, sizeof(DBT)); |
687 |
MDB_cursor *cursor; |
| 633 |
memset(&data, 0, sizeof(DBT)); |
688 |
int rv = 0; |
| 634 |
key.data = strdup(dn); |
|
|
| 635 |
key.size = strlen(dn)+1; |
| 636 |
key.flags = DB_DBT_REALLOC; |
| 637 |
data.flags = DB_DBT_REALLOC; |
| 638 |
|
689 |
|
| 639 |
dbp->cursor(dbp, NULL, &cur, 0); |
690 |
memset(&key, 0, sizeof(MDB_val)); |
| 640 |
cur->c_get(cur, &key, &data, DB_FIRST); |
691 |
memset(&data, 0, sizeof(MDB_val)); |
|
|
692 |
key.mv_data = strdup(dn); |
| 693 |
key.mv_size = strlen(dn)+1; |
| 694 |
|
| 695 |
if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) { |
| 696 |
cache_error_message(rv, "mdb_txn_begin"); |
| 697 |
return rv; |
| 698 |
} |
| 699 |
if ((rv = mdb_cursor_open(txn, dbi, &cursor)) != 0) { |
| 700 |
cache_error_message(rv, "mdb_cursor_open"); |
| 701 |
mdb_txn_abort(txn); |
| 702 |
return rv; |
| 703 |
} |
| 704 |
rv = mdb_cursor_get(cursor, &key, &data, MDB_FIRST); |
| 641 |
do { |
705 |
do { |
| 642 |
printf("%s\n", (char*)key.data); |
706 |
if (rv != 0) { |
| 643 |
} while (cur->c_get(cur, &key, &data, DB_NEXT) == 0); |
707 |
cache_error_message(rv, "mdb_cursor_get"); |
|
|
708 |
mdb_txn_abort(txn); |
| 709 |
return rv; |
| 710 |
} |
| 711 |
printf("%s\n", (char*)key.mv_data); |
| 712 |
} while ((rv = mdb_cursor_get(cursor, &key, &data, MDB_NEXT))); |
| 644 |
|
713 |
|
| 645 |
cur->c_close(cur); |
714 |
mdb_cursor_close(cursor); |
| 646 |
free(key.data); |
715 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_print_entries)"); |
| 647 |
free(data.data); |
716 |
mdb_txn_abort(txn); |
| 648 |
return 0; |
717 |
return 0; |
| 649 |
} |
718 |
} |
| 650 |
|
719 |
|
| 651 |
int cache_next_entry(DBC **cur, char **dn, CacheEntry *entry) |
720 |
int cache_next_entry(MDB_cursor **cursor, char **dn, CacheEntry *entry) |
| 652 |
{ |
721 |
{ |
| 653 |
DBT key, data; |
722 |
MDB_val key, data; |
| 654 |
int rv; |
723 |
int rv; |
| 655 |
|
724 |
|
| 656 |
memset(&key, 0, sizeof(DBT)); |
725 |
memset(&key, 0, sizeof(MDB_val)); |
| 657 |
key.flags = DB_DBT_REALLOC; |
726 |
memset(&data, 0, sizeof(MDB_val)); |
| 658 |
memset(&data, 0, sizeof(DBT)); |
|
|
| 659 |
data.flags = DB_DBT_REALLOC; |
| 660 |
|
727 |
|
| 661 |
if ((rv=(*cur)->c_get(*cur, &key, &data, DB_NEXT)) == DB_NOTFOUND) { |
728 |
if ((rv=mdb_cursor_get(*cursor, &key, &data, MDB_NEXT)) == MDB_NOTFOUND) { |
| 662 |
return rv; |
729 |
return rv; |
| 663 |
} else if (rv != 0) { |
730 |
} else if (rv != 0) { |
| 664 |
dbp->err(dbp, rv, "c_get"); |
731 |
cache_error_message(rv, "mdb_cursor_get"); |
| 665 |
return rv; |
732 |
return rv; |
| 666 |
} |
733 |
} |
| 667 |
|
734 |
|
| 668 |
/* skip master entry */ |
735 |
/* skip master entry */ |
| 669 |
if (strcmp(key.data, MASTER_KEY) == 0) { |
736 |
if (strcmp(key.mv_data, MASTER_KEY) == 0) { |
| 670 |
free(key.data); |
737 |
return cache_next_entry(cursor, dn, entry); |
| 671 |
free(data.data); |
|
|
| 672 |
return cache_next_entry(cur, dn, entry); |
| 673 |
} |
738 |
} |
| 674 |
|
739 |
|
| 675 |
if (*dn) |
740 |
if (*dn) |
| 676 |
free(*dn); |
741 |
free(*dn); |
| 677 |
*dn = strdup(key.data); |
742 |
*dn = strdup(key.mv_data); |
| 678 |
|
743 |
|
| 679 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %d bytes", data.size); |
744 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %zu bytes", data.mv_size); |
| 680 |
|
745 |
|
| 681 |
if ((rv=parse_entry(data.data, data.size, entry)) != 0) { |
746 |
if ((rv=parse_entry(data.mv_data, data.mv_size, entry)) != 0) { |
| 682 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
747 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 683 |
"parsing entry failed: %s", *dn); |
748 |
"parsing entry failed: %s", *dn); |
| 684 |
printf("%d\n", data.size); |
749 |
printf("%zu\n", data.mv_size); |
| 685 |
free(key.data); |
|
|
| 686 |
free(data.data); |
| 687 |
return rv; |
750 |
return rv; |
| 688 |
} |
751 |
} |
| 689 |
|
752 |
|
| 690 |
free(key.data); |
|
|
| 691 |
free(data.data); |
| 692 |
|
| 693 |
return 0; |
753 |
return 0; |
| 694 |
} |
754 |
} |
| 695 |
|
755 |
|
| 696 |
int cache_free_cursor(DBC *cur) |
756 |
int cache_free_cursor(MDB_cursor *cursor) |
| 697 |
{ |
757 |
{ |
| 698 |
return cur->c_close(cur); |
758 |
int rv; |
|
|
759 |
MDB_txn *txn; |
| 760 |
|
| 761 |
/* |
| 762 |
// mdb_reader_list(env, &mdb_message_func, NULL); |
| 763 |
MDB_envinfo stat; |
| 764 |
MDB_env *env = mdb_txn_env(txn); |
| 765 |
mdb_env_info(env, &stat); |
| 766 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "LAST COMMITTED TXN: %zu", stat.me_last_txnid); |
| 767 |
*/ |
| 768 |
|
| 769 |
mdb_cursor_close(cursor); |
| 770 |
|
| 771 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_free_cursor)"); |
| 772 |
if ((rv = mdb_txn_commit(txn)) != 0) { |
| 773 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 774 |
"Transation commit failed"); |
| 775 |
cache_error_message(rv, "mdb_txn_commit"); |
| 776 |
} |
| 777 |
return rv; |
| 699 |
} |
778 |
} |
| 700 |
|
779 |
|
| 701 |
int cache_close(void) |
780 |
void cache_close(void) |
| 702 |
{ |
781 |
{ |
| 703 |
int rv; |
782 |
mdb_close(env, dbi); |
|
|
783 |
mdb_env_close(env); |
| 704 |
|
784 |
|
| 705 |
if (dbp && (rv = dbp->close(dbp, 0)) != 0) { |
|
|
| 706 |
dbp->err(dbp, rv, "close"); |
| 707 |
} |
| 708 |
dbp = NULL; |
| 709 |
#ifdef WITH_DB42 |
| 710 |
if ((rv = dbenvp->close(dbenvp, 0)) != 0) { |
| 711 |
univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, |
| 712 |
"closing database environment failed"); |
| 713 |
} |
| 714 |
#endif |
| 715 |
if (lock_fp != NULL) { |
785 |
if (lock_fp != NULL) { |
| 716 |
fclose(lock_fp); |
786 |
fclose(lock_fp); |
| 717 |
lock_fp = NULL; |
787 |
lock_fp = NULL; |
| 718 |
} |
788 |
} |
| 719 |
return rv; |
|
|
| 720 |
} |
789 |
} |