From dd1bea98e16f7674b25dd7b3ab29b5a638ee8e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Fri, 25 Sep 2015 22:06:14 +0200 Subject: [PATCH] core/start: ensure that the previous QubesDB daemon isn't running When restarting VM (starting it just after it was shut down), it may happen that previous `qubesdb-daemon` instance is still running - if VM doesn't properly terminate the connection, dom0 part will not terminate immediately, but at next alive check (every 10s). Such `qubesdb-daemon`, when terminating, will remove pid file and socket file. In case of new daemon already running it would be those of the new daemon, making the whole QubesDB of this VM inaccessible for dom0 (`qubesdb-daemon` is running, but its socket is removed). To prevent this race, ensure that previous instance is terminated before starting the new one. There is no need to manually removing socket file, because if some stale socket exists, it will be replaced by the new one when new `qubesdb-daemon` starts up. QubesOS/qubes-issues#1241 --- core-modules/000QubesVm.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core-modules/000QubesVm.py b/core-modules/000QubesVm.py index 1cc8d212..5006296f 100644 --- a/core-modules/000QubesVm.py +++ b/core-modules/000QubesVm.py @@ -34,6 +34,7 @@ import sys import time import uuid import xml.parsers.expat +import signal from qubes import qmemman from qubes import qmemman_algo import libvirt @@ -1703,6 +1704,18 @@ class QubesVm(object): def start_qubesdb(self): self.log.debug('start_qubesdb()') + pidfile = '/var/run/qubes/qubesdb.{}.pid'.format(self.name) + try: + if os.path.exists(pidfile): + old_qubesdb_pid = open(pidfile, 'r').read() + os.kill(int(old_qubesdb_pid), signal.SIGTERM) + timeout = 25 + while os.path.exists(pidfile) and timeout: + time.sleep(0.2) + timeout -= 1 + except IOError: # ENOENT (pidfile) + pass + retcode = subprocess.call ([ system_path["qubesdb_daemon_path"], str(self.xid),