Matthias Andree: > Am 11.06.2017 um 20:50 schrieb Wietse Venema: > > Philip Paeps: > >> On 2017-06-11 14:07:36 (-0400), Wietse Venema <wie...@porcupine.org> wrote: > >>> Oh, and it will of course open a DB_CONFIG file in whatever happens to > >>> be the super-user's cwd when they invoke the postmap or postalias > >>> command, so this is not just a matter of set-gid Postfix commands. > >>> > >>> [...] > >>> - if ((errno = db->set_cachesize(db, 0, dict_db_cache_size, 0)) != 0) > >>> - msg_fatal("set DB cache size %d: %m", dict_db_cache_size); > >> Is this change intentional, or did it sneak in? It seems unrelated to > >> the environment workaround. > > dbenv->set_cachesize(dbenv, 0, dict_db_cache_size, 0) rejected a > > call with the Postfix default cache size, and there appears to be > > no API to find what cache size it would have accepted. Screw it. > > This library needs to die. > > Hi Wietse, > > sorry for the techy noise on a users list in this post. There may be > valid reasons for killing off Berkeley DB, but your using it counter to > the specs is not one :-) > > Explanation: BDB did not reject the size, but it did reject your attempt > to call db->set_cachesize(...) when the "db" handle was created and > initialized with a non-NULL dbenv (the db_create(&db, dbenv, 0) call below).
I was calling dbenv->set_cachesize(dbenv, 0, dict_db_cache_size, 0) as stated in my email above, not db->set_cachesize(...) Anyway. I found a call dbenv->set_cache_max, introduced somewhere between DB 4.2 and DB 4.7. That fixes the problem for all but very old implementations. See postfix-3.3-20170612. Wietse > Meaning that: > You are attempting to set the cache size on the /database/ (not the > /environment/). The documentation of Berkeley DB states it is an error > to set the cache size for databases opened within an environment (i. e. > with a non-null dbenv used in db_create()), because the database uses > the cache from its environment. Before your patch, there was no > environment (the dbenv argument was 0 in your db_create() call), so it > was permissible to call db->set_cachesize(). > > So instead of calling db->set_cachesize, you now - after introducing the > environment - need to call dbenv->set_cachesize, (the _env_ being the > important addition), so that you set the cache size on the environment > (dbenv variable in your code) instead. > We've been doing that successfully in bogofilter for more than a decade > across various Berkeley DB versions. > > You can no longer use this: > * > https://docs.oracle.com/cd/E17275_01/html/api_reference/C/dbset_cachesize.html > "Because databases opened within Berkeley DB environments use the cache > specified to the environment, it is an error to attempt to set a cache > in a database created within an environment." > > You need to use this: > * > https://docs.oracle.com/cd/E17275_01/html/api_reference/C/envset_cachesize.html > > and you best set it very early, *before* the dbenv->open. > > > Note that the fatal error messages in the code are also misleading here > in two places - all these marked calls create are the in-memory > structures ("handles"), the actual environment or database, are only > created on their respective ->open() calls. > > + /* Fix 20170611 workaround for undocumented ./DB_CONFIG read. */ > > + if ((errno = db_env_create(&dbenv, 0)) != 0) > > + msg_fatal("create DB environment: %m"); > here ^^^^^^ I suggest: > > msg_fatal("create DB environment handle: %m"); > > > + dirname_buf = vstring_alloc(100); > > + if ((errno = dbenv->open(dbenv, sane_dirname(dirname_buf, db_path), > > + DB_INIT_MPOOL | DB_CREATE | DB_PRIVATE, 0)) != 0) > > + msg_fatal("open DB environment: %m"); > > + vstring_free(dirname_buf); > > + if ((errno = db_create(&db, dbenv, 0)) != 0) > > msg_fatal("create DB database: %m"); > > here ^^^^^^ I suggest: > > msg_fatal("create DB database handle: %m"); > > HTH > Matthias > > Wietse