core: cleanup remains of failed domain startup (#825)

This commit is contained in:
Marek Marczykowski-Górecki 2014-05-10 21:23:04 +02:00
parent 067876afb6
commit e5feb3169a
2 changed files with 43 additions and 2 deletions

View File

@ -607,10 +607,13 @@ class QubesVm(object):
return dominfo
return None
def get_xc_dominfo(self):
def get_xc_dominfo(self, name = None):
if dry_run:
return
if name is None:
name = self.name
start_xid = self.xid
if start_xid < 0:
start_xid = 0
@ -626,7 +629,7 @@ class QubesVm(object):
for dominfo in domains:
domname = self._xid_to_name(dominfo['domid'])
if domname == self.name:
if domname == name:
return dominfo
return None
@ -1662,6 +1665,10 @@ class QubesVm(object):
try:
subprocess.check_call(xl_cmdline)
except:
try:
self._cleanup_zombie_domains()
except:
pass
raise QubesException("Failed to load VM config")
xid = self.get_xid()
@ -1716,6 +1723,24 @@ class QubesVm(object):
return xid
def _cleanup_zombie_domains(self):
"""
This function is workaround broken libxl (which leaves not fully
created domain on failure) and vchan on domain crash behaviour
@return: None
"""
xc = self.get_xc_dominfo()
if xc and xc['dying'] == 1:
# GUID still running?
guid_pidfile = '/var/run/qubes/guid-running.%d' % xc['domid']
if os.path.exists(guid_pidfile):
guid_pid = open(guid_pidfile).read().strip()
os.kill(int(guid_pid), 15)
# qrexec still running?
if self.is_qrexec_running():
#TODO: kill qrexec daemon
pass
def shutdown(self, force=False, xid = None):
if dry_run:
return

View File

@ -503,6 +503,22 @@ class QubesHVm(QubesVm):
xs.set_permissions('', '{0}/qubes-tools'.format(domain_path),
[{ 'dom': xid }])
def _cleanup_zombie_domains(self):
super(QubesHVm, self)._cleanup_zombie_domains()
if not self.is_running():
xc_stubdom = self.get_xc_dominfo(name=self.name+'-dm')
if xc_stubdom is not None:
if xc_stubdom['paused'] == 1:
subprocess.call(['xl', 'destroy', str(xc_stubdom['domid'])])
if xc_stubdom['dying'] == 1:
# GUID still running?
guid_pidfile = \
'/var/run/qubes/guid-running.%d' % xc_stubdom['domid']
if os.path.exists(guid_pidfile):
guid_pid = open(guid_pidfile).read().strip()
os.kill(int(guid_pid), 15)
def suspend(self):
if dry_run:
return