Index: debian/control =================================================================== --- debian/control (Revision 71546) +++ debian/control (Arbeitskopie) @@ -7,7 +7,7 @@ ucslint-univention, libssl-dev, libldap2-dev, - libdb3-dev, + liblmdb-dev, python-all-dev, libunivention-debug-dev (>= 0.8), libunivention-config-dev, @@ -26,7 +26,8 @@ univention-runit, python2.7-univention, python2.7-univention-debug, - python-univention-lib (>= 1.0.25-1) + python-univention-lib (>= 1.0.25-1), + lmdb-utils Conflicts: univention-ldap-listener (<< 2.2.2) Description: UCS - Directory Listener UCS Directory Listener is a client for the UCS Index: debian/rules =================================================================== --- debian/rules (Revision 71546) +++ debian/rules (Arbeitskopie) @@ -37,7 +37,7 @@ override_dh_auto_build: $(MAKE) -C src clean - $(MAKE) -C src DB_CFLAGS="-I/usr/include/db3 -DWITH_DB3" DB_LDADD="-ldb3" + $(MAKE) -C src DB_LDADD="-llmdb" dh_auto_build override_dh_auto_install: Index: debian/univention-directory-listener.postinst =================================================================== --- debian/univention-directory-listener.postinst (Revision 71546) +++ debian/univention-directory-listener.postinst (Arbeitskopie) @@ -45,6 +45,14 @@ chown listener /var/lib/univention-ldap/listener/listener* fi +if [ ! -e /var/lib/univention-directory-listener/cache ]; then + mkdir /var/lib/univention-directory-listener/cache + if [ -f /var/lib/univention-directory-listener/cache.db ]; then + db_dump /var/lib/univention-directory-listener/cache.db | \ + mdb_load /var/lib/univention-directory-listener/cache + fi +fi + #DEBHELPER# univention-config-registry set listener/debug/level?2 \ Index: src/Makefile =================================================================== --- src/Makefile (Revision 71546) +++ src/Makefile (Arbeitskopie) @@ -30,11 +30,10 @@ # . # CC=gcc -DB_LDADD=-ldb3 -DB_CFLAGS=-I/usr/include/db3 -DWITH_DB3 +DB_LDADD=-llmdb DB_OBJS=cache.o cache_entry.o cache_lowlevel.o base64.o filter.o -CFLAGS=-g -Wall -Werror -D_FILE_OFFSET_BITS=64 $(DB_CFLAGS) +CFLAGS=-g -Wall -Werror -D_FILE_OFFSET_BITS=64 LDADD=-g -luniventiondebug -licuuc LISTENER_LDADD=$(LDADD) -luniventionpolicy -lldap -lpython2.7 $(DB_LDADD) LISTENER_OBJS=main.o notifier.o transfile.o handlers.o change.o network.o signals.o select_server.o utils.o $(DB_OBJS) @@ -62,4 +61,4 @@ .PHONY: clean clean: - $(RM) *.o listener dump demo verify *.db3 *.db42 + $(RM) *.o listener dump demo verify Index: src/cache.c =================================================================== --- src/cache.c (Revision 71546) +++ src/cache.c (Arbeitskopie) @@ -67,7 +67,7 @@ #include #include #include -#include +#include #include #include @@ -91,10 +91,8 @@ CacheMasterEntry cache_master_entry; -DB *dbp; -#ifdef WITH_DB42 -DB_ENV *dbenvp; -#endif +MDB_env *env; +MDB_dbi dbi; static FILE *lock_fp=NULL; static struct filter cache_filter; @@ -110,17 +108,17 @@ } } -#ifdef WITH_DB42 -static void cache_panic_call(DB_ENV *dbenvp, int errval) +static void cache_error_message(int rv, char *msg) { - exit(1); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, + "database error: %s: %s (%d)\n", + msg, mdb_strerror(rv), rv); } -#endif -static void cache_error_message(const char *errpfx, char *msg) -{ - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, - "database error: %s", msg); +int mdb_message_func(const char *msg, void *ctx) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, + "%s\n", msg); + return 0; } int cache_lock(void) @@ -130,7 +128,7 @@ assert(!lock_fp); - rv = snprintf(lock_file, PATH_MAX, "%s/cache.db.lock", cache_dir); + rv = snprintf(lock_file, PATH_MAX, "%s/cache.lock", cache_dir); if (rv < 0 || rv >= PATH_MAX) abort(); @@ -155,65 +153,53 @@ int cache_init(void) { int rv; - char file[PATH_MAX]; + char mdb_dir[PATH_MAX]; + MDB_txn *txn; - snprintf(file, PATH_MAX, "%s/cache.db", cache_dir); + snprintf(mdb_dir, PATH_MAX, "%s/cache", cache_dir); -#ifdef WITH_DB42 - if ((rv = db_env_create(&dbenvp, 0)) != 0) { + if ((rv = mdb_env_create(&env)) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, - "creating database environment failed"); + "creating environment handle failed"); + cache_error_message(rv, "mdb_env_create"); return rv; } - dbenvp->set_errcall(dbenvp, cache_error_message); - dbenvp->set_paniccall(dbenvp, cache_panic_call); - if ((rv = dbenvp->open(dbenvp, cache_dir, DB_CREATE | DB_INIT_MPOOL | - /*DB_INIT_LOCK | */DB_INIT_LOG | DB_INIT_TXN | - DB_RECOVER, 0600)) != 0) { + if ((rv = mdb_env_set_mapsize(env, 1992294400)) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, - "opening database environment failed"); - dbenvp->err(dbenvp, rv, "%s", "environment"); + "setting mdb mapsize failed"); + cache_error_message(rv, "mdb_env_set_mapsize"); return rv; } - if ((rv = db_create(&dbp, dbenvp, 0)) != 0) { + if ((rv = mdb_env_open(env, mdb_dir, MDB_NORDAHEAD, 0600)) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, - "creating database handle failed"); + "opening database failed"); + cache_error_message(rv, "mdb_env_open"); return rv; } - if ((rv = dbp->open(dbp, NULL, "cache.db", NULL, DB_BTREE, - DB_CREATE | DB_CHKSUM | DB_AUTO_COMMIT, - 0600)) != 0) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, - "opening database failed"); - dbp->err(dbp, rv, "open"); - // FIXME: free dbp + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_init)"); + if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) { + cache_error_message(rv, "mdb_txn_begin"); + mdb_env_close(env); return rv; } -#else - if ((rv = db_create(&dbp, NULL, 0)) != 0) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, - "creating database handle failed"); + if ((rv = mdb_open(txn, NULL, 0, &dbi)) != 0) { + cache_error_message(rv, "mdb_open"); + mdb_txn_abort(txn); + mdb_env_close(env); return rv; } - if ((rv = dbp->open(dbp, file, NULL, DB_BTREE, DB_CREATE, 0600)) != 0) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, - "opening database failed"); - dbp->err(dbp, rv, "open"); - // FIXME: free dbp + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_init)"); + if ((rv = mdb_txn_commit(txn)) != 0) { + cache_error_message(rv, "mdb_txn_commit"); + mdb_dbi_close(env, dbi); + mdb_env_close(env); return rv; } - dbp->set_errcall(dbp, cache_error_message); -#endif + setup_cache_filter(); return 0; } -void cache_sync(void) { - if (!INIT_ONLY && dbp) { - dbp->sync(dbp, 0); - } -} - int cache_set_schema_id(const NotifierID value) { int rv, fd, len; @@ -297,83 +283,119 @@ int cache_get_master_entry(CacheMasterEntry *master_entry) { - DBT key, data; + MDB_txn *txn; + MDB_cursor *cursor; + MDB_val key, data; int rv; - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); + memset(&key, 0, sizeof(MDB_val)); + memset(&data, 0, sizeof(MDB_val)); - key.data=MASTER_KEY; - key.size=MASTER_KEY_SIZE; - data.flags = DB_DBT_REALLOC; + key.mv_data=MASTER_KEY; + key.mv_size=MASTER_KEY_SIZE; - if ((rv=dbp->get(dbp, NULL, &key, &data, 0)) == DB_NOTFOUND) + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_get_master_entry)"); + if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) { + cache_error_message(rv, "mdb_txn_begin"); return rv; + } + if ((rv = mdb_cursor_open(txn, dbi, &cursor)) != 0) { + cache_error_message(rv, "mdb_cursor_open"); + mdb_txn_abort(txn); + return rv; + } + if ((rv = mdb_cursor_get(cursor, &key, &data, MDB_SET_KEY)) == MDB_NOTFOUND) { + mdb_cursor_close(cursor); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_get_master_entry)"); + mdb_txn_abort(txn); + return rv; + } else if (rv != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "reading master entry from database failed"); - dbp->err(dbp, rv, "get"); + cache_error_message(rv, "mdb_get"); + mdb_cursor_close(cursor); + mdb_txn_abort(txn); return rv; } + mdb_cursor_close(cursor); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_get_master_entry)"); + mdb_txn_abort(txn); - if (data.size != sizeof(CacheMasterEntry)) { + if (data.mv_size != sizeof(CacheMasterEntry)) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "master entry has unexpected length"); return 1; } - memcpy(master_entry, data.data, sizeof(CacheMasterEntry)); - free(data.data); + memcpy(master_entry, data.mv_data, sizeof(CacheMasterEntry)); return 0; } -int cache_update_master_entry(CacheMasterEntry *master_entry, DB_TXN *dbtxnp) +/* The dbtxnp argument is only used when WITH_DB42 is defined - useless? */ +int cache_update_master_entry(CacheMasterEntry *master_entry, MDB_txn *dbtxnp) { - DBT key, data; + MDB_txn *txn = dbtxnp; + MDB_val key, data; int rv; int flags; - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); + memset(&key, 0, sizeof(MDB_val)); + memset(&data, 0, sizeof(MDB_val)); - key.data=MASTER_KEY; - key.size=MASTER_KEY_SIZE; + key.mv_data=MASTER_KEY; + key.mv_size=MASTER_KEY_SIZE; - data.data=(void*)master_entry; - data.size=sizeof(CacheMasterEntry); + data.mv_data=(void*)master_entry; + data.mv_size=sizeof(CacheMasterEntry); -#ifdef WITH_DB42 - if (dbtxnp == NULL) - flags = DB_AUTO_COMMIT; - else -#endif - flags = 0; + flags = 0; - if ((rv=dbp->put(dbp, dbtxnp, &key, &data, flags)) != 0) { + if (!dbtxnp) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_update_master_entry)"); + } + if (!dbtxnp && (rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) { + cache_error_message(rv, "mdb_txn_begin"); + return rv; + } + if ((rv = mdb_put(txn, dbi, &key, &data, flags)) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "storing master entry in database failed"); - dbp->err(dbp, rv, "put"); + cache_error_message(rv, "mdb_put"); + mdb_txn_abort(txn); return rv; } + if (!dbtxnp) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_update_master_entry)"); + } + if (!dbtxnp && (rv = mdb_txn_commit(txn)) != 0) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, + "storing master entry in database failed"); + cache_error_message(rv, "mdb_txn_commit"); + return rv; + } - cache_sync(); - return 0; } -DB_TXN* cache_new_transaction(NotifierID id, char *dn) +MDB_txn *cache_new_transaction(NotifierID id, char *dn) { #ifdef WITH_DB42 - DB_TXN *dbtxnp; + int rv; + MDB_txn *txn; CacheMasterEntry master_entry; NotifierID *old_id; - dbenvp->txn_begin(dbenvp, NULL, &dbtxnp, 0); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_new_transaction)"); + if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) { + cache_error_message(rv, "mdb_txn_begin"); + return NULL; + } if (id != 0) { if (cache_get_master_entry(&master_entry) != 0) { - dbtxnp->abort(dbtxnp); + mdb_txn_abort(txn); return NULL; } @@ -386,18 +408,18 @@ univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "New ID (%ld) is not greater than old" " ID (%ld): %s", id, *old_id, dn); - dbtxnp->abort(dbtxnp); + mdb_txn_abort(txn); return NULL; } else *old_id = id; - if (cache_update_master_entry(&master_entry, dbtxnp) != 0) { - dbtxnp->abort(dbtxnp); + if (cache_update_master_entry(&master_entry, txn) != 0) { + mdb_txn_abort(txn); return NULL; } } - return dbtxnp; + return txn; #else return NULL; #endif @@ -410,14 +432,14 @@ cache_delete_entry do nothing (at least if WITH_DB42 is undefined) */ inline int cache_update_entry(NotifierID id, char *dn, CacheEntry *entry) { - DBT key, data; - DB_TXN *dbtxnp; + MDB_txn *txn; + MDB_val key, data; int rv = 0; - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); + memset(&key, 0, sizeof(MDB_val)); + memset(&data, 0, sizeof(MDB_val)); - if ((rv=unparse_entry(&data.data, &data.size, entry)) != 0) { + if ((rv=unparse_entry(&data.mv_data, &data.mv_size, entry)) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "unparsing entry failed"); return rv; @@ -426,40 +448,44 @@ signals_block(); #ifdef WITH_DB42 - dbtxnp = cache_new_transaction(id, dn); - if (dbtxnp == NULL) { + txn = cache_new_transaction(id, dn); + if (txn == NULL) { signals_unblock(); - free(data.data); return 1; } #else - dbtxnp = NULL; + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_update_entry)"); + if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) { + cache_error_message(rv, "mdb_txn_begin"); + signals_unblock(); + return rv; + } #endif - key.data=dn; - key.size=strlen(dn)+1; + key.mv_data=dn; + key.mv_size=strlen(dn)+1; - if ((rv=dbp->put(dbp, dbtxnp, &key, &data, 0)) != 0) { + if ((rv = mdb_put(txn, dbi, &key, &data, 0)) != 0) { signals_unblock(); univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "storing entry in database failed: %s", dn); - dbp->err(dbp, rv, "put"); -#ifdef WITH_DB42 - dbtxnp->abort(dbtxnp); -#endif - free(data.data); + cache_error_message(rv, "mdb_put"); + mdb_txn_abort(txn); return rv; } - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %d bytes for %s", data.size, dn); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "put %zu bytes for %s", data.mv_size, dn); -#ifdef WITH_DB42 - dbtxnp->commit(dbtxnp, 0); -#endif - cache_sync(); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_update_entry)"); + if ((rv = mdb_txn_commit(txn)) != 0) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, + "storing updated entry in database failed"); + cache_error_message(rv, "mdb_txn_commit"); + return rv; + } + signals_unblock(); - free(data.data); return rv; } @@ -482,37 +508,46 @@ int cache_delete_entry(NotifierID id, char *dn) { - DB_TXN *dbtxnp; - DBT key; + MDB_txn *txn; + MDB_val key; int rv; - memset(&key, 0, sizeof(DBT)); + memset(&key, 0, sizeof(MDB_val)); - key.data=dn; - key.size=strlen(dn)+1; + key.mv_data=dn; + key.mv_size=strlen(dn)+1; signals_block(); #ifdef WITH_DB42 - dbtxnp = cache_new_transaction(id, dn); - if (dbtxnp == NULL) { + txn = cache_new_transaction(id, dn); + if (txn == NULL) { signals_unblock(); return 1; } #else - dbtxnp = NULL; + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_delete_entry)"); + if ((rv = mdb_txn_begin(env, NULL, 0, &txn)) != 0) { + cache_error_message(rv, "mdb_txn_begin"); + return rv; + } #endif - if ((rv=dbp->del(dbp, dbtxnp, &key, 0)) != 0 && rv != DB_NOTFOUND) { + if ((rv = mdb_del(txn, dbi, &key, 0)) != 0 && rv != MDB_NOTFOUND) { signals_unblock(); univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "removing from database failed: %s", dn); - dbp->err(dbp, rv, "del"); + cache_error_message(rv, "mdb_del"); + mdb_txn_abort(txn); + return rv; } -#ifdef WITH_DB42 - dbtxnp->commit(dbtxnp, 0); -#endif - cache_sync(); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_delete_entry)"); + if ((rv = mdb_txn_commit(txn)) != 0) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, + "storing entry removal from database failed"); + cache_error_message(rv, "mdb_txn_commit"); + return rv; + } signals_unblock(); return rv; @@ -551,43 +586,48 @@ int cache_get_entry(char *dn, CacheEntry *entry) { - DBT key, data; + MDB_txn *txn; + MDB_val key, data; int rv = 0; - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); + memset(&key, 0, sizeof(MDB_val)); + memset(&data, 0, sizeof(MDB_val)); memset(entry, 0, sizeof(CacheEntry)); - key.data=dn; - key.size=strlen(dn)+1; - data.flags = DB_DBT_REALLOC; + key.mv_data=dn; + key.mv_size=strlen(dn)+1; + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_get_entry)"); + if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) { + cache_error_message(rv, "mdb_txn_begin"); + return rv; + } signals_block(); - rv=dbp->get(dbp, NULL, &key, &data, 0); + rv = mdb_get(txn, dbi, &key, &data); signals_unblock(); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_get_entry)"); + mdb_txn_abort(txn); - if (rv != 0 && rv != DB_NOTFOUND) { + if (rv != 0 && rv != MDB_NOTFOUND) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "reading %s from database failed", dn); - dbp->err(dbp, rv, "get"); + cache_error_message(rv, "mdb_get"); return rv; - } else if (rv == DB_NOTFOUND) { + } else if (rv == MDB_NOTFOUND) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "no cache entry found for %s", dn); return rv; } - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %d bytes for %s", - data.size, dn); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %zu bytes for %s", + data.mv_size, dn); - if ((rv=parse_entry(data.data, data.size, entry)) != 0) { + if ((rv=parse_entry(data.mv_data, data.mv_size, entry)) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "parsing entry failed"); - free(data.data); exit(1); } - free(data.data); return rv; } @@ -604,7 +644,7 @@ } rv = cache_get_entry(lower_dn, entry); - if (rv == DB_NOTFOUND && mixedcase ) { + if (rv == MDB_NOTFOUND && mixedcase ) { // try again with original dn rv = cache_get_entry(dn, entry); } @@ -613,108 +653,137 @@ return rv; } -int cache_first_entry(DBC **cur, char **dn, CacheEntry *entry) +int cache_first_entry(MDB_cursor **cursor, char **dn, CacheEntry *entry) { + MDB_txn *txn; int rv; - if ((rv=dbp->cursor(dbp, NULL, cur, 0)) != 0) { - dbp->err(dbp, rv, "cursor"); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction begin (cache_first_entry)"); + if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) { + cache_error_message(rv, "mdb_txn_begin"); return rv; } + if ((rv = mdb_cursor_open(txn, dbi, cursor)) != 0) { + cache_error_message(rv, "mdb_cursor_open"); + mdb_txn_abort(txn); + return rv; + } - return cache_next_entry(cur, dn, entry); + /* + // mdb_reader_list(env, &mdb_message_func, NULL); + MDB_envinfo stat; + MDB_env *env = mdb_txn_env(txn); + mdb_env_info(env, &stat); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "LAST COMMITTED TXN: %zu", stat.me_last_txnid); + */ + + return cache_next_entry(cursor, dn, entry); } int cache_print_entries(char *dn) { - DBT key, data; - DBC *cur; - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - key.data = strdup(dn); - key.size = strlen(dn)+1; - key.flags = DB_DBT_REALLOC; - data.flags = DB_DBT_REALLOC; + MDB_txn *txn; + MDB_val key, data; + MDB_cursor *cursor; + int rv = 0; - dbp->cursor(dbp, NULL, &cur, 0); - cur->c_get(cur, &key, &data, DB_FIRST); + memset(&key, 0, sizeof(MDB_val)); + memset(&data, 0, sizeof(MDB_val)); + key.mv_data = strdup(dn); + key.mv_size = strlen(dn)+1; + + if ((rv = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)) != 0) { + cache_error_message(rv, "mdb_txn_begin"); + return rv; + } + if ((rv = mdb_cursor_open(txn, dbi, &cursor)) != 0) { + cache_error_message(rv, "mdb_cursor_open"); + mdb_txn_abort(txn); + return rv; + } + rv = mdb_cursor_get(cursor, &key, &data, MDB_FIRST); do { - printf("%s\n", (char*)key.data); - } while (cur->c_get(cur, &key, &data, DB_NEXT) == 0); + if (rv != 0) { + cache_error_message(rv, "mdb_cursor_get"); + mdb_txn_abort(txn); + return rv; + } + printf("%s\n", (char*)key.mv_data); + } while ((rv = mdb_cursor_get(cursor, &key, &data, MDB_NEXT))); - cur->c_close(cur); - free(key.data); - free(data.data); + mdb_cursor_close(cursor); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction abort (cache_print_entries)"); + mdb_txn_abort(txn); return 0; } -int cache_next_entry(DBC **cur, char **dn, CacheEntry *entry) +int cache_next_entry(MDB_cursor **cursor, char **dn, CacheEntry *entry) { - DBT key, data; + MDB_val key, data; int rv; - memset(&key, 0, sizeof(DBT)); - key.flags = DB_DBT_REALLOC; - memset(&data, 0, sizeof(DBT)); - data.flags = DB_DBT_REALLOC; + memset(&key, 0, sizeof(MDB_val)); + memset(&data, 0, sizeof(MDB_val)); - if ((rv=(*cur)->c_get(*cur, &key, &data, DB_NEXT)) == DB_NOTFOUND) { + if ((rv=mdb_cursor_get(*cursor, &key, &data, MDB_NEXT)) == MDB_NOTFOUND) { return rv; } else if (rv != 0) { - dbp->err(dbp, rv, "c_get"); + cache_error_message(rv, "mdb_cursor_get"); return rv; } /* skip master entry */ - if (strcmp(key.data, MASTER_KEY) == 0) { - free(key.data); - free(data.data); - return cache_next_entry(cur, dn, entry); + if (strcmp(key.mv_data, MASTER_KEY) == 0) { + return cache_next_entry(cursor, dn, entry); } if (*dn) free(*dn); - *dn = strdup(key.data); + *dn = strdup(key.mv_data); - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %d bytes", data.size); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "got %zu bytes", data.mv_size); - if ((rv=parse_entry(data.data, data.size, entry)) != 0) { + if ((rv=parse_entry(data.mv_data, data.mv_size, entry)) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "parsing entry failed: %s", *dn); - printf("%d\n", data.size); - free(key.data); - free(data.data); + printf("%zu\n", data.mv_size); return rv; } - free(key.data); - free(data.data); - return 0; } -int cache_free_cursor(DBC *cur) +int cache_free_cursor(MDB_cursor *cursor) { - return cur->c_close(cur); + int rv; + MDB_txn *txn; + + /* + // mdb_reader_list(env, &mdb_message_func, NULL); + MDB_envinfo stat; + MDB_env *env = mdb_txn_env(txn); + mdb_env_info(env, &stat); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "LAST COMMITTED TXN: %zu", stat.me_last_txnid); + */ + + mdb_cursor_close(cursor); + + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "Transaction commit (cache_free_cursor)"); + if ((rv = mdb_txn_commit(txn)) != 0) { + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, + "Transation commit failed"); + cache_error_message(rv, "mdb_txn_commit"); + } + return rv; } -int cache_close(void) +void cache_close(void) { - int rv; + mdb_close(env, dbi); + mdb_env_close(env); - if (dbp && (rv = dbp->close(dbp, 0)) != 0) { - dbp->err(dbp, rv, "close"); - } - dbp = NULL; -#ifdef WITH_DB42 - if ((rv = dbenvp->close(dbenvp, 0)) != 0) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, - "closing database environment failed"); - } -#endif if (lock_fp != NULL) { fclose(lock_fp); lock_fp = NULL; } - return rv; } Index: src/cache.h =================================================================== --- src/cache.h (Revision 71546) +++ src/cache.h (Arbeitskopie) @@ -33,7 +33,7 @@ #ifndef _CACHE_H_ #define _CACHE_H_ -#include +#include #include "network.h" #include "cache_entry.h" @@ -53,7 +53,7 @@ void cache_sync(void); int cache_get_master_entry (CacheMasterEntry *master_entry); int cache_update_master_entry (CacheMasterEntry *master_entry, - DB_TXN *dptxnp); + MDB_txn *dptxnp); int cache_update_entry (NotifierID id, char *dn, CacheEntry *entry); @@ -73,14 +73,14 @@ int cache_get_entry_lower_upper( char *dn, CacheEntry *entry); -int cache_first_entry (DBC **cur, +int cache_first_entry (MDB_cursor **cur, char **dn, CacheEntry *entry); -int cache_next_entry (DBC **cur, +int cache_next_entry (MDB_cursor **cur, char **dn, CacheEntry *entry); -int cache_free_cursor (DBC *cur); -int cache_close (void); +int cache_free_cursor (MDB_cursor *cur); +void cache_close (void); /* deprecated with DB42*/ int cache_set_int (char *key, Index: src/cache_lowlevel.c =================================================================== --- src/cache_lowlevel.c (Revision 71546) +++ src/cache_lowlevel.c (Arbeitskopie) @@ -46,12 +46,12 @@ struct cache_entry_header { u_int16_t type; - u_int32_t key_size; - u_int32_t data_size; + size_t key_size; + size_t data_size; }; -void hex_dump(int level, void *data, u_int32_t start, u_int32_t size) +void hex_dump(int level, void *data, size_t start, size_t size) { int i; int pos; @@ -68,7 +68,7 @@ snprintf(str+pos , 80-pos , "%c", isprint(((char*)data+start)[i]) ? ((char*)data+start)[i] : '?'); pos+=1; if ((i+1) % per_line == 0) { - univention_debug(UV_DEBUG_LISTENER, level, "%s| %s (%08d)", hex, str, start+i-per_line); + univention_debug(UV_DEBUG_LISTENER, level, "%s| %s (%08zu)", hex, str, start+i-per_line); //fprintf(stderr, "%s| %s (%08d)\n", hex, str, start+i-per_line); memset(hex, 0, 80); memset(str, 0, 80); @@ -80,22 +80,22 @@ } /* assumption: enough memory as been allocated for us */ -static int append_buffer(void **data, u_int32_t *size, u_int32_t *pos, void* blob_data, u_int32_t blob_size) +static int append_buffer(void **data, size_t *size, size_t *pos, void* blob_data, size_t blob_size) { if (blob_size > 0) { memcpy((void*)(((char*)*data)+*pos), blob_data, blob_size); - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "position was=%d is=%d", *pos, *pos+blob_size); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "position was=%zu is=%zu", *pos, *pos+blob_size); *pos += blob_size; } return 0; } -static int write_header(void **data, u_int32_t *size, u_int32_t *pos, u_int16_t type, void* key_data, u_int32_t key_size, void* data_data, u_int32_t data_size) +static int write_header(void **data, size_t *size, size_t *pos, u_int16_t type, void* key_data, size_t key_size, void* data_data, size_t data_size) { struct cache_entry_header h; - u_int32_t need_memory; + size_t need_memory; - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "write_header key_size=%d data_size=%d", key_size, data_size); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "write_header key_size=%zu data_size=%zu", key_size, data_size); need_memory = sizeof(struct cache_entry_header)+key_size+data_size; if (*size < *pos+need_memory) { @@ -118,7 +118,7 @@ return 0; } -int unparse_entry(void **data, u_int32_t *size, CacheEntry *entry) +int unparse_entry(void **data, size_t *size, CacheEntry *entry) { CacheEntryAttribute **attribute; char **value; @@ -125,7 +125,7 @@ char **module; int *length; int i; - u_int32_t pos=0; + size_t pos=0; for (attribute=entry->attributes; attribute != NULL && *attribute != NULL; attribute++) { for (value=(*attribute)->values, i=0, length=(*attribute)->length; *value != NULL; value++, i++) { @@ -146,15 +146,15 @@ return 0; } -static int read_header(void *data, u_int32_t size, u_int32_t *pos, void **key_data, u_int32_t *key_size, void **data_data, u_int32_t *data_size) +static int read_header(void *data, size_t size, size_t *pos, void **key_data, size_t *key_size, void **data_data, size_t *data_size) { struct cache_entry_header *h; if (*pos == size) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "end of buffer pos=size=%d", *pos); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "end of buffer pos=size=%zu", *pos); return 0; } else if (*pos+sizeof(struct cache_entry_header) > size) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "buffer exceeded pos=%d size=%d", *pos, size); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "buffer exceeded pos=%zu size=%zu", *pos, size); return -1; } @@ -161,7 +161,7 @@ h = (struct cache_entry_header*)((char*)data+*pos); if ((h->type != 1 && h->type != 2) || h->key_size == 0) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "read_header pos=%d type=%d key_size=%d data_size=%d", *pos, h->type, h->key_size, h->data_size); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "read_header pos=%zu type=%d key_size=%zu data_size=%zu", *pos, h->type, h->key_size, h->data_size); *key_size = 0; *key_data = NULL; *data_size = 0; @@ -170,7 +170,7 @@ } *pos += sizeof(struct cache_entry_header); if (*pos+h->key_size+h->data_size > size) { - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "buffer exceeded pos=%d size=%d", *pos, size); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "buffer exceeded pos=%zu size=%zu", *pos, size); return -1; } @@ -186,17 +186,17 @@ *data_size = 0; *data_data = NULL; } - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "read_header pos=%d type=%d key_size=%d data_size=%d key_data=[%s] data_data=[%s]", *pos, h->type, h->key_size, h->data_size, (char*)*key_data, (char*)*data_data); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ALL, "read_header pos=%zu type=%d key_size=%zu data_size=%zu key_data=[%s] data_data=[%s]", *pos, h->type, h->key_size, h->data_size, (char*)*key_data, (char*)*data_data); return h->type; } -int parse_entry(void *data, u_int32_t size, CacheEntry *entry) +int parse_entry(void *data, size_t size, CacheEntry *entry) { u_int16_t type; void *key_data, *data_data; - u_int32_t key_size, data_size; - u_int32_t pos=0; + size_t key_size, data_size; + size_t pos=0; entry->attributes=NULL; entry->attribute_count=0; @@ -265,15 +265,15 @@ } else { char filename[PATH_MAX]; FILE *file; - u_int32_t len; + size_t len; int rv; - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "bad data block at position %d:", pos); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "bad data block at position %zu:", pos); len = pos < 1000 ? pos : 1000; - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "last %d bytes of previous entry:", len); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "last %zu bytes of previous entry:", len); hex_dump(UV_DEBUG_ERROR, data, pos < 1000 ? 0 : pos-1000, len); len = pos + 1000 > size ? size-pos : 1000; - univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "first %d bytes of current entry:", len); + univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "first %zu bytes of current entry:", len); hex_dump(UV_DEBUG_ERROR, data, pos, len); rv = snprintf(filename, PATH_MAX, "%s/bad_cache", cache_dir); Index: src/cache_lowlevel.h =================================================================== --- src/cache_lowlevel.h (Revision 71546) +++ src/cache_lowlevel.h (Arbeitskopie) @@ -36,11 +36,11 @@ #include "cache.h" int unparse_entry (void **data, - u_int32_t *size, + size_t *size, CacheEntry *entry); int parse_entry (void *data, - u_int32_t size, + size_t size, CacheEntry *entry); -void hex_dump(int level, void *data, u_int32_t start, u_int32_t size); +void hex_dump(int level, void *data, size_t start, size_t size); #endif /* _CACHE_LOWLEVEL_ */ Index: src/change.c =================================================================== --- src/change.c (Revision 71546) +++ src/change.c (Arbeitskopie) @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include @@ -74,7 +74,7 @@ struct filter **f; int rv; CacheEntry cache_entry, old_cache_entry; - DBC *dbc_cur; + MDB_cursor *dbc_cur = NULL; char *dn = NULL; int i; bool abort_init = false; @@ -93,7 +93,7 @@ /* remove old entries for module */ univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "remove old entries for module %s", handler->name); - for (rv=cache_first_entry(&dbc_cur, &dn, &cache_entry); rv != DB_NOTFOUND; + for (rv=cache_first_entry(&dbc_cur, &dn, &cache_entry); rv != MDB_NOTFOUND; rv=cache_next_entry(&dbc_cur, &dn, &cache_entry)) { if (rv == -1) continue; if (rv < 0) break; @@ -112,7 +112,7 @@ /* initialize schema; if it's not in cache yet (it really should be), it'll be initialized on the regular schema check after ldapsearches */ if ((rv = cache_get_entry_lower_upper("cn=Subschema", &cache_entry)) != 0 && - rv != DB_NOTFOUND) { + rv != MDB_NOTFOUND) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while reading from database"); return LDAP_OTHER; @@ -183,7 +183,7 @@ for (i=0; ild, dns[i].dn, LDAP_SCOPE_BASE, "(objectClass=*)", attrs, attrsonly0, serverctrls, clientctrls, &timeout, sizelimit0, &res2)); @@ -243,7 +243,6 @@ } } INIT_ONLY = old_init_only; - cache_sync(); return 0; } @@ -264,7 +263,7 @@ univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while converting LDAP entry to cache entry"); goto result; } - if ((rv = cache_get_entry_lower_upper(dn, &old_cache_entry)) != 0 && rv != DB_NOTFOUND) { + if ((rv = cache_get_entry_lower_upper(dn, &old_cache_entry)) != 0 && rv != MDB_NOTFOUND) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error while reading from database"); rv = LDAP_OTHER; } else { @@ -290,7 +289,7 @@ CacheEntry entry; int rv; - if ((rv = cache_get_entry_lower_upper(dn, &entry)) == DB_NOTFOUND) { + if ((rv = cache_get_entry_lower_upper(dn, &entry)) == MDB_NOTFOUND) { signals_block(); /* run handlers anyway */ if (handlers_delete(dn, &entry, command) == 0) { @@ -703,7 +702,7 @@ univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "updating '%s' command %c", trans->cur.notify.dn, trans->cur.notify.command); rv = cache_get_entry_lower_upper(trans->cur.notify.dn, &trans->cur.cache); - if (rv != 0 && rv != DB_NOTFOUND) { + if (rv != 0 && rv != MDB_NOTFOUND) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "error reading database for %s", trans->cur.notify.dn); return LDAP_OTHER; } Index: src/dump.c =================================================================== --- src/dump.c (Revision 71546) +++ src/dump.c (Arbeitskopie) @@ -67,7 +67,7 @@ char *output_file = NULL; FILE *fp; int rv; - DBC *cur; + MDB_cursor *cur = NULL; char *dn = NULL; CacheEntry entry; @@ -136,7 +136,7 @@ printf("%ld %ld\n", cache_master_entry.id, cache_master_entry.schema_id); } else { - for (rv=cache_first_entry(&cur, &dn, &entry); rv != DB_NOTFOUND; + for (rv=cache_first_entry(&cur, &dn, &entry); rv != MDB_NOTFOUND; rv=cache_next_entry(&cur, &dn, &entry)) { if ((rv == 0 && !broken_only) || (rv == -1 && broken_only)) { cache_dump_entry(dn, &entry, fp); Index: src/main.c =================================================================== --- src/main.c (Revision 71546) +++ src/main.c (Arbeitskopie) @@ -594,7 +594,7 @@ /* if no ID is set, assume the database has just been initialized */ rv = cache_get_master_entry(&cache_master_entry); - if (rv == DB_NOTFOUND) { + if (rv == MDB_NOTFOUND) { cache_get_int("notifier_id", &cache_master_entry.id, -1); if (cache_master_entry.id == -1) { rv = notifier_get_id_s(NULL, &cache_master_entry.id); Index: src/verify.c =================================================================== --- src/verify.c (Revision 71546) +++ src/verify.c (Arbeitskopie) @@ -140,7 +140,7 @@ char *bindpw = NULL; char *basedn = NULL; int rv; - DBC *cur; + MDB_cursor *cur = NULL; char *dn; CacheEntry entry; LDAP *ld; @@ -227,7 +227,7 @@ if (cache_init() != 0) exit(1); - for (rv=cache_first_entry(&cur, &dn, &entry); rv != DB_NOTFOUND; + for (rv=cache_first_entry(&cur, &dn, &entry); rv != MDB_NOTFOUND; rv=cache_next_entry(&cur, &dn, &entry)) { if (rv < -1) break; @@ -261,7 +261,7 @@ char *dn = ldap_get_dn(ld, cur); if (has_dn(dn)) continue; - if ((rv = cache_get_entry(dn, &entry)) == DB_NOTFOUND) { + if ((rv = cache_get_entry(dn, &entry)) == MDB_NOTFOUND) { printf("E: %s only in LDAP\n", dn); } else if (rv != 0) { printf("E: error reading %s from cache", dn);