Self-resetting PrivContext
When nova-compute, an oslo.service, receives SIGHUP, running PrivContext clients terminate, resulting in the shutdown of their corresponding ClientChannel threads. Subsequent attempts to execute privileged methods fail with EPIPE as a result. The PrivContext._wrap'per (the meat of the entrypoint decorator) already had a check to lazily start() the ClientChannel if that hasn't already happened. This commit makes ClientChannel store state indicating whether it's still running; and adds logic to PrivContext._wrap to check that state and reset (stop() and re-start()) the ClientChannel if it was previously created but terminated. Change-Id: I8096fc7fd014e6dd299fae8ab073336c7cae362a Closes-Bug: #1715374
This commit is contained in:
parent
14fbdc967f
commit
e896ed39c4
@ -113,6 +113,7 @@ class Future(object):
|
|||||||
|
|
||||||
class ClientChannel(object):
|
class ClientChannel(object):
|
||||||
def __init__(self, sock):
|
def __init__(self, sock):
|
||||||
|
self.running = False
|
||||||
self.writer = Serializer(sock)
|
self.writer = Serializer(sock)
|
||||||
self.lock = threading.Lock()
|
self.lock = threading.Lock()
|
||||||
self.reader_thread = threading.Thread(
|
self.reader_thread = threading.Thread(
|
||||||
@ -127,6 +128,8 @@ class ClientChannel(object):
|
|||||||
|
|
||||||
def _reader_main(self, reader):
|
def _reader_main(self, reader):
|
||||||
"""This thread owns and demuxes the read channel"""
|
"""This thread owns and demuxes the read channel"""
|
||||||
|
with self.lock:
|
||||||
|
self.running = True
|
||||||
for msg in reader:
|
for msg in reader:
|
||||||
msgid, data = msg
|
msgid, data = msg
|
||||||
if msgid is None:
|
if msgid is None:
|
||||||
@ -148,6 +151,7 @@ class ClientChannel(object):
|
|||||||
with self.lock:
|
with self.lock:
|
||||||
for mbox in self.outstanding_msgs.values():
|
for mbox in self.outstanding_msgs.values():
|
||||||
mbox.set_exception(exc)
|
mbox.set_exception(exc)
|
||||||
|
self.running = False
|
||||||
|
|
||||||
def out_of_band(self, msg):
|
def out_of_band(self, msg):
|
||||||
"""Received OOB message. Subclasses might want to override this."""
|
"""Received OOB message. Subclasses might want to override this."""
|
||||||
|
@ -237,6 +237,9 @@ class PrivContext(object):
|
|||||||
def _wrap(self, func, *args, **kwargs):
|
def _wrap(self, func, *args, **kwargs):
|
||||||
if self.client_mode:
|
if self.client_mode:
|
||||||
name = '%s.%s' % (func.__module__, func.__name__)
|
name = '%s.%s' % (func.__module__, func.__name__)
|
||||||
|
if self.channel is not None and not self.channel.running:
|
||||||
|
LOG.warning("RESTARTING PrivContext for %s", name)
|
||||||
|
self.stop()
|
||||||
if self.channel is None:
|
if self.channel is None:
|
||||||
self.start()
|
self.start()
|
||||||
return self.channel.remote_call(name, args, kwargs)
|
return self.channel.remote_call(name, args, kwargs)
|
||||||
|
Loading…
Reference in New Issue
Block a user