2
0
mirror of https://github.com/xcat2/confluent.git synced 2025-01-17 21:23:18 +00:00

Fix DB corruption potential

Make sure that the dbm object is closed before another thread might come along.  Out of an overabundance of caution,
also join() existing cfgwriter thread to make sure that only one thread touches it at a time.  In theory, it should only possibly
be after the db is closed, but take no chances.
This commit is contained in:
Jarrod Johnon 2014-09-23 12:08:13 -04:00
parent 89ca5b412b
commit 8728007d1e

View File

@ -1130,6 +1130,9 @@ class ConfigManager(object):
cls._writepending = True
return
cls._syncrunning = True
# if the thread is exiting, join it to let it close, just in case
if cls._cfgwriter is not None:
cls._cfgwriter.join()
cls._cfgwriter = threading.Thread(target=cls._sync_to_file)
cls._cfgwriter.start()
@ -1141,14 +1144,16 @@ class ConfigManager(object):
del _cfgstore['dirtyglobals']
_mkpath(cls._cfgdir)
globalf = dbm.open(cls._cfgdir + "/globals", 'c', 384) # 0600
for globalkey in dirtyglobals:
if globalkey in _cfgstore['globals']:
globalf[globalkey] = \
cPickle.dumps(_cfgstore['globals'][globalkey])
else:
if globalkey in globalf:
del globalf[globalkey]
globalf.close()
try:
for globalkey in dirtyglobals:
if globalkey in _cfgstore['globals']:
globalf[globalkey] = \
cPickle.dumps(_cfgstore['globals'][globalkey])
else:
if globalkey in globalf:
del globalf[globalkey]
finally:
globalf.close()
if 'dirtykeys' in _cfgstore:
with _dirtylock:
currdirt = copy.deepcopy(_cfgstore['dirtykeys'])
@ -1163,13 +1168,16 @@ class ConfigManager(object):
currdict = _cfgstore['tenant'][tenant]
for category in dkdict.iterkeys():
_mkpath(pathname)
dbf = dbm.open(pathname + category, 'c', 384) # 0600 mode
for ck in dkdict[category]:
if ck not in currdict[category]:
if ck in dbf:
del dbf[ck]
else:
dbf[ck] = cPickle.dumps(currdict[category][ck])
dbf = dbm.open(pathname + category, 'c', 384): # 0600
try:
for ck in dkdict[category]:
if ck not in currdict[category]:
if ck in dbf:
del dbf[ck]
else:
dbf[ck] = cPickle.dumps(currdict[category][ck])
finally:
dbf.close()
willrun = False
with cls._syncstate:
if cls._writepending: