mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 18:21:39 +01:00
bitkeeper revision 1.1662.1.1 (42a07145CPNIh8TprNz04Qg7x-S7Cw)
xend cleanups from Mike Wray. XendDomain.py: Add comment for domain_mem_target_set. SrvDaemon.py: Use XEND_DAEMONIZE, XEND_DEBUG and XEND_DEBUGLOG. XendRoot.py: Use XEND_DEBUG. netif.py: Unknown domains are called "Domain-%d" % dom. params.py: Add additional parameters and set some parameters from environment variables. blkif.py, XendDomain.py: Cleanup whitespace. XendRoot.py: enable_dump default is 'no'. enable_dump is a bool. Add 'true' and 'false' to get_config_bool. XendDomainInfo.py: Add DOMAIN_CRASH shutdown code. XendDomain.py: Simplify. Add domain_dumpcore. Move class XendDomainDict outside of class XendDomain. Import shutdown_reason from XendDomainInfo. Update comment for xen_domain. PrettyPrint.py: Cleanup prettyprintstring. SrvDir.py: Cleanup render_GET. xc.c: Various cleanups. Signed-off-by: Mike Wray <mike.wray@hp.com> Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
This commit is contained in:
1 parent
f2f4f0e234
commit
d057c5ef08
10 files changed
+122
-72
No files matched your search
@@ -14,6 +14,7 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "xc_private.h"
|
||||
#include "linux_boot_params.h"
|
||||
|
||||
@@ -842,8 +843,8 @@ static PyMethodDef pyxc_methods[] = {
|
||||
{ "domain_dumpcore",
|
||||
(PyCFunction)pyxc_domain_dumpcore,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"dump core of a domain.\n"
|
||||
" dom [int]: Identifier of domain to be paused.\n\n"
|
||||
"Dump core of a domain.\n"
|
||||
" dom [int]: Identifier of domain to dump core of.\n\n"
|
||||
" corefile [string]: Name of corefile to be created.\n\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
|
||||
@@ -77,19 +77,16 @@ class SrvDir(SrvBase):
|
||||
return v
|
||||
|
||||
def render_GET(self, req):
|
||||
try:
|
||||
if self.use_sxp(req):
|
||||
req.setHeader("Content-type", sxp.mime_type)
|
||||
self.ls(req, 1)
|
||||
else:
|
||||
req.write('<html><head></head><body>')
|
||||
self.print_path(req)
|
||||
self.ls(req)
|
||||
self.form(req)
|
||||
req.write('</body></html>')
|
||||
return ''
|
||||
except Exception, ex:
|
||||
self._perform_err(ex, "GET", req)
|
||||
if self.use_sxp(req):
|
||||
req.setHeader("Content-type", sxp.mime_type)
|
||||
self.ls(req, 1)
|
||||
else:
|
||||
req.write('<html><head></head><body>')
|
||||
self.print_path(req)
|
||||
self.ls(req)
|
||||
self.form(req)
|
||||
req.write('</body></html>')
|
||||
return ''
|
||||
|
||||
def ls(self, req, use_sxp=0):
|
||||
url = req.prePathURL()
|
||||
|
||||
@@ -285,15 +285,18 @@ def prettyprint(sxpr, out=sys.stdout, width=80):
|
||||
sxp.show(sxpr, out=out)
|
||||
print >> out
|
||||
|
||||
def prettyprintstring(sxp):
|
||||
class tmpstr:
|
||||
def __init__(self):
|
||||
self.str = ""
|
||||
def write(self, str):
|
||||
self.str = self.str + str
|
||||
tmp = tmpstr()
|
||||
prettyprint(sxp, out=tmp)
|
||||
return tmp.str
|
||||
def prettyprintstring(sxp, width=80):
|
||||
"""Prettyprint an SXP form to a string.
|
||||
|
||||
sxpr s-expression
|
||||
width maximum output width
|
||||
"""
|
||||
io = StringIO.StringIO()
|
||||
prettyprint(sxpr, out=io, width=width)
|
||||
io.seek(0)
|
||||
val = io.getvalue()
|
||||
io.close()
|
||||
return val
|
||||
|
||||
def main():
|
||||
pin = sxp.Parser()
|
||||
|
||||
@@ -20,7 +20,7 @@ import sxp
|
||||
import XendRoot; xroot = XendRoot.instance()
|
||||
import XendCheckpoint
|
||||
import XendDB
|
||||
import XendDomainInfo
|
||||
from xen.xend.XendDomainInfo import XendDomainInfo, shutdown_reason
|
||||
import EventServer; eserver = EventServer.instance()
|
||||
from XendError import XendError
|
||||
from XendLogging import log
|
||||
@@ -31,6 +31,13 @@ __all__ = [ "XendDomain" ]
|
||||
|
||||
SHUTDOWN_TIMEOUT = 30
|
||||
|
||||
class XendDomainDict(dict):
|
||||
def get_by_name(self, name):
|
||||
try:
|
||||
return filter(lambda d: d.name == name, self.values())[0]
|
||||
except IndexError, err:
|
||||
return None
|
||||
|
||||
class XendDomain:
|
||||
"""Index of all domains. Singleton.
|
||||
"""
|
||||
@@ -38,15 +45,8 @@ class XendDomain:
|
||||
"""Path to domain database."""
|
||||
dbpath = "domain"
|
||||
|
||||
class XendDomainDict(dict):
|
||||
def get_by_name(self, name):
|
||||
try:
|
||||
return filter(lambda d: d.name == name, self.values())[0]
|
||||
except IndexError, err:
|
||||
return None
|
||||
|
||||
"""Dict of domain info indexed by domain id."""
|
||||
domains = XendDomainDict()
|
||||
domains = None
|
||||
|
||||
def __init__(self):
|
||||
# Hack alert. Python does not support mutual imports, but XendDomainInfo
|
||||
@@ -54,6 +54,7 @@ class XendDomain:
|
||||
# to import XendDomain from XendDomainInfo causes unbounded recursion.
|
||||
# So we stuff the XendDomain instance (self) into xroot's components.
|
||||
xroot.add_component("xen.xend.XendDomain", self)
|
||||
self.domains = XendDomainDict()
|
||||
# Table of domain info indexed by domain id.
|
||||
self.db = XendDB.XendDB(self.dbpath)
|
||||
eserver.subscribe('xend.virq', self.onVirq)
|
||||
@@ -84,6 +85,8 @@ class XendDomain:
|
||||
def xen_domain(self, dom):
|
||||
"""Get info about a single domain from xc.
|
||||
Returns None if not found.
|
||||
|
||||
@param dom domain id
|
||||
"""
|
||||
try:
|
||||
dom = int(dom)
|
||||
@@ -189,7 +192,7 @@ class XendDomain:
|
||||
continue
|
||||
log.debug('XendDomain>reap> domain died name=%s id=%s', name, id)
|
||||
if d['shutdown']:
|
||||
reason = XendDomainInfo.shutdown_reason(d['shutdown_reason'])
|
||||
reason = shutdown_reason(d['shutdown_reason'])
|
||||
log.debug('XendDomain>reap> shutdown name=%s id=%s reason=%s', name, id, reason)
|
||||
if reason in ['suspend']:
|
||||
if dominfo and dominfo.is_terminated():
|
||||
@@ -203,8 +206,8 @@ class XendDomain:
|
||||
eserver.inject('xend.domain.exit', [name, id, reason])
|
||||
self.domain_restart_schedule(id, reason)
|
||||
else:
|
||||
if xroot.get_enable_dump() == 'true':
|
||||
xc.domain_dumpcore(dom = int(id), corefile = "/var/xen/dump/%s.%s.core"%(name,id))
|
||||
if xroot.get_enable_dump():
|
||||
self.domain_dumpcore(int(id))
|
||||
eserver.inject('xend.domain.exit', [name, id, 'crash'])
|
||||
destroyed += 1
|
||||
self.final_domain_destroy(id)
|
||||
@@ -216,7 +219,7 @@ class XendDomain:
|
||||
self.reap()
|
||||
doms = self.xen_domains()
|
||||
# Add entries for any domains we don't know about.
|
||||
for (id, d) in doms.items():
|
||||
for id in doms.keys():
|
||||
if id not in self.domains:
|
||||
self.domain_lookup(id)
|
||||
# Remove entries for domains that no longer exist.
|
||||
@@ -326,9 +329,7 @@ class XendDomain:
|
||||
|
||||
try:
|
||||
fd = os.open(src, os.O_RDONLY)
|
||||
|
||||
return XendCheckpoint.restore(self, fd)
|
||||
|
||||
except OSError, ex:
|
||||
raise XendError("can't read guest state file %s: %s" %
|
||||
(src, ex[1]))
|
||||
@@ -343,20 +344,19 @@ class XendDomain:
|
||||
self.refresh_domain(id)
|
||||
return self.domains.get(id)
|
||||
|
||||
def domain_lookup(self, name):
|
||||
name = str(name)
|
||||
dominfo = self.domains.get_by_name(name) or self.domains.get(name)
|
||||
if dominfo:
|
||||
return dominfo
|
||||
try:
|
||||
d = self.xen_domain(name)
|
||||
if d:
|
||||
log.info("Creating entry for unknown domain: id=%s", name)
|
||||
dominfo = XendDomainInfo.vm_recreate(None, d)
|
||||
self._add_domain(dominfo)
|
||||
return dominfo
|
||||
except Exception, ex:
|
||||
log.exception("Error creating domain info: id=%s", name)
|
||||
def domain_lookup(self, id):
|
||||
name = str(id)
|
||||
dominfo = self.domains.get_by_name(name) or self.domains.get(id)
|
||||
if not dominfo:
|
||||
try:
|
||||
info = self.xen_domain(id)
|
||||
if info:
|
||||
log.info("Creating entry for unknown domain: id=%s", name)
|
||||
dominfo = XendDomainInfo.vm_recreate(None, info)
|
||||
self._add_domain(dominfo)
|
||||
except Exception, ex:
|
||||
log.exception("Error creating domain info: id=%s", name)
|
||||
return dominfo
|
||||
|
||||
def domain_unpause(self, id):
|
||||
"""Unpause domain execution.
|
||||
@@ -595,6 +595,7 @@ class XendDomain:
|
||||
return xc.sedf_domain_get(dominfo.dom)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
def domain_device_create(self, id, devconfig):
|
||||
"""Create a new device for a domain.
|
||||
|
||||
@@ -700,11 +701,28 @@ class XendDomain:
|
||||
raise XendError(str(ex))
|
||||
|
||||
def domain_mem_target_set(self, id, target):
|
||||
"""Set the memory target for a domain.
|
||||
|
||||
@param id: domain
|
||||
@param target: memory target (in MB)
|
||||
@return: 0 on success, -1 on error
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
return dominfo.mem_target_set(target)
|
||||
|
||||
def domain_dumpcore(self, id):
|
||||
"""Save a core dump for a crashed domain.
|
||||
|
||||
@param id: domain
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
corefile = "/var/xen/dump/%s.%s.core"% (dominfo.name, dominfo.id)
|
||||
try:
|
||||
xc.domain_dumpcore(dom=dominfo.id, corefile=corefile)
|
||||
except Exception, ex:
|
||||
log.warning("Dumpcore failed, id=%s name=%s: %s",
|
||||
dominfo.id, dominfo.name, ex)
|
||||
|
||||
|
||||
|
||||
def instance():
|
||||
"""Singleton constructor. Use this instead of the class constructor.
|
||||
"""
|
||||
|
||||
@@ -45,11 +45,16 @@ DOMAIN_REBOOT = 1
|
||||
"""Shutdown code for suspend."""
|
||||
DOMAIN_SUSPEND = 2
|
||||
|
||||
"""Shutdown code for crash."""
|
||||
DOMAIN_CRASH = 3
|
||||
|
||||
"""Map shutdown codes to strings."""
|
||||
shutdown_reasons = {
|
||||
DOMAIN_POWEROFF: "poweroff",
|
||||
DOMAIN_REBOOT : "reboot",
|
||||
DOMAIN_SUSPEND : "suspend" }
|
||||
DOMAIN_SUSPEND : "suspend",
|
||||
DOMAIN_CRASH : "crash",
|
||||
}
|
||||
|
||||
"""Map shutdown reasons to the message type to use.
|
||||
"""
|
||||
|
||||
@@ -177,7 +177,10 @@ class XendRoot:
|
||||
logfile = self.get_config_value("logfile", self.logfile_default)
|
||||
loglevel = self.get_config_value("loglevel", self.loglevel_default)
|
||||
self.logging = XendLogging(logfile, level=loglevel)
|
||||
#self.logging.addLogStderr()
|
||||
|
||||
from xen.xend.server import params
|
||||
if params.XEND_DEBUG:
|
||||
self.logging.addLogStderr()
|
||||
|
||||
def get_logging(self):
|
||||
"""Get the XendLogging instance.
|
||||
@@ -241,9 +244,9 @@ class XendRoot:
|
||||
|
||||
def get_config_bool(self, name, val=None):
|
||||
v = self.get_config_value(name, val)
|
||||
if v in ['yes', '1', 'on', 1, True]:
|
||||
if v in ['yes', '1', 'on', 'true', 1, True]:
|
||||
return True
|
||||
if v in ['no', '0', 'off', 0, False]:
|
||||
if v in ['no', '0', 'off', 'false', 0, False]:
|
||||
return False
|
||||
raise XendError("invalid xend config %s: expected bool: %s" % (name, v))
|
||||
|
||||
@@ -325,7 +328,7 @@ class XendRoot:
|
||||
return self.get_config_value('network-script', 'network')
|
||||
|
||||
def get_enable_dump(self):
|
||||
return self.get_config_value('enable-dump', 'false')
|
||||
return self.get_config_bool('enable-dump', 'no')
|
||||
|
||||
def get_vif_bridge(self):
|
||||
return self.get_config_value('vif-bridge', 'xen-br0')
|
||||
|
||||
@@ -167,7 +167,7 @@ class Daemon:
|
||||
return pid
|
||||
|
||||
def daemonize(self):
|
||||
if not DAEMONIZE: return
|
||||
if not XEND_DAEMONIZE: return
|
||||
# Detach from TTY.
|
||||
os.setsid()
|
||||
|
||||
@@ -177,16 +177,16 @@ class Daemon:
|
||||
os.close(0)
|
||||
os.close(1)
|
||||
os.close(2)
|
||||
if DEBUG:
|
||||
if XEND_DEBUG:
|
||||
os.open('/dev/null', os.O_RDONLY)
|
||||
# XXX KAF: Why doesn't this capture output from C extensions that
|
||||
# fprintf(stdout) or fprintf(stderr) ??
|
||||
os.open('/var/log/xend-debug.log', os.O_WRONLY|os.O_CREAT)
|
||||
os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT)
|
||||
os.dup(1)
|
||||
else:
|
||||
os.open('/dev/null', os.O_RDWR)
|
||||
os.dup(0)
|
||||
os.open('/var/log/xend-debug.log', os.O_WRONLY|os.O_CREAT)
|
||||
os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT)
|
||||
|
||||
|
||||
def start(self, trace=0):
|
||||
@@ -308,7 +308,7 @@ class Daemon:
|
||||
servers.start()
|
||||
except Exception, ex:
|
||||
print >>sys.stderr, 'Exception starting xend:', ex
|
||||
if DEBUG:
|
||||
if XEND_DEBUG:
|
||||
traceback.print_exc()
|
||||
log.exception("Exception starting xend")
|
||||
self.exit(1)
|
||||
|
||||
@@ -56,7 +56,7 @@ class BlkifBackend:
|
||||
|
||||
def openEvtchn(self):
|
||||
self.evtchn = channel.eventChannel(self.backendDomain, self.frontendDomain)
|
||||
|
||||
|
||||
def getEventChannelBackend(self):
|
||||
val = 0
|
||||
if self.evtchn:
|
||||
|
||||
@@ -230,7 +230,7 @@ class NetDev(Dev):
|
||||
vm = xd.domain_lookup(dom)
|
||||
vmname = vm.name
|
||||
except:
|
||||
vmname = 'DOM%d' % dom
|
||||
vmname = 'Domain-%d' % dom
|
||||
return { 'domain': vmname,
|
||||
'vif' : self.get_vifname(),
|
||||
'mac' : self.get_mac(),
|
||||
|
||||
@@ -1,6 +1,29 @@
|
||||
import os
|
||||
|
||||
def getenv(var, val, conv=None):
|
||||
"""Get a value from the environment, with optional conversion.
|
||||
|
||||
@param var name of environment variable
|
||||
@param val default value
|
||||
@param conv conversion function to apply to env value
|
||||
@return converted value or default
|
||||
"""
|
||||
try:
|
||||
v = os.getenv(var)
|
||||
if v is None:
|
||||
v = val
|
||||
else:
|
||||
print var, '=', v
|
||||
if conv:
|
||||
v = conv(v)
|
||||
except:
|
||||
v = val
|
||||
return v
|
||||
|
||||
# The following parameters could be placed in a configuration file.
|
||||
XEND_PID_FILE = '/var/run/xend.pid'
|
||||
XEND_TRACE_FILE = '/var/log/xend.trace'
|
||||
|
||||
XEND_USER = 'root'
|
||||
|
||||
XEND_PID_FILE = '/var/run/xend.pid'
|
||||
XEND_TRACE_FILE = '/var/log/xend.trace'
|
||||
XEND_DEBUG_LOG = '/var/log/xend-debug.log'
|
||||
XEND_USER = 'root'
|
||||
XEND_DEBUG = getenv("XEND_DEBUG", 0, conv=int)
|
||||
XEND_DAEMONIZE = getenv("XEND_DAEMONIZE", not XEND_DEBUG, conv=int)
|
||||