Maintained by: NLnet Labs

[Unbound-users] Thread safety and atomicity assumptions for unbound-control set_option

W.C.A. Wijngaards
Mon Aug 15 10:29:57 CEST 2011

Hash: SHA1

Hi Jake,

On 08/12/2011 11:01 PM, Jake Montgomery wrote:
> I'm a developer, and I sometimes make custom modifications to the the
> unbound code. I am a bit confused about the assumptions being made in
> the unbound code with regard to what is safe on multiprocessor systems.

It is multiprocessor safe.

> The 'new' "unbound-control set_option" command seems to allow the
> modification of many configuration variables by directly writing to the

Yes, it comes from the set_option() call to libunbound which accepts the
same parameters (and because it executes before libunbound starts it
support almost all options very well).  And it was very few lines of
code to provide the function in the live server - proviso that it does
not support all of the options.

What would work is in a threaded unbound compile you change 'boolean'
style options.  Changing a single integer is fairly safe on
multiprocessor machines, and using that as a boolean - remember that the
other threads only read, so the worst that could happen is that they get
a garbled value read back.  For a boolean, 0 or not zero, this is very
harmless.  For other variables, yes indeed, but you are saved by modern
cpus where the 'sig_atomic_t' is equal to 'int', therefore, you do not
see 'garbled' versions of the integers.

If something needs stronger support, this can be provided but would need
special code.  set_option is a power-user interface.

get_option is much more useful and highly appreciated, I hear, in some
environments (for accountability).

> globally shared config_file structure. Most of these variables are never
> used after initialization (which begs the question - why make them
> settable?) However, some of them are accessed directly during normal

Well they are settable because in libunbound, it works, and is a user
interface to set the options you want the validator to use.

> operation. AFAICT, it is possible for these variables to be written and
> read simultaneously on multiprocessor systems. The variable

Yes but only one thread can write, and the others read.  And this is
'int', often similar to 'sig_atomic_t', and very often interpreted as
booleans.  Hence I am not worried about it.

> config_file->log_queries is one of many examples. I have not done an
> exhaustive search, but the examples I have found are all single integer
> values. Nonetheless, concurrent writing and reading goes against what I

Pfew :-)

> understand to be _conservative_ best practices for cross platform code. 

Yes.  Set_option for some options may need special support.  Also, if
you are not running threaded but forked, I believe the set_option
command it sent and also processed by the other processes, and it would
work fine there.

> In addition, the variables are not marked as volatile, so it would be
> theoretically possible for subsequent reads to be optimized out by the c
> compiler, resulting in the settings changes not being reflected in
> behavioral changes on worker threads, other than the one which processed
> the command. (Admittedly, this is possible in theory, but unlikely in
> the extreme in practice, given current compilers and the scope of the
> variables.)


> * This is not intended as a troll or criticism, and I have the utmost
> respect for the creators and maintainers of the unbound code base. *

thanks, blush :-)

> It would be helpful for me to understand what assumptions and guidelines
> the unbound code uses for unprotected concurrent memory access. Armed
> with this information, I could make my modifications in a manner
> consistent with the current code.

The set_option is indeed as we spoke about.

In other code (the cache), there are proper mutexes.

For handling control commands (i.e. not set_option) it uses pipes to
signal and do IPC.

Also there is signal handling with proper volatile sig_atomic_t

The set_option command certainly seems to be too powerful, and not easy
to understand, and with the concerns you rais, I wonder if it may be
better to remove the command from unbound-control (it would stay in
libunbound because that works).

Best regards,
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora -