Merge branch 'backup-logging-deadlock'
* backup-logging-deadlock: backup: avoid deadlock on logging during restore
This commit is contained in:
commit
55c9a82c0a
@ -249,6 +249,30 @@ def launch_scrypt(action, input_name, output_name, passphrase):
|
|||||||
p.pty = pty
|
p.pty = pty
|
||||||
return p
|
return p
|
||||||
|
|
||||||
|
def _fix_logging_lock_after_fork():
|
||||||
|
"""
|
||||||
|
HACK:
|
||||||
|
This is running in a child process, parent might hold some lock
|
||||||
|
while fork was called (but will be released only in a parent
|
||||||
|
process). This specifically applies to a logging module and
|
||||||
|
results in a deadlock (if one is unlucky). "Fix" this by
|
||||||
|
reinitialize a lock on all registered logging handlers
|
||||||
|
just after a fork() call, until fixed upstream:
|
||||||
|
|
||||||
|
https://bugs.python.org/issue6721
|
||||||
|
"""
|
||||||
|
if not hasattr(logging, '_handlerList'):
|
||||||
|
return
|
||||||
|
|
||||||
|
# pylint: disable=protected-access
|
||||||
|
for handler_ref in logging._handlerList:
|
||||||
|
handler = handler_ref()
|
||||||
|
if handler is None:
|
||||||
|
continue
|
||||||
|
if handler.lock:
|
||||||
|
handler.lock = type(handler.lock)()
|
||||||
|
|
||||||
|
|
||||||
class ExtractWorker3(Process):
|
class ExtractWorker3(Process):
|
||||||
'''Process for handling inner tar layer of backup archive'''
|
'''Process for handling inner tar layer of backup archive'''
|
||||||
# pylint: disable=too-many-instance-attributes
|
# pylint: disable=too-many-instance-attributes
|
||||||
@ -362,6 +386,7 @@ class ExtractWorker3(Process):
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
|
_fix_logging_lock_after_fork()
|
||||||
self.__run__()
|
self.__run__()
|
||||||
except Exception:
|
except Exception:
|
||||||
# Cleanup children
|
# Cleanup children
|
||||||
|
Loading…
Reference in New Issue
Block a user