Ensure option groups don't change during logging

oslo.config allows us to configure groups and options dynamically. This
can cause a race with our logging as we attempt to iterate through
option groups that are changing under our feet. This wouldn't be a huge
issue, since these are just logs are we can always log again, if needed,
but we store groups in a dictionary and Python doesn't like us changing
the size of a dict it's iterating through:

  RuntimeError: dictionary changed size during iteration

Given that we're only reading through this option group and don't need
to worry about a group _disappearing_, the solution is pretty simple:
create a copy of our option group names ahead of time so we don't need
to worry about new ones coming and messing things up.

No tests are included since this is a race and the only way I see to
reproduce this would involve lots of ugly threading.

Change-Id: Id3b28465d645a24f0fcebff2dd68a9bd30e21594
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
Closes-Bug: #1856312
(cherry picked from commit e3e2ba55ee)
(cherry picked from commit 22c286c63b)
(cherry picked from commit 0a9c6c156a)
This commit is contained in:
Stephen Finucane 2019-12-13 16:18:33 +00:00 committed by Stephen Finucane
parent a3f2568152
commit c1394f6e2d
1 changed files with 1 additions and 1 deletions

View File

@ -3019,7 +3019,7 @@ class ConfigOpts(collections.Mapping):
logger.log(lvl, "%-30s = %s", opt_name, logger.log(lvl, "%-30s = %s", opt_name,
_sanitize(opt, getattr(self, opt_name))) _sanitize(opt, getattr(self, opt_name)))
for group_name in self._groups: for group_name in list(self._groups):
group_attr = self.GroupAttr(self, self._get_group(group_name)) group_attr = self.GroupAttr(self, self._get_group(group_name))
for opt_name in sorted(self._groups[group_name]._opts): for opt_name in sorted(self._groups[group_name]._opts):
opt = self._get_opt_info(opt_name, group_name)['opt'] opt = self._get_opt_info(opt_name, group_name)['opt']