From 0121cb2fd4e75d809519afbe8f60a1f31121821e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Mon, 22 Feb 2016 17:56:43 +0100 Subject: [PATCH] qmemman: make memory request handling more defensive If getting memory for new VM fails for any reason, make sure that global lock will be released. Otherwise qmemman will stop functioning at all. QubesOS/qubes-issues#1636 --- qmemman/qmemman_server.py | 60 +++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/qmemman/qmemman_server.py b/qmemman/qmemman_server.py index 7c295243..ff8ae69c 100755 --- a/qmemman/qmemman_server.py +++ b/qmemman/qmemman_server.py @@ -175,37 +175,41 @@ class QMemmanReqHandler(SocketServer.BaseRequestHandler): self.log = logging.getLogger('qmemman.daemon.reqhandler') got_lock = False - # self.request is the TCP socket connected to the client - while True: - self.data = self.request.recv(1024).strip() - self.log.debug('data={!r}'.format(self.data)) - if len(self.data) == 0: - self.log.info('EOF') + try: + # self.request is the TCP socket connected to the client + while True: + self.data = self.request.recv(1024).strip() + self.log.debug('data={!r}'.format(self.data)) + if len(self.data) == 0: + self.log.info('EOF') + if got_lock: + global force_refresh_domain_list + force_refresh_domain_list = True + return + + # XXX something is wrong here: return without release? if got_lock: - global force_refresh_domain_list - force_refresh_domain_list = True - global_lock.release() - self.log.debug('global_lock released') - return + self.log.warning('Second request over qmemman.sock?') + return - # XXX something is wrong here: return without release? + self.log.debug('acquiring global_lock') + global_lock.acquire() + self.log.debug('global_lock acquired') + + got_lock = True + if system_state.do_balloon(int(self.data)): + resp = "OK\n" + else: + resp = "FAIL\n" + self.log.debug('resp={!r}'.format(resp)) + self.request.send(resp) + except BaseException as e: + self.log.exception( + "exception while handling request: {!r}".format(e)) + finally: if got_lock: - self.log.warning('Second request over qmemman.sock?') - return - - self.log.debug('acquiring global_lock') - global_lock.acquire() - self.log.debug('global_lock acquired') - - got_lock = True - if system_state.do_balloon(int(self.data)): - resp = "OK\n" - else: - resp = "FAIL\n" - self.log.debug('resp={!r}'.format(resp)) - self.request.send(resp) - - # XXX no release of lock? + global_lock.release() + self.log.debug('global_lock released') def start_server(server):