mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
Domain core-dumping fixes
The code was attempting to use the domain's current number of pages (info.nr_pages) as a maximum index. We then walk the memory map and can easily over-write past the end of the nr_pages-sized array, if the domain has more pages mapped in than earlier (live dump). Restrict ourselves to the current number of pages. Also fix the dump core method in xend to actually implement the crash and live options. In particular this means that xend clients other than xm now get non-live dumps by default. Signed-off-by: John Levon <john.levon@sun.com>
This commit is contained in:
1 parent
51494c8651
commit
fb0a30b839
5 files changed
+54
-41
No files matched your search
@@ -1237,13 +1237,23 @@ class XendDomain:
|
||||
POWER_STATE_NAMES[DOM_STATE_PAUSED],
|
||||
POWER_STATE_NAMES[dominfo._stateGet()])
|
||||
|
||||
dopause = (not live and dominfo._stateGet() == DOM_STATE_RUNNING)
|
||||
if dopause:
|
||||
dominfo.pause()
|
||||
|
||||
try:
|
||||
log.info("Domain core dump requested for domain %s (%d) "
|
||||
"live=%d crash=%d.",
|
||||
dominfo.getName(), dominfo.getDomid(), live, crash)
|
||||
return dominfo.dumpCore(filename)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
try:
|
||||
log.info("Domain core dump requested for domain %s (%d) "
|
||||
"live=%d crash=%d.",
|
||||
dominfo.getName(), dominfo.getDomid(), live, crash)
|
||||
dominfo.dumpCore(filename)
|
||||
if crash:
|
||||
self.domain_destroy(domid)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
finally:
|
||||
if dopause and not crash:
|
||||
dominfo.unpause()
|
||||
|
||||
def domain_destroy(self, domid):
|
||||
"""Terminate domain immediately.
|
||||
|
||||
@@ -2027,26 +2027,31 @@ class XendDomainInfo:
|
||||
@raise: XendError if core dumping failed.
|
||||
"""
|
||||
|
||||
try:
|
||||
if not corefile:
|
||||
this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
|
||||
corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time,
|
||||
self.info['name_label'], self.domid)
|
||||
if not corefile:
|
||||
this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
|
||||
corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time,
|
||||
self.info['name_label'], self.domid)
|
||||
|
||||
if os.path.isdir(corefile):
|
||||
raise XendError("Cannot dump core in a directory: %s" %
|
||||
corefile)
|
||||
|
||||
self._writeVm(DUMPCORE_IN_PROGRESS, 'True')
|
||||
xc.domain_dumpcore(self.domid, corefile)
|
||||
if os.path.isdir(corefile):
|
||||
raise XendError("Cannot dump core in a directory: %s" %
|
||||
corefile)
|
||||
|
||||
try:
|
||||
try:
|
||||
self._writeVm(DUMPCORE_IN_PROGRESS, 'True')
|
||||
xc.domain_dumpcore(self.domid, corefile)
|
||||
except RuntimeError, ex:
|
||||
corefile_incomp = corefile+'-incomplete'
|
||||
try:
|
||||
os.rename(corefile, corefile_incomp)
|
||||
except:
|
||||
pass
|
||||
|
||||
log.error("core dump failed: id = %s name = %s: %s",
|
||||
self.domid, self.info['name_label'], str(ex))
|
||||
raise XendError("Failed to dump core: %s" % str(ex))
|
||||
finally:
|
||||
self._removeVm(DUMPCORE_IN_PROGRESS)
|
||||
except RuntimeError, ex:
|
||||
corefile_incomp = corefile+'-incomplete'
|
||||
os.rename(corefile, corefile_incomp)
|
||||
self._removeVm(DUMPCORE_IN_PROGRESS)
|
||||
log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s",
|
||||
self.domid, self.info['name_label'])
|
||||
raise XendError("Failed to dump core: %s" % str(ex))
|
||||
|
||||
#
|
||||
# Device creation/deletion functions
|
||||
|
||||
@@ -1351,22 +1351,10 @@ def xm_dump_core(args):
|
||||
else:
|
||||
filename = None
|
||||
|
||||
if not live:
|
||||
ds = server.xend.domain.pause(dom, True)
|
||||
|
||||
try:
|
||||
print "Dumping core of domain: %s ..." % str(dom)
|
||||
server.xend.domain.dump(dom, filename, live, crash)
|
||||
|
||||
if crash:
|
||||
print "Destroying domain: %s ..." % str(dom)
|
||||
server.xend.domain.destroy(dom)
|
||||
elif reset:
|
||||
print "Resetting domain: %s ..." % str(dom)
|
||||
server.xend.domain.reset(dom)
|
||||
finally:
|
||||
if not live and not crash and not reset and ds == DOM_STATE_RUNNING:
|
||||
server.xend.domain.unpause(dom)
|
||||
print "Dumping core of domain: %s ..." % str(dom)
|
||||
server.xend.domain.dump(dom, filename, live, crash)
|
||||
if reset:
|
||||
server.xend.domain.reset(dom)
|
||||
|
||||
def xm_rename(args):
|
||||
arg_check(args, "rename", 2)
|
||||
|
||||