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
This commit is contained in:
Marek Marczykowski-Górecki 2015-09-25 22:06:14 +02:00
parent 4a4d16feb9
commit dd1bea98e1
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724

View File

@ -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),