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).

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

Reply via email to