diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h index a95cf227d3..4d77312f6e 100644 --- a/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h +++ b/linux-2.6.11-xen-sparse/include/asm-xen/hypervisor.h @@ -311,6 +311,22 @@ HYPERVISOR_suspend( return ret; } +static inline int +HYPERVISOR_crash( + void) +{ + int ret; + unsigned long ign1; + __asm__ __volatile__ ( + TRAP_INSTR + : "=a" (ret), "=b" (ign1) + : "0" (__HYPERVISOR_sched_op), + "1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift)) + : "memory" ); + + return ret; +} + static inline long HYPERVISOR_set_timer_op( u64 timeout) diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index a62b112519..8d670c3d16 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -3,10 +3,22 @@ # Port xend should use for the HTTP interface. (xend-port 8000) -# Address xend should listen on. +# Port xend should use for the event interface. +(xend-event-port 8001) + +# Address xend should listen on for HTTP connections. # Specifying 'localhost' prevents remote connections. # Specifying the empty string '' allows all connections. -(xend-address '') +(xend-address 'localhost') + +# The port xend should start from when allocating a port +# for a domain console. +(console-port-base 9600) + +# Address xend should listen on for console connections. +# Specifying 'localhost' prevents remote connections. +# Specifying the empty string '' allows all connections. +(console-address 'localhost') ## Use the following if VIF traffic is routed. # The script used to start/stop networking for xend. diff --git a/tools/python/xen/xend/Args.py b/tools/python/xen/xend/Args.py index 3e16844f74..480aa7ac21 100644 --- a/tools/python/xen/xend/Args.py +++ b/tools/python/xen/xend/Args.py @@ -78,6 +78,8 @@ class Args: val = str(v) elif type == 'sxpr': val = self.sxpr(v) + elif type == 'bool': + val = self.bool(v) else: raise ArgError('invalid type:' + str(type)) return val @@ -86,6 +88,9 @@ class Args: except StandardError, ex: raise ArgError(str(ex)) + def bool(self, v): + return (v.lower() in ['on', 'yes', '1', 'true']) + def sxpr(self, v): if isinstance(v, types.ListType): val = v diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index dea3eeeb2f..c8236a4ecd 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -2,6 +2,11 @@ """Xend root class. Creates the event server and handles configuration. + +Other classes get config variables by importing this module, +using instance() to get a XendRoot instance, and then +the config functions (e.g. get_xend_port()) to get +configured values. """ import os @@ -34,17 +39,33 @@ class XendRoot: """Where block control scripts live.""" block_script_dir = "/etc/xen/scripts" + """Default path to the log file. """ logfile_default = "/var/log/xend.log" loglevel_default = 'DEBUG' + """Default interface address xend listens at. """ + xend_address_default = '' + + """Default port xend serves HTTP at. """ + xend_port_default = '8000' + + """Default port xend serves events at. """ + xend_event_port_default = '8001' + + """Default inteface address xend listens at for consoles.""" + console_address_default = '' + + """Default port xend serves consoles at. """ + console_port_base_default = '9600' + components = {} def __init__(self): self.dbroot = None self.config_path = None self.config = None - self.logger = None + self.logging = None self.configure() eserver.subscribe('xend.*', self.event_handler) #eserver.subscribe('xend.domain.created', self.event_handler) @@ -73,9 +94,9 @@ class XendRoot: def _format(self, msg, args): if args: - return str(msg) - else: return str(msg) % args + else: + return str(msg) def _log(self, mode, fmt, args): """Logging function that uses the logger if it exists, otherwise @@ -90,7 +111,7 @@ class XendRoot: if log: getattr(log, mode)(fmt, *args) else: - print >>stderr, "xend", "[%s]" % level, self._format(msg, args) + print >>sys.stderr, "xend", "[%s]" % level, self._format(fmt, args) def logDebug(self, fmt, *args): """Log a debug message. @@ -132,7 +153,6 @@ class XendRoot: self.configure_logger() self.dbroot = self.get_config_value("dbroot", self.dbroot_default) - def configure_logger(self): logfile = self.get_config_value("logfile", self.logfile_default) loglevel = self.get_config_value("loglevel", self.loglevel_default) @@ -146,7 +166,7 @@ class XendRoot: def get_logger(self): """Get the logger. """ - return self.logging.getLogger() + return self.logging and self.logging.getLogger() def get_dbroot(self): """Get the path to the database root. @@ -160,14 +180,20 @@ class XendRoot: """ self.config_path = os.getenv(self.config_var, self.config_default) if os.path.exists(self.config_path): - fin = file(self.config_path, 'rb') + #self.logInfo('Reading config file %s', self.config_path) try: - config = sxp.parse(fin) + fin = file(self.config_path, 'rb') + try: + config = sxp.parse(fin) + finally: + fin.close() config.insert(0, 'xend-config') self.config = config - finally: - fin.close() + except Exception, ex: + self.logError('Reading config file %s: %s', self.config_path, str(ex)) + raise else: + self.logError('Config file does not exist: %s', self.config_path) self.config = ['xend-config'] def get_config(self, name=None): @@ -193,10 +219,35 @@ class XendRoot: return sxp.child_value(self.config, name, val=val) def get_xend_port(self): - return int(self.get_config_value('xend-port', '8000')) + """Get the port xend listens at for its HTTP interface. + """ + return int(self.get_config_value('xend-port', self.xend_port_default)) + + def get_xend_event_port(self): + """Get the port xend listens at for connection to its event server. + """ + return int(self.get_config_value('xend-event-port', self.xend_event_port_default)) def get_xend_address(self): - return self.get_config_value('xend-address', '') + """Get the address xend listens at for its HTTP and event ports. + This defaults to the empty string which allows all hosts to connect. + If this is set to 'localhost' only the localhost will be able to connect + to the HTTP and event ports. + """ + return self.get_config_value('xend-address', self.xend_address_default) + + def get_console_address(self): + """Get the address xend listens at for its console ports. + This defaults to the empty string which allows all hosts to connect. + If this is set to 'localhost' only the localhost will be able to connect + to the console ports. + """ + return self.get_config_value('console-address', self.console_address_default) + + def get_console_port_base(self): + """Get the base port number used to generate console ports for domains. + """ + return int(self.get_config_value('console-port-base', self.console_port_base_default)) def get_block_script(self, type): return self.get_config_value('block-%s' % type, '') diff --git a/tools/python/xen/xend/server/SrvBase.py b/tools/python/xen/xend/server/SrvBase.py index b32d102273..5990733d75 100644 --- a/tools/python/xen/xend/server/SrvBase.py +++ b/tools/python/xen/xend/server/SrvBase.py @@ -106,7 +106,8 @@ class SrvBase(resource.Resource): try: val = op_method(op, req) except Exception, err: - return self._perform_err(err, op, req) + self._perform_err(err, op, req) + return '' if isinstance(val, defer.Deferred): val.addCallback(self._perform_cb, op, req, dfr=1) diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 117ae2a973..2ca8f38f99 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -598,10 +598,10 @@ class Daemon: def set_user(self): # Set the UID. try: - os.setuid(pwd.getpwnam(USER)[2]) + os.setuid(pwd.getpwnam(XEND_USER)[2]) return 0 except KeyError, error: - print "Error: no such user '%s'" % USER + print "Error: no such user '%s'" % XEND_USER return 1 def stop(self): @@ -611,7 +611,7 @@ class Daemon: xroot = XendRoot.instance() log.info("Xend Daemon started") self.createFactories() - self.listenEvent() + self.listenEvent(xroot) self.listenNotifier() self.listenVirq() SrvServer.create(bridge=1) @@ -625,9 +625,11 @@ class Daemon: self.usbifCF = usbif.UsbifControllerFactory() self.consoleCF = console.ConsoleControllerFactory() - def listenEvent(self): + def listenEvent(self, xroot): protocol = EventFactory(self) - return reactor.listenTCP(EVENT_PORT, protocol) + port = xroot.get_xend_event_port() + interface = xroot.get_xend_address() + return reactor.listenTCP(port, protocol, interface=interface) def listenNotifier(self): protocol = NotifierProtocol(self.channelF) diff --git a/tools/python/xen/xend/server/SrvDir.py b/tools/python/xen/xend/server/SrvDir.py index 106c5ef268..712521c7b3 100644 --- a/tools/python/xen/xend/server/SrvDir.py +++ b/tools/python/xen/xend/server/SrvDir.py @@ -88,7 +88,7 @@ class SrvDir(SrvBase): req.write('') return '' except Exception, ex: - self._perform_err(ex, req) + self._perform_err(ex, "GET", req) def ls(self, req, use_sxp=0): url = req.prePathURL() diff --git a/tools/python/xen/xend/server/console.py b/tools/python/xen/xend/server/console.py index ea4bf49921..3e76c6ccef 100755 --- a/tools/python/xen/xend/server/console.py +++ b/tools/python/xen/xend/server/console.py @@ -11,6 +11,8 @@ from xen.xend.XendError import XendError from xen.xend import EventServer eserver = EventServer.instance() from xen.xend.XendLogging import log +from xen.xend import XendRoot +xroot = XendRoot.instance() import controller from messages import * @@ -191,7 +193,8 @@ class ConsoleController(controller.Controller): pass else: f = ConsoleFactory(self, self.idx) - self.listener = reactor.listenTCP(self.console_port, f) + interface = xroot.get_console_address() + self.listener = reactor.listenTCP(self.console_port, f, interface=interface) def connect(self, addr, conn): """Connect a TCP connection to the console. diff --git a/tools/python/xen/xend/server/params.py b/tools/python/xen/xend/server/params.py index bb5277aecd..0f8632a4f2 100644 --- a/tools/python/xen/xend/server/params.py +++ b/tools/python/xen/xend/server/params.py @@ -3,9 +3,5 @@ XEND_PID_FILE = '/var/run/xend.pid' XFRD_PID_FILE = '/var/run/xfrd.pid' XEND_TRACE_FILE = '/var/log/xend.trace' -USER = 'root' - -EVENT_PORT = 8001 - -CONSOLE_PORT_BASE = 9600 +XEND_USER = 'root' diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index 87de21eb4b..bcc5db1d8d 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -190,6 +190,16 @@ #define SCHEDOP_cmdmask 255 /* 8-bit command. */ #define SCHEDOP_reasonshift 8 /* 8-bit reason code. (SCHEDOP_shutdown) */ +/* + * Reason codes for SCHEDOP_shutdown. These may be interpreted by control + * software to determine the appropriate action. For the most part, Xen does + * not care about the shutdown code (SHUTDOWN_crash excepted). + */ +#define SHUTDOWN_poweroff 0 /* Domain exited normally. Clean up and kill. */ +#define SHUTDOWN_reboot 1 /* Clean up, kill, and then restart. */ +#define SHUTDOWN_suspend 2 /* Clean up, save suspend info, kill. */ +#define SHUTDOWN_crash 3 /* Tell controller we've crashed. */ + /* * Commands to HYPERVISOR_console_io(). */