John Levon
2006-Dec-28 17:52 UTC
[Xen-devel] [PATCH] Support xend configuration via Solaris SMF
# HG changeset patch # User john.levon@sun.com # Date 1167328159 28800 # Node ID 1dda9046d582d2cfb4efb00bd23124d85afcdb62 # Parent d0a640b8c84c6c10b3312233d68cbc006252d873 Enable xend to pick up properties from SMF on Solaris. Also rename XendRoot to the much clearer XendOptions. Signed-off-by: John Levon <john.levon@sun.com> diff --git a/tools/python/setup.py b/tools/python/setup.py --- a/tools/python/setup.py +++ b/tools/python/setup.py @@ -30,12 +30,23 @@ xs = Extension("xs", libraries = libraries, sources = [ "xen/lowlevel/xs/xs.c" ]) +scf = Extension("scf", + extra_compile_args = extra_compile_args, + include_dirs = include_dirs + [ "xen/lowlevel/scf" ], + library_dirs = library_dirs, + libraries = libraries, + sources = [ "xen/lowlevel/scf/scf.c" ]) + acm = Extension("acm", extra_compile_args = extra_compile_args, include_dirs = include_dirs + [ "xen/lowlevel/acm" ], library_dirs = library_dirs, libraries = libraries, sources = [ "xen/lowlevel/acm/acm.c" ]) + +modules = [ xc, xs, acm ] +if os.uname()[0] == ''SunOS'': + modules.append(scf) setup(name = ''xen'', version = ''3.0'', @@ -56,7 +67,7 @@ setup(name = ''xen'', ''xen.xm.tests'' ], ext_package = "xen.lowlevel", - ext_modules = [ xc, xs, acm ] + ext_modules = modules ) os.chdir(''logging'') diff --git a/tools/python/xen/lowlevel/scf/scf.c b/tools/python/xen/lowlevel/scf/scf.c new file mode 100644 --- /dev/null +++ b/tools/python/xen/lowlevel/scf/scf.c @@ -0,0 +1,156 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <Python.h> + +#include <libscf.h> +#include <stdio.h> + +#define XEND_FMRI "svc:/system/xen/xend:default" +#define XEND_PG "config" + +static PyObject *scf_exc; + +static void * +scf_exception(const char *err, const char *value) +{ + int scferr = scf_error(); + const char *scfstrerr = scf_strerror(scferr); + PyObject *obj = Py_BuildValue("(isss)", scferr, err, scfstrerr, value); + PyErr_SetObject(scf_exc, obj); + return (NULL); +} + +static PyObject * +pyscf_get_bool(PyObject *o, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", NULL }; + scf_simple_prop_t *prop; + uint8_t *val; + char *name; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) + return (NULL); + + prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name); + + if (prop == NULL) + return (scf_exception("scf_simple_prop_get() failed", name)); + + if ((val = scf_simple_prop_next_boolean(prop)) == NULL) + return (scf_exception("scf_simple_prop_next_boolean() failed", + name)); + + if (*val) { + scf_simple_prop_free(prop); + Py_INCREF(Py_True); + return (Py_True); + } + + scf_simple_prop_free(prop); + Py_INCREF(Py_False); + return (Py_False); +} + +static PyObject * +pyscf_get_int(PyObject *o, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", NULL }; + scf_simple_prop_t *prop; + PyObject *obj; + int64_t *val; + char *name; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) + return (NULL); + + prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name); + + if (prop == NULL) + return (scf_exception("scf_simple_prop_get() failed", name)); + + if ((val = scf_simple_prop_next_integer(prop)) == NULL) + return (scf_exception("scf_simple_prop_next_integer() failed", + name)); + + obj = PyInt_FromLong((long)*val); + scf_simple_prop_free(prop); + return (obj); +} + +static PyObject * +pyscf_get_string(PyObject *o, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", NULL }; + scf_simple_prop_t *prop; + PyObject *obj; + char *name; + char *str; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) + return (NULL); + + prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name); + + if (prop == NULL) + return (scf_exception("scf_simple_prop_get() failed", name)); + + if ((str = scf_simple_prop_next_astring(prop)) == NULL) { + scf_simple_prop_free(prop); + return (scf_exception("scf_simple_prop_next_astring() failed", + name)); + } + + obj = PyString_FromString(str); + scf_simple_prop_free(prop); + return (obj); +} + +PyDoc_STRVAR(pyscf_get_bool__doc__, + "get_bool(name) - get the value of the named boolean property"); +PyDoc_STRVAR(pyscf_get_int__doc__, + "get_int(name) - get the value of the named integer property"); +PyDoc_STRVAR(pyscf_get_string__doc__, + "get_string(name) - get the value of the named string property"); + +static struct PyMethodDef pyscf_module_methods[] = { + { "get_bool", (PyCFunction) pyscf_get_bool, + METH_VARARGS|METH_KEYWORDS, pyscf_get_bool__doc__ }, + { "get_int", (PyCFunction) pyscf_get_int, + METH_VARARGS|METH_KEYWORDS, pyscf_get_int__doc__ }, + { "get_string", (PyCFunction) pyscf_get_string, + METH_VARARGS|METH_KEYWORDS, pyscf_get_string__doc__ }, + { NULL, NULL, 0, NULL } +}; + +PyMODINIT_FUNC +initscf(void) +{ + PyObject *m; + m = Py_InitModule("scf", pyscf_module_methods); + + scf_exc = PyErr_NewException("scf.error", NULL, NULL); + Py_INCREF(scf_exc); + PyModule_AddObject(m, "error", scf_exc); + PyModule_AddIntConstant(m, "SCF_ERROR_NOT_FOUND", SCF_ERROR_NOT_FOUND); +} diff --git a/tools/python/xen/xend/Vifctl.py b/tools/python/xen/xend/Vifctl.py --- a/tools/python/xen/xend/Vifctl.py +++ b/tools/python/xen/xend/Vifctl.py @@ -20,7 +20,7 @@ """ import os -import XendRoot +import XendOptions def network(op): @@ -30,7 +30,7 @@ def network(op): """ if op not in [''start'', ''stop'']: raise ValueError(''Invalid operation: '' + op) - script = XendRoot.instance().get_network_script() + script = XendOptions.instance().get_network_script() if script: script.insert(1, op) os.spawnv(os.P_WAIT, script[0], script) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -32,7 +32,7 @@ import xen.lowlevel.xc import xen.lowlevel.xc -from xen.xend import XendRoot, XendCheckpoint, XendDomainInfo +from xen.xend import XendOptions, XendCheckpoint, XendDomainInfo from xen.xend.PrettyPrint import prettyprint from xen.xend.XendConfig import XendConfig from xen.xend.XendError import XendError, XendInvalidDomain, VmError @@ -51,7 +51,7 @@ from xen.xend import uuid from xen.xend import uuid xc = xen.lowlevel.xc.xc() -xroot = XendRoot.instance() +xoptions = XendOptions.instance() __all__ = [ "XendDomain" ] @@ -214,7 +214,7 @@ class XendDomain: @rtype: String @return: Path. """ - dom_path = xroot.get_xend_domains_path() + dom_path = xoptions.get_xend_domains_path() if domuuid: dom_path = os.path.join(dom_path, domuuid) return dom_path @@ -361,7 +361,7 @@ class XendDomain: def _setDom0CPUCount(self): """Sets the number of VCPUs dom0 has. Retreived from the - Xend configuration, L{XendRoot}. + Xend configuration, L{XendOptions}. @requires: Expects to be protected by domains_lock. @rtype: None @@ -369,7 +369,7 @@ class XendDomain: dom0 = self.privilegedDomain() # get max number of vcpus to use for dom0 from config - target = int(xroot.get_dom0_vcpus()) + target = int(xoptions.get_dom0_vcpus()) log.debug("number of vcpus to use is %d", target) # target == 0 means use all processors @@ -1154,7 +1154,7 @@ class XendDomain: dominfo.checkLiveMigrateMemory() if port == 0: - port = xroot.get_xend_relocation_port() + port = xoptions.get_xend_relocation_port() try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((dst, port)) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -38,7 +38,7 @@ from xen.util import security from xen.util import security from xen.xend import balloon, sxp, uuid, image, arch -from xen.xend import XendRoot, XendNode, XendConfig +from xen.xend import XendOptions, XendNode, XendConfig from xen.xend.XendConfig import scrub_password from xen.xend.XendBootloader import bootloader @@ -54,7 +54,7 @@ BOOTLOADER_LOOPBACK_DEVICE = ''/dev/xvdp'' BOOTLOADER_LOOPBACK_DEVICE = ''/dev/xvdp'' xc = xen.lowlevel.xc.xc() -xroot = XendRoot.instance() +xoptions = XendOptions.instance() log = logging.getLogger("xend.XendDomainInfo") #log.setLevel(logging.TRACE) @@ -734,7 +734,7 @@ class XendDomainInfo: ''domid'': str(self.domid), ''vm'': self.vmpath, ''name'': self.info[''name_label''], - ''console/limit'': str(xroot.get_console_limit() * 1024), + ''console/limit'': str(xoptions.get_console_limit() * 1024), ''memory/target'': str(self.info[''memory_static_min''] * 1024) } @@ -970,7 +970,7 @@ class XendDomainInfo: log.warn(''Domain has crashed: name=%s id=%d.'', self.info[''name_label''], self.domid) - if xroot.get_enable_dump(): + if xoptions.get_enable_dump(): self.dumpCore() restart_reason = ''crash'' diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -21,7 +21,7 @@ import xen.lowlevel.xc import xen.lowlevel.xc from xen.xend import uuid from xen.xend.XendError import XendError -from xen.xend.XendRoot import instance as xendroot +from xen.xend.XendOptions import instance as xendoptions from xen.xend.XendStorageRepository import XendStorageRepository from xen.xend.XendLogging import log from xen.xend.XendPIF import * @@ -42,7 +42,7 @@ class XendNode: """ self.xc = xen.lowlevel.xc.xc() - self.state_store = XendStateStore(xendroot().get_xend_state_path()) + self.state_store = XendStateStore(xendoptions().get_xend_state_path()) # load host state from XML file saved_host = self.state_store.load_state(''host'') diff --git a/tools/python/xen/xend/XendOptions.py b/tools/python/xen/xend/XendOptions.py new file mode 100644 --- /dev/null +++ b/tools/python/xen/xend/XendOptions.py @@ -0,0 +1,367 @@ +#===========================================================================+# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#===========================================================================+# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> +# Copyright (C) 2005 XenSource Ltd +#===========================================================================+ +"""Xend root class. +Creates the servers and handles configuration. + +Other classes get config variables by importing this module, +using instance() to get a XendOptions instance, and then +the config functions (e.g. get_xend_port()) to get +configured values. +""" + +import os +import os.path +import string +import sys + +from xen.xend import sxp, osdep, XendLogging +from xen.xend.XendError import XendError + +if os.uname()[0] == ''SunOS'': + from xen.lowlevel import scf + +class XendOptions: + """Root of the management classes.""" + + """Where network control scripts live.""" + network_script_dir = osdep.scripts_dir + + """Where block control scripts live.""" + block_script_dir = osdep.scripts_dir + + """Default path to the log file. """ + logfile_default = "/var/log/xen/xend.log" + + """Default level of information to be logged.""" + loglevel_default = ''DEBUG'' + + """Default Xen-API server configuration. """ + xen_api_server_default = [[''unix'']] + + """Default for the flag indicating whether xend should run an http server + (deprecated).""" + xend_http_server_default = ''no'' + + xend_tcp_xmlrpc_server_default = ''no'' + + xend_unix_xmlrpc_server_default = ''yes'' + + """Default interface address xend listens at. """ + xend_address_default = '''' + + """Default for the flag indicating whether xend should run a relocation server.""" + xend_relocation_server_default = ''no'' + + """Default interface address the xend relocation server listens at. """ + xend_relocation_address_default = '''' + + """Default port xend serves HTTP at. """ + xend_port_default = 8000 + + """Default port xend serves relocation at. """ + xend_relocation_port_default = 8002 + + xend_relocation_hosts_allow_default = '''' + + """Default for the flag indicating whether xend should run a unix-domain + server (deprecated).""" + xend_unix_server_default = ''no'' + + """Default external migration tool """ + external_migration_tool_default = '''' + + """Default path the unix-domain server listens at.""" + xend_unix_path_default = ''/var/lib/xend/xend-socket'' + + dom0_min_mem_default = 0 + + dom0_vcpus_default = 0 + + vncpasswd_default = None + + """Default interface to listen for VNC connections on""" + xend_vnc_listen_default = ''127.0.0.1'' + + """Default session storage path.""" + xend_domains_path_default = ''/var/lib/xend/domains'' + + """Default xend management state storage.""" + xend_state_path_default = ''/var/lib/xend/state'' + + def __init__(self): + self.configure() + + def _logError(self, fmt, *args): + """Logging function to log to stderr. We use this for XendOptions log + messages because they may be logged before the logger has been + configured. Other components can safely use the logger. + """ + print >>sys.stderr, "xend [ERROR]", fmt % args + + + def configure(self): + self.set_config() + XendLogging.init(self.get_config_string("logfile", + self.logfile_default), + self.get_config_string("loglevel", + self.loglevel_default)) + + def set_config(self): + raise NotImplementedError() + + def get_config_bool(self, name, val=None): + raise NotImplementedError() + + def get_config_int(self, name, val=None): + raise NotImplementedError() + + def get_config_string(self, name, val=None): + raise NotImplementedError() + + def get_xen_api_server(self): + raise NotImplementedError() + + def get_xend_http_server(self): + """Get the flag indicating whether xend should run an http server. + """ + return self.get_config_bool("xend-http-server", self.xend_http_server_default) + + def get_xend_tcp_xmlrpc_server(self): + return self.get_config_bool("xend-tcp-xmlrpc-server", + self.xend_tcp_xmlrpc_server_default) + + def get_xend_unix_xmlrpc_server(self): + return self.get_config_bool("xend-unix-xmlrpc-server", + self.xend_unix_xmlrpc_server_default) + + def get_xend_relocation_server(self): + """Get the flag indicating whether xend should run a relocation server. + """ + return self.get_config_bool("xend-relocation-server", + self.xend_relocation_server_default) + + def get_xend_port(self): + """Get the port xend listens at for its HTTP interface. + """ + return self.get_config_int(''xend-port'', self.xend_port_default) + + def get_xend_relocation_port(self): + """Get the port xend listens at for connection to its relocation server. + """ + return self.get_config_int(''xend-relocation-port'', + self.xend_relocation_port_default) + + def get_xend_relocation_hosts_allow(self): + return self.get_config_string("xend-relocation-hosts-allow", + self.xend_relocation_hosts_allow_default) + + def get_xend_address(self): + """Get the address xend listens at for its HTTP port. + 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 port. + """ + return self.get_config_string(''xend-address'', self.xend_address_default) + + def get_xend_relocation_address(self): + """Get the address xend listens at for its relocation server port. + 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 relocation port. + """ + return self.get_config_string(''xend-relocation-address'', self.xend_relocation_address_default) + + def get_xend_unix_server(self): + """Get the flag indicating whether xend should run a unix-domain server. + """ + return self.get_config_bool("xend-unix-server", self.xend_unix_server_default) + + def get_xend_unix_path(self): + """Get the path the xend unix-domain server listens at. + """ + return self.get_config_string("xend-unix-path", self.xend_unix_path_default) + + def get_xend_domains_path(self): + """ Get the path for persistent domain configuration storage + """ + return self.get_config_string("xend-domains-path", self.xend_domains_path_default) + + def get_xend_state_path(self): + """ Get the path for persistent domain configuration storage + """ + return self.get_config_string("xend-state-path", self.xend_state_path_default) + + def get_network_script(self): + """@return the script used to alter the network configuration when + Xend starts and stops, or None if no such script is specified.""" + + s = self.get_config_string(''network-script'') + + if s: + result = s.split(" ") + result[0] = os.path.join(self.network_script_dir, result[0]) + return result + else: + return None + + def get_external_migration_tool(self): + """@return the name of the tool to handle virtual TPM migration.""" + return self.get_config_string(''external-migration-tool'', self.external_migration_tool_default) + + def get_enable_dump(self): + return self.get_config_bool(''enable-dump'', ''no'') + + def get_vif_script(self): + return self.get_config_string(''vif-script'', ''vif-bridge'') + + def get_dom0_min_mem(self): + return self.get_config_int(''dom0-min-mem'', self.dom0_min_mem_default) + + def get_dom0_vcpus(self): + return self.get_config_int(''dom0-cpus'', self.dom0_vcpus_default) + + def get_console_limit(self): + return self.get_config_int(''console-limit'', 1024) + + def get_vnclisten_address(self): + return self.get_config_string(''vnc-listen'', self.xend_vnc_listen_default) + + def get_vncpasswd_default(self): + return self.get_config_string(''vncpasswd'', + self.vncpasswd_default) + +class XendOptionsFile(XendOptions): + + """Default path to the config file.""" + config_default = "/etc/xen/xend-config.sxp" + + """Environment variable used to override config_default.""" + config_var = "XEND_CONFIG" + + def set_config(self): + """If the config file exists, read it. If not, ignore it. + + The config file is a sequence of sxp forms. + """ + self.config_path = os.getenv(self.config_var, self.config_default) + if os.path.exists(self.config_path): + try: + fin = file(self.config_path, ''rb'') + try: + config = sxp.parse(fin) + finally: + fin.close() + if config is None: + config = [''xend-config''] + else: + config.insert(0, ''xend-config'') + self.config = config + 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_value(self, name, val=None): + """Get the value of an atomic configuration element. + + @param name: element name + @param val: default value (optional, defaults to None) + @return: value + """ + return sxp.child_value(self.config, name, val=val) + + def get_config_bool(self, name, val=None): + v = string.lower(str(self.get_config_value(name, val))) + if v in [''yes'', ''y'', ''1'', ''on'', ''true'', ''t'']: + return True + if v in [''no'', ''n'', ''0'', ''off'', ''false'', ''f'']: + return False + raise XendError("invalid xend config %s: expected bool: %s" % (name, v)) + + def get_config_int(self, name, val=None): + v = self.get_config_value(name, val) + try: + return int(v) + except Exception: + raise XendError("invalid xend config %s: expected int: %s" % (name, v)) + + def get_config_string(self, name, val=None): + return get_config_value(self, name, val) + + def get_xen_api_server(self): + """Get the Xen-API server configuration. + """ + return self.get_config_value(''xen-api-server'', + self.xen_api_server_default) + +if os.uname()[0] == ''SunOS'': + class XendOptionsSMF(XendOptions): + + def set_config(self): + pass + + def get_config_bool(self, name, val=None): + try: + return scf.get_bool(name) + except scf.error, e: + if e[0] == scf.SCF_ERROR_NOT_FOUND: + return val + else: + raise XendError("option %s: %s:%s" % (name, e[1], e[2])) + + def get_config_int(self, name, val=None): + try: + return scf.get_int(name) + except scf.error, e: + if e[0] == scf.SCF_ERROR_NOT_FOUND: + return val + else: + raise XendError("option %s: %s:%s" % (name, e[1], e[2])) + + def get_config_string(self, name, val=None): + try: + return scf.get_string(name) + except scf.error, e: + if e[0] == scf.SCF_ERROR_NOT_FOUND: + return val + else: + raise XendError("option %s: %s:%s" % (name, e[1], e[2])) + + def get_xen_api_server(self): + # When the new server is a supported configuration, we should + # expand this. + return [["unix"]] + +def instance(): + """Get an instance of XendOptions. + Use this instead of the constructor. + """ + global inst + try: + inst + except: + if os.uname()[0] == ''SunOS'': + inst = XendOptionsSMF() + else: + inst = XendOptionsFile() + return inst diff --git a/tools/python/xen/xend/XendPIF.py b/tools/python/xen/xend/XendPIF.py --- a/tools/python/xen/xend/XendPIF.py +++ b/tools/python/xen/xend/XendPIF.py @@ -20,7 +20,6 @@ import re import re import socket -from xen.xend.XendRoot import instance as xendroot from xen.xend.XendLogging import log MAC_RE = '':''.join([''[0-9a-f]{2}''] * 6) diff --git a/tools/python/xen/xend/XendProtocol.py b/tools/python/xen/xend/XendProtocol.py --- a/tools/python/xen/xend/XendProtocol.py +++ b/tools/python/xen/xend/XendProtocol.py @@ -24,7 +24,7 @@ from encode import * from encode import * from xen.xend import sxp -from xen.xend import XendRoot +from xen.xend import XendOptions DEBUG = 0 @@ -34,7 +34,7 @@ HTTP_NO_CONTENT = 2 HTTP_NO_CONTENT = 204 -xroot = XendRoot.instance() +xoptions = XendOptions.instance() class XendError(RuntimeError): @@ -218,7 +218,7 @@ class UnixXendClientProtocol(HttpXendCli def __init__(self, path=None): if path is None: - path = xroot.get_xend_unix_path() + path = xoptions.get_xend_unix_path() self.path = path def makeConnection(self, _): diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py deleted file mode 100644 --- a/tools/python/xen/xend/XendRoot.py +++ /dev/null @@ -1,322 +0,0 @@ -#===========================================================================-# This library is free software; you can redistribute it and/or -# modify it under the terms of version 2.1 of the GNU Lesser General Public -# License as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#===========================================================================-# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> -# Copyright (C) 2005 XenSource Ltd -#===========================================================================- -"""Xend root class. -Creates the servers 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 -import os.path -import string -import sys - -from xen.xend import sxp, osdep, XendLogging -from xen.xend.XendError import XendError - -class XendRoot: - """Root of the management classes.""" - - """Default path to the config file.""" - config_default = "/etc/xen/xend-config.sxp" - - """Environment variable used to override config_default.""" - config_var = "XEND_CONFIG" - - """Where network control scripts live.""" - network_script_dir = osdep.scripts_dir - - """Where block control scripts live.""" - block_script_dir = osdep.scripts_dir - - """Default path to the log file. """ - logfile_default = "/var/log/xen/xend.log" - - """Default level of information to be logged.""" - loglevel_default = ''DEBUG'' - - """Default Xen-API server configuration. """ - xen_api_server_default = [[''unix'']] - - """Default for the flag indicating whether xend should run an http server - (deprecated).""" - xend_http_server_default = ''no'' - - xend_tcp_xmlrpc_server_default = ''no'' - - xend_unix_xmlrpc_server_default = ''yes'' - - """Default interface address xend listens at. """ - xend_address_default = '''' - - """Default for the flag indicating whether xend should run a relocation server.""" - xend_relocation_server_default = ''no'' - - """Default interface address the xend relocation server listens at. """ - xend_relocation_address_default = '''' - - """Default port xend serves HTTP at. """ - xend_port_default = ''8000'' - - """Default port xend serves relocation at. """ - xend_relocation_port_default = ''8002'' - - xend_relocation_hosts_allow_default = '''' - - """Default for the flag indicating whether xend should run a unix-domain - server (deprecated).""" - xend_unix_server_default = ''no'' - - """Default external migration tool """ - external_migration_tool_default = '''' - - """Default path the unix-domain server listens at.""" - xend_unix_path_default = ''/var/lib/xend/xend-socket'' - - dom0_min_mem_default = ''0'' - - dom0_vcpus_default = ''0'' - - vncpasswd_default = None - - """Default interface to listen for VNC connections on""" - xend_vnc_listen_default = ''127.0.0.1'' - - """Default session storage path.""" - xend_domains_path_default = ''/var/lib/xend/domains'' - - """Default xend management state storage.""" - xend_state_path_default = ''/var/lib/xend/state'' - - components = {} - - def __init__(self): - self.config_path = None - self.config = None - self.configure() - - - def _logError(self, fmt, *args): - """Logging function to log to stderr. We use this for XendRoot log - messages because they may be logged before the logger has been - configured. Other components can safely use the logger. - """ - print >>sys.stderr, "xend [ERROR]", fmt % args - - - def configure(self): - self.set_config() - XendLogging.init(self.get_config_value("logfile", - self.logfile_default), - self.get_config_value("loglevel", - self.loglevel_default)) - - - def set_config(self): - """If the config file exists, read it. If not, ignore it. - - The config file is a sequence of sxp forms. - """ - self.config_path = os.getenv(self.config_var, self.config_default) - if os.path.exists(self.config_path): - try: - fin = file(self.config_path, ''rb'') - try: - config = sxp.parse(fin) - finally: - fin.close() - if config is None: - config = [''xend-config''] - else: - config.insert(0, ''xend-config'') - self.config = config - 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): - """Get the configuration element with the given name, or - the whole configuration if no name is given. - - @param name: element name (optional) - @return: config or none - """ - if name is None: - val = self.config - else: - val = sxp.child(self.config, name) - return val - - def get_config_value(self, name, val=None): - """Get the value of an atomic configuration element. - - @param name: element name - @param val: default value (optional, defaults to None) - @return: value - """ - return sxp.child_value(self.config, name, val=val) - - def get_config_bool(self, name, val=None): - v = string.lower(str(self.get_config_value(name, val))) - if v in [''yes'', ''y'', ''1'', ''on'', ''true'', ''t'']: - return True - if v in [''no'', ''n'', ''0'', ''off'', ''false'', ''f'']: - return False - raise XendError("invalid xend config %s: expected bool: %s" % (name, v)) - - def get_config_int(self, name, val=None): - v = self.get_config_value(name, val) - try: - return int(v) - except Exception: - raise XendError("invalid xend config %s: expected int: %s" % (name, v)) - - def get_xen_api_server(self): - """Get the Xen-API server configuration. - """ - return self.get_config_value(''xen-api-server'', - self.xen_api_server_default) - - def get_xend_http_server(self): - """Get the flag indicating whether xend should run an http server. - """ - return self.get_config_bool("xend-http-server", self.xend_http_server_default) - - def get_xend_tcp_xmlrpc_server(self): - return self.get_config_bool("xend-tcp-xmlrpc-server", - self.xend_tcp_xmlrpc_server_default) - - def get_xend_unix_xmlrpc_server(self): - return self.get_config_bool("xend-unix-xmlrpc-server", - self.xend_unix_xmlrpc_server_default) - - def get_xend_relocation_server(self): - """Get the flag indicating whether xend should run a relocation server. - """ - return self.get_config_bool("xend-relocation-server", - self.xend_relocation_server_default) - - def get_xend_port(self): - """Get the port xend listens at for its HTTP interface. - """ - return self.get_config_int(''xend-port'', self.xend_port_default) - - def get_xend_relocation_port(self): - """Get the port xend listens at for connection to its relocation server. - """ - return self.get_config_int(''xend-relocation-port'', - self.xend_relocation_port_default) - - def get_xend_relocation_hosts_allow(self): - return self.get_config_value("xend-relocation-hosts-allow", - self.xend_relocation_hosts_allow_default) - - def get_xend_address(self): - """Get the address xend listens at for its HTTP port. - 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 port. - """ - return self.get_config_value(''xend-address'', self.xend_address_default) - - def get_xend_relocation_address(self): - """Get the address xend listens at for its relocation server port. - 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 relocation port. - """ - return self.get_config_value(''xend-relocation-address'', self.xend_relocation_address_default) - - def get_xend_unix_server(self): - """Get the flag indicating whether xend should run a unix-domain server. - """ - return self.get_config_bool("xend-unix-server", self.xend_unix_server_default) - - def get_xend_unix_path(self): - """Get the path the xend unix-domain server listens at. - """ - return self.get_config_value("xend-unix-path", self.xend_unix_path_default) - - def get_xend_domains_path(self): - """ Get the path for persistent domain configuration storage - """ - return self.get_config_value("xend-domains-path", self.xend_domains_path_default) - - def get_xend_state_path(self): - """ Get the path for persistent domain configuration storage - """ - return self.get_config_value("xend-state-path", self.xend_state_path_default) - - def get_network_script(self): - """@return the script used to alter the network configuration when - Xend starts and stops, or None if no such script is specified.""" - - s = self.get_config_value(''network-script'') - - if s: - result = s.split(" ") - result[0] = os.path.join(self.network_script_dir, result[0]) - return result - else: - return None - - def get_external_migration_tool(self): - """@return the name of the tool to handle virtual TPM migration.""" - return self.get_config_value(''external-migration-tool'', self.external_migration_tool_default) - - def get_enable_dump(self): - return self.get_config_bool(''enable-dump'', ''no'') - - def get_vif_script(self): - return self.get_config_value(''vif-script'', ''vif-bridge'') - - def get_dom0_min_mem(self): - return self.get_config_int(''dom0-min-mem'', self.dom0_min_mem_default) - - def get_dom0_vcpus(self): - return self.get_config_int(''dom0-cpus'', self.dom0_vcpus_default) - - def get_console_limit(self): - return self.get_config_int(''console-limit'', 1024) - - def get_vnclisten_address(self): - return self.get_config_value(''vnc-listen'', self.xend_vnc_listen_default) - - def get_vncpasswd_default(self): - return self.get_config_value(''vncpasswd'', - self.vncpasswd_default) - -def instance(): - """Get an instance of XendRoot. - Use this instead of the constructor. - """ - global inst - try: - inst - except: - inst = XendRoot() - return inst diff --git a/tools/python/xen/xend/balloon.py b/tools/python/xen/xend/balloon.py --- a/tools/python/xen/xend/balloon.py +++ b/tools/python/xen/xend/balloon.py @@ -22,7 +22,7 @@ import xen.lowlevel.xc import xen.lowlevel.xc import XendDomain -import XendRoot +import XendOptions from XendLogging import log from XendError import VmError @@ -107,11 +107,11 @@ def free(need_mem): # usage, so we recheck the required alloc each time around the loop, but # track the last used value so that we don''t trigger too many watches. - xroot = XendRoot.instance() + xoptions = XendOptions.instance() xc = xen.lowlevel.xc.xc() try: - dom0_min_mem = xroot.get_dom0_min_mem() * 1024 + dom0_min_mem = xoptions.get_dom0_min_mem() * 1024 retries = 0 sleep_time = SLEEP_TIME_GROWTH diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -459,14 +459,14 @@ class HVMImageHandler(ImageHandler): vnclisten = imageConfig.get(''vnclisten'') if not(vnclisten): - vnclisten = (xen.xend.XendRoot.instance(). + vnclisten = (xen.xend.XendOptions.instance(). get_vnclisten_address()) if vnclisten: ret += [''-vnclisten'', vnclisten] vncpasswd = vncpasswd_vmconfig if vncpasswd is None: - vncpasswd = (xen.xend.XendRoot.instance(). + vncpasswd = (xen.xend.XendOptions.instance(). get_vncpasswd_default()) if vncpasswd is None: raise VmError(''vncpasswd is not set up in '' + diff --git a/tools/python/xen/xend/server/DevController.py b/tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py +++ b/tools/python/xen/xend/server/DevController.py @@ -19,7 +19,7 @@ from threading import Event from threading import Event import types -from xen.xend import sxp, XendRoot +from xen.xend import sxp, XendOptions from xen.xend.XendError import VmError from xen.xend.XendLogging import log @@ -50,7 +50,7 @@ xenbusState = { ''Closed'' : 6, } -xroot = XendRoot.instance() +xoptions = XendOptions.instance() xenbusState.update(dict(zip(xenbusState.values(), xenbusState.keys()))) @@ -324,7 +324,7 @@ class DevController: Make sure that the migration has finished and only then return from the call. """ - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool: log.info("Calling external migration tool for step %d" % step) fd = os.popen("%s -type %s -step %d -host %s -domname %s" % @@ -341,7 +341,7 @@ class DevController: """ Recover from device migration. The given step was the last one that was successfully executed. """ - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool: log.info("Calling external migration tool") fd = os.popen("%s -type %s -step %d -host %s -domname %s -recover" % diff --git a/tools/python/xen/xend/server/SrvRoot.py b/tools/python/xen/xend/server/SrvRoot.py --- a/tools/python/xen/xend/server/SrvRoot.py +++ b/tools/python/xen/xend/server/SrvRoot.py @@ -25,7 +25,7 @@ class SrvRoot(SrvDir): """Server sub-components. Each entry is (name, class), where ''name'' is the entry name and ''class'' is the name of its class. """ - #todo Get this list from the XendRoot config. + #todo Get this list from the XendOptions config. subdirs = [ (''node'', ''SrvNode'' ), (''domain'', ''SrvDomainDir'' ), diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -48,7 +48,7 @@ from threading import Thread from xen.web.httpserver import HttpServer, UnixHttpServer -from xen.xend import XendRoot, XendAPI +from xen.xend import XendOptions, XendAPI from xen.xend import Vifctl from xen.xend.XendLogging import log from xen.xend.XendClient import XEN_API_SOCKET @@ -57,7 +57,7 @@ from SrvRoot import SrvRoot from SrvRoot import SrvRoot from XMLRPCServer import XMLRPCServer -xroot = XendRoot.instance() +xoptions = XendOptions.instance() class XendServers: @@ -163,7 +163,7 @@ class XendServers: log.info("Restarting all XML-RPC and Xen-API servers...") self.cleaningUp = False self.reloadingConfig = False - xroot.set_config() + xoptions.set_config() new_servers = [x for x in self.servers if isinstance(x, HttpServer)] self.servers = new_servers @@ -172,16 +172,16 @@ class XendServers: break def _loadConfig(servers, root, reload): - if not reload and xroot.get_xend_http_server(): + if not reload and xoptions.get_xend_http_server(): servers.add(HttpServer(root, - xroot.get_xend_address(), - xroot.get_xend_port())) - if not reload and xroot.get_xend_unix_server(): - path = xroot.get_xend_unix_path() + xoptions.get_xend_address(), + xoptions.get_xend_port())) + if not reload and xoptions.get_xend_unix_server(): + path = xoptions.get_xend_unix_path() log.info(''unix path='' + path) servers.add(UnixHttpServer(root, path)) - api_cfg = xroot.get_xen_api_server() + api_cfg = xoptions.get_xen_api_server() if api_cfg: try: addrs = [(str(x[0]).split('':''), @@ -216,10 +216,10 @@ def _loadConfig(servers, root, reload): except TypeError, exn: log.error(''Xen-API server configuration %s is invalid.'', api_cfg) - if xroot.get_xend_tcp_xmlrpc_server(): + if xoptions.get_xend_tcp_xmlrpc_server(): servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, True)) - if xroot.get_xend_unix_xmlrpc_server(): + if xoptions.get_xend_unix_xmlrpc_server(): servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False)) diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -24,10 +24,10 @@ import random import random import re -from xen.xend import XendRoot +from xen.xend import XendOptions from xen.xend.server.DevController import DevController -xroot = XendRoot.instance() +xoptions = XendOptions.instance() def randomMAC(): """Generate a random MAC address. @@ -138,8 +138,8 @@ class NetifController(DevController): def getDeviceDetails(self, config): """@see DevController.getDeviceDetails""" - script = os.path.join(xroot.network_script_dir, - config.get(''script'', xroot.get_vif_script())) + script = os.path.join(xoptions.network_script_dir, + config.get(''script'', xoptions.get_vif_script())) typ = config.get(''type'') bridge = config.get(''bridge'') mac = config.get(''mac'') @@ -190,7 +190,7 @@ class NetifController(DevController): (script, ip, bridge, mac, typ, vifname, rate, uuid) = devinfo if script: - network_script_dir = xroot.network_script_dir + os.sep + network_script_dir = xoptions.network_script_dir + os.sep result[''script''] = script.replace(network_script_dir, "") if ip: result[''ip''] = ip diff --git a/tools/python/xen/xend/server/relocate.py b/tools/python/xen/xend/server/relocate.py --- a/tools/python/xen/xend/server/relocate.py +++ b/tools/python/xen/xend/server/relocate.py @@ -24,7 +24,7 @@ from xen.web import protocol, tcp, unix from xen.xend import sxp from xen.xend import XendDomain -from xen.xend import XendRoot +from xen.xend import XendOptions from xen.xend.XendError import XendError from xen.xend.XendLogging import log @@ -114,15 +114,15 @@ class RelocationProtocol(protocol.Protoc def listenRelocation(): - xroot = XendRoot.instance() - if xroot.get_xend_unix_server(): + xoptions = XendOptions.instance() + if xoptions.get_xend_unix_server(): path = ''/var/lib/xend/relocation-socket'' unix.UnixListener(path, RelocationProtocol) - if xroot.get_xend_relocation_server(): - port = xroot.get_xend_relocation_port() - interface = xroot.get_xend_relocation_address() + if xoptions.get_xend_relocation_server(): + port = xoptions.get_xend_relocation_port() + interface = xoptions.get_xend_relocation_address() - hosts_allow = xroot.get_xend_relocation_hosts_allow() + hosts_allow = xoptions.get_xend_relocation_hosts_allow() if hosts_allow == '''': hosts_allow = None else: diff --git a/tools/python/xen/xend/server/tests/test_controllers.py b/tools/python/xen/xend/server/tests/test_controllers.py --- a/tools/python/xen/xend/server/tests/test_controllers.py +++ b/tools/python/xen/xend/server/tests/test_controllers.py @@ -2,9 +2,9 @@ import re import re import unittest -import xen.xend.XendRoot +import xen.xend.XendOptions -xen.xend.XendRoot.XendRoot.config_default = ''/dev/null'' +xen.xend.XendOptions.XendOptions.config_default = ''/dev/null'' from xen.xend.server import netif @@ -13,7 +13,7 @@ FAKE_DEVID = 63 FAKE_DEVID = 63 -xroot = xen.xend.XendRoot.instance() +xoptions = xen.xend.XendOptions.instance() class test_controllers(unittest.TestCase): @@ -36,8 +36,8 @@ class test_controllers(unittest.TestCase self.assertEqual(backdets[''handle''], str(FAKE_DEVID)) self.assertEqual(backdets[''script''], - os.path.join(xroot.network_script_dir, - xroot.get_vif_script())) + os.path.join(xoptions.network_script_dir, + xoptions.get_vif_script())) self.assertValidMac(backdets[''mac''], expectedMac) self.assertEqual(frontdets[''handle''], str(FAKE_DEVID)) diff --git a/tools/python/xen/xend/server/tpmif.py b/tools/python/xen/xend/server/tpmif.py --- a/tools/python/xen/xend/server/tpmif.py +++ b/tools/python/xen/xend/server/tpmif.py @@ -20,7 +20,7 @@ """Support for virtual TPM interfaces.""" -from xen.xend import XendRoot +from xen.xend import XendOptions from xen.xend.XendLogging import log from xen.xend.XendError import XendError from xen.xend.XendConstants import DEV_MIGRATE_TEST, VTPM_DELETE_SCRIPT @@ -29,7 +29,7 @@ import os import os import re -xroot = XendRoot.instance() +xoptions = XendOptions.instance() def destroy_vtpmstate(name): if os.path.exists(VTPM_DELETE_SCRIPT): @@ -88,7 +88,7 @@ class TPMifController(DevController): def migrate(self, deviceConfig, network, dst, step, domName): """@see DevContoller.migrate""" if network: - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool != '''': log.info("Request to network-migrate device to %s. step=%d.", dst, step) @@ -116,7 +116,7 @@ class TPMifController(DevController): def recover_migrate(self, deviceConfig, network, dst, step, domName): """@see DevContoller.recover_migrate""" if network: - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool != '''': log.info("Request to recover network-migrated device. last good step=%d.", step) diff --git a/tools/python/xen/xend/server/vfbif.py b/tools/python/xen/xend/server/vfbif.py --- a/tools/python/xen/xend/server/vfbif.py +++ b/tools/python/xen/xend/server/vfbif.py @@ -52,7 +52,7 @@ class VfbifController(DevController): if config.has_key("vncpasswd"): passwd = config["vncpasswd"] else: - passwd = xen.xend.XendRoot.instance().get_vncpasswd_default() + passwd = xen.xend.XendOptions.instance().get_vncpasswd_default() if passwd: self.vm.storeVm("vncpasswd", passwd) log.debug("Stored a VNC password for vfb access") @@ -66,7 +66,7 @@ class VfbifController(DevController): elif config.has_key("vncdisplay"): args += ["--vncport", "%d" % (5900 + config["vncdisplay"])] vnclisten = config.get("vnclisten", - xen.xend.XendRoot.instance().get_vnclisten_address()) + xen.xend.XendOptions.instance().get_vnclisten_address()) args += [ "--listen", vnclisten ] spawn_detached(args[0], args + std_args, os.environ) elif t == "sdl": diff --git a/tools/python/xen/xm/tests/test_create.py b/tools/python/xen/xm/tests/test_create.py --- a/tools/python/xen/xm/tests/test_create.py +++ b/tools/python/xen/xm/tests/test_create.py @@ -3,9 +3,9 @@ import tempfile import tempfile import unittest -import xen.xend.XendRoot - -xen.xend.XendRoot.XendRoot.config_default = ''/dev/null'' +import xen.xend.XendOptions + +xen.xend.XendOptions.XendOptions.config_default = ''/dev/null'' import xen.xm.create _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
John Levon
2006-Dec-29 14:51 UTC
Re: [Xen-devel] [PATCH] Support xend configuration via Solaris SMF
Ooops, fixed patch. john # HG changeset patch # User john.levon@sun.com # Date 1167403005 28800 # Node ID a18e42ef75a880637414d697102f534f8653b61a # Parent 819689bd07959241a860c29c01bf7d8a259f00ff Enable xend to pick up properties from SMF on Solaris. Also rename XendRoot to the much clearer XendOptions. Signed-off-by: John Levon <john.levon@sun.com> diff --git a/tools/python/setup.py b/tools/python/setup.py --- a/tools/python/setup.py +++ b/tools/python/setup.py @@ -30,12 +30,23 @@ xs = Extension("xs", libraries = libraries, sources = [ "xen/lowlevel/xs/xs.c" ]) +scf = Extension("scf", + extra_compile_args = extra_compile_args, + include_dirs = include_dirs + [ "xen/lowlevel/scf" ], + library_dirs = library_dirs, + libraries = libraries, + sources = [ "xen/lowlevel/scf/scf.c" ]) + acm = Extension("acm", extra_compile_args = extra_compile_args, include_dirs = include_dirs + [ "xen/lowlevel/acm" ], library_dirs = library_dirs, libraries = libraries, sources = [ "xen/lowlevel/acm/acm.c" ]) + +modules = [ xc, xs, acm ] +if os.uname()[0] == ''SunOS'': + modules.append(scf) setup(name = ''xen'', version = ''3.0'', @@ -56,7 +67,7 @@ setup(name = ''xen'', ''xen.xm.tests'' ], ext_package = "xen.lowlevel", - ext_modules = [ xc, xs, acm ] + ext_modules = modules ) os.chdir(''logging'') diff --git a/tools/python/xen/lowlevel/scf/scf.c b/tools/python/xen/lowlevel/scf/scf.c new file mode 100644 --- /dev/null +++ b/tools/python/xen/lowlevel/scf/scf.c @@ -0,0 +1,156 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <Python.h> + +#include <libscf.h> +#include <stdio.h> + +#define XEND_FMRI "svc:/system/xen/xend:default" +#define XEND_PG "config" + +static PyObject *scf_exc; + +static void * +scf_exception(const char *err, const char *value) +{ + int scferr = scf_error(); + const char *scfstrerr = scf_strerror(scferr); + PyObject *obj = Py_BuildValue("(isss)", scferr, err, scfstrerr, value); + PyErr_SetObject(scf_exc, obj); + return (NULL); +} + +static PyObject * +pyscf_get_bool(PyObject *o, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", NULL }; + scf_simple_prop_t *prop; + uint8_t *val; + char *name; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) + return (NULL); + + prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name); + + if (prop == NULL) + return (scf_exception("scf_simple_prop_get() failed", name)); + + if ((val = scf_simple_prop_next_boolean(prop)) == NULL) + return (scf_exception("scf_simple_prop_next_boolean() failed", + name)); + + if (*val) { + scf_simple_prop_free(prop); + Py_INCREF(Py_True); + return (Py_True); + } + + scf_simple_prop_free(prop); + Py_INCREF(Py_False); + return (Py_False); +} + +static PyObject * +pyscf_get_int(PyObject *o, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", NULL }; + scf_simple_prop_t *prop; + PyObject *obj; + int64_t *val; + char *name; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) + return (NULL); + + prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name); + + if (prop == NULL) + return (scf_exception("scf_simple_prop_get() failed", name)); + + if ((val = scf_simple_prop_next_integer(prop)) == NULL) + return (scf_exception("scf_simple_prop_next_integer() failed", + name)); + + obj = PyInt_FromLong((long)*val); + scf_simple_prop_free(prop); + return (obj); +} + +static PyObject * +pyscf_get_string(PyObject *o, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = { "name", NULL }; + scf_simple_prop_t *prop; + PyObject *obj; + char *name; + char *str; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &name)) + return (NULL); + + prop = scf_simple_prop_get(NULL, XEND_FMRI, XEND_PG, name); + + if (prop == NULL) + return (scf_exception("scf_simple_prop_get() failed", name)); + + if ((str = scf_simple_prop_next_astring(prop)) == NULL) { + scf_simple_prop_free(prop); + return (scf_exception("scf_simple_prop_next_astring() failed", + name)); + } + + obj = PyString_FromString(str); + scf_simple_prop_free(prop); + return (obj); +} + +PyDoc_STRVAR(pyscf_get_bool__doc__, + "get_bool(name) - get the value of the named boolean property"); +PyDoc_STRVAR(pyscf_get_int__doc__, + "get_int(name) - get the value of the named integer property"); +PyDoc_STRVAR(pyscf_get_string__doc__, + "get_string(name) - get the value of the named string property"); + +static struct PyMethodDef pyscf_module_methods[] = { + { "get_bool", (PyCFunction) pyscf_get_bool, + METH_VARARGS|METH_KEYWORDS, pyscf_get_bool__doc__ }, + { "get_int", (PyCFunction) pyscf_get_int, + METH_VARARGS|METH_KEYWORDS, pyscf_get_int__doc__ }, + { "get_string", (PyCFunction) pyscf_get_string, + METH_VARARGS|METH_KEYWORDS, pyscf_get_string__doc__ }, + { NULL, NULL, 0, NULL } +}; + +PyMODINIT_FUNC +initscf(void) +{ + PyObject *m; + m = Py_InitModule("scf", pyscf_module_methods); + + scf_exc = PyErr_NewException("scf.error", NULL, NULL); + Py_INCREF(scf_exc); + PyModule_AddObject(m, "error", scf_exc); + PyModule_AddIntConstant(m, "SCF_ERROR_NOT_FOUND", SCF_ERROR_NOT_FOUND); +} diff --git a/tools/python/xen/xend/Vifctl.py b/tools/python/xen/xend/Vifctl.py --- a/tools/python/xen/xend/Vifctl.py +++ b/tools/python/xen/xend/Vifctl.py @@ -20,7 +20,7 @@ """ import os -import XendRoot +import XendOptions def network(op): @@ -30,7 +30,7 @@ def network(op): """ if op not in [''start'', ''stop'']: raise ValueError(''Invalid operation: '' + op) - script = XendRoot.instance().get_network_script() + script = XendOptions.instance().get_network_script() if script: script.insert(1, op) os.spawnv(os.P_WAIT, script[0], script) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -32,7 +32,7 @@ import xen.lowlevel.xc import xen.lowlevel.xc -from xen.xend import XendRoot, XendCheckpoint, XendDomainInfo +from xen.xend import XendOptions, XendCheckpoint, XendDomainInfo from xen.xend.PrettyPrint import prettyprint from xen.xend.XendConfig import XendConfig from xen.xend.XendError import XendError, XendInvalidDomain, VmError @@ -51,7 +51,7 @@ from xen.xend import uuid from xen.xend import uuid xc = xen.lowlevel.xc.xc() -xroot = XendRoot.instance() +xoptions = XendOptions.instance() __all__ = [ "XendDomain" ] @@ -214,7 +214,7 @@ class XendDomain: @rtype: String @return: Path. """ - dom_path = xroot.get_xend_domains_path() + dom_path = xoptions.get_xend_domains_path() if domuuid: dom_path = os.path.join(dom_path, domuuid) return dom_path @@ -361,7 +361,7 @@ class XendDomain: def _setDom0CPUCount(self): """Sets the number of VCPUs dom0 has. Retreived from the - Xend configuration, L{XendRoot}. + Xend configuration, L{XendOptions}. @requires: Expects to be protected by domains_lock. @rtype: None @@ -369,7 +369,7 @@ class XendDomain: dom0 = self.privilegedDomain() # get max number of vcpus to use for dom0 from config - target = int(xroot.get_dom0_vcpus()) + target = int(xoptions.get_dom0_vcpus()) log.debug("number of vcpus to use is %d", target) # target == 0 means use all processors @@ -1154,7 +1154,7 @@ class XendDomain: dominfo.checkLiveMigrateMemory() if port == 0: - port = xroot.get_xend_relocation_port() + port = xoptions.get_xend_relocation_port() try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((dst, port)) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -38,7 +38,7 @@ from xen.util import security from xen.util import security from xen.xend import balloon, sxp, uuid, image, arch -from xen.xend import XendRoot, XendNode, XendConfig +from xen.xend import XendOptions, XendNode, XendConfig from xen.xend.XendConfig import scrub_password from xen.xend.XendBootloader import bootloader @@ -54,7 +54,7 @@ BOOTLOADER_LOOPBACK_DEVICE = ''/dev/xvdp'' BOOTLOADER_LOOPBACK_DEVICE = ''/dev/xvdp'' xc = xen.lowlevel.xc.xc() -xroot = XendRoot.instance() +xoptions = XendOptions.instance() log = logging.getLogger("xend.XendDomainInfo") #log.setLevel(logging.TRACE) @@ -734,7 +734,7 @@ class XendDomainInfo: ''domid'': str(self.domid), ''vm'': self.vmpath, ''name'': self.info[''name_label''], - ''console/limit'': str(xroot.get_console_limit() * 1024), + ''console/limit'': str(xoptions.get_console_limit() * 1024), ''memory/target'': str(self.info[''memory_static_min''] * 1024) } @@ -970,7 +970,7 @@ class XendDomainInfo: log.warn(''Domain has crashed: name=%s id=%d.'', self.info[''name_label''], self.domid) - if xroot.get_enable_dump(): + if xoptions.get_enable_dump(): self.dumpCore() restart_reason = ''crash'' diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -21,7 +21,7 @@ import xen.lowlevel.xc import xen.lowlevel.xc from xen.xend import uuid from xen.xend.XendError import XendError -from xen.xend.XendRoot import instance as xendroot +from xen.xend.XendOptions import instance as xendoptions from xen.xend.XendStorageRepository import XendStorageRepository from xen.xend.XendLogging import log from xen.xend.XendPIF import * @@ -42,7 +42,7 @@ class XendNode: """ self.xc = xen.lowlevel.xc.xc() - self.state_store = XendStateStore(xendroot().get_xend_state_path()) + self.state_store = XendStateStore(xendoptions().get_xend_state_path()) # load host state from XML file saved_host = self.state_store.load_state(''host'') diff --git a/tools/python/xen/xend/XendOptions.py b/tools/python/xen/xend/XendOptions.py new file mode 100644 --- /dev/null +++ b/tools/python/xen/xend/XendOptions.py @@ -0,0 +1,367 @@ +#===========================================================================+# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#===========================================================================+# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> +# Copyright (C) 2005 XenSource Ltd +#===========================================================================+ +"""Xend root class. +Creates the servers and handles configuration. + +Other classes get config variables by importing this module, +using instance() to get a XendOptions instance, and then +the config functions (e.g. get_xend_port()) to get +configured values. +""" + +import os +import os.path +import string +import sys + +from xen.xend import sxp, osdep, XendLogging +from xen.xend.XendError import XendError + +if os.uname()[0] == ''SunOS'': + from xen.lowlevel import scf + +class XendOptions: + """Root of the management classes.""" + + """Where network control scripts live.""" + network_script_dir = osdep.scripts_dir + + """Where block control scripts live.""" + block_script_dir = osdep.scripts_dir + + """Default path to the log file. """ + logfile_default = "/var/log/xen/xend.log" + + """Default level of information to be logged.""" + loglevel_default = ''DEBUG'' + + """Default Xen-API server configuration. """ + xen_api_server_default = [[''unix'']] + + """Default for the flag indicating whether xend should run an http server + (deprecated).""" + xend_http_server_default = ''no'' + + xend_tcp_xmlrpc_server_default = ''no'' + + xend_unix_xmlrpc_server_default = ''yes'' + + """Default interface address xend listens at. """ + xend_address_default = '''' + + """Default for the flag indicating whether xend should run a relocation server.""" + xend_relocation_server_default = ''no'' + + """Default interface address the xend relocation server listens at. """ + xend_relocation_address_default = '''' + + """Default port xend serves HTTP at. """ + xend_port_default = 8000 + + """Default port xend serves relocation at. """ + xend_relocation_port_default = 8002 + + xend_relocation_hosts_allow_default = '''' + + """Default for the flag indicating whether xend should run a unix-domain + server (deprecated).""" + xend_unix_server_default = ''no'' + + """Default external migration tool """ + external_migration_tool_default = '''' + + """Default path the unix-domain server listens at.""" + xend_unix_path_default = ''/var/lib/xend/xend-socket'' + + dom0_min_mem_default = 0 + + dom0_vcpus_default = 0 + + vncpasswd_default = None + + """Default interface to listen for VNC connections on""" + xend_vnc_listen_default = ''127.0.0.1'' + + """Default session storage path.""" + xend_domains_path_default = ''/var/lib/xend/domains'' + + """Default xend management state storage.""" + xend_state_path_default = ''/var/lib/xend/state'' + + def __init__(self): + self.configure() + + def _logError(self, fmt, *args): + """Logging function to log to stderr. We use this for XendOptions log + messages because they may be logged before the logger has been + configured. Other components can safely use the logger. + """ + print >>sys.stderr, "xend [ERROR]", fmt % args + + + def configure(self): + self.set_config() + XendLogging.init(self.get_config_string("logfile", + self.logfile_default), + self.get_config_string("loglevel", + self.loglevel_default)) + + def set_config(self): + raise NotImplementedError() + + def get_config_bool(self, name, val=None): + raise NotImplementedError() + + def get_config_int(self, name, val=None): + raise NotImplementedError() + + def get_config_string(self, name, val=None): + raise NotImplementedError() + + def get_xen_api_server(self): + raise NotImplementedError() + + def get_xend_http_server(self): + """Get the flag indicating whether xend should run an http server. + """ + return self.get_config_bool("xend-http-server", self.xend_http_server_default) + + def get_xend_tcp_xmlrpc_server(self): + return self.get_config_bool("xend-tcp-xmlrpc-server", + self.xend_tcp_xmlrpc_server_default) + + def get_xend_unix_xmlrpc_server(self): + return self.get_config_bool("xend-unix-xmlrpc-server", + self.xend_unix_xmlrpc_server_default) + + def get_xend_relocation_server(self): + """Get the flag indicating whether xend should run a relocation server. + """ + return self.get_config_bool("xend-relocation-server", + self.xend_relocation_server_default) + + def get_xend_port(self): + """Get the port xend listens at for its HTTP interface. + """ + return self.get_config_int(''xend-port'', self.xend_port_default) + + def get_xend_relocation_port(self): + """Get the port xend listens at for connection to its relocation server. + """ + return self.get_config_int(''xend-relocation-port'', + self.xend_relocation_port_default) + + def get_xend_relocation_hosts_allow(self): + return self.get_config_string("xend-relocation-hosts-allow", + self.xend_relocation_hosts_allow_default) + + def get_xend_address(self): + """Get the address xend listens at for its HTTP port. + 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 port. + """ + return self.get_config_string(''xend-address'', self.xend_address_default) + + def get_xend_relocation_address(self): + """Get the address xend listens at for its relocation server port. + 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 relocation port. + """ + return self.get_config_string(''xend-relocation-address'', self.xend_relocation_address_default) + + def get_xend_unix_server(self): + """Get the flag indicating whether xend should run a unix-domain server. + """ + return self.get_config_bool("xend-unix-server", self.xend_unix_server_default) + + def get_xend_unix_path(self): + """Get the path the xend unix-domain server listens at. + """ + return self.get_config_string("xend-unix-path", self.xend_unix_path_default) + + def get_xend_domains_path(self): + """ Get the path for persistent domain configuration storage + """ + return self.get_config_string("xend-domains-path", self.xend_domains_path_default) + + def get_xend_state_path(self): + """ Get the path for persistent domain configuration storage + """ + return self.get_config_string("xend-state-path", self.xend_state_path_default) + + def get_network_script(self): + """@return the script used to alter the network configuration when + Xend starts and stops, or None if no such script is specified.""" + + s = self.get_config_string(''network-script'') + + if s: + result = s.split(" ") + result[0] = os.path.join(self.network_script_dir, result[0]) + return result + else: + return None + + def get_external_migration_tool(self): + """@return the name of the tool to handle virtual TPM migration.""" + return self.get_config_string(''external-migration-tool'', self.external_migration_tool_default) + + def get_enable_dump(self): + return self.get_config_bool(''enable-dump'', ''no'') + + def get_vif_script(self): + return self.get_config_string(''vif-script'', ''vif-bridge'') + + def get_dom0_min_mem(self): + return self.get_config_int(''dom0-min-mem'', self.dom0_min_mem_default) + + def get_dom0_vcpus(self): + return self.get_config_int(''dom0-cpus'', self.dom0_vcpus_default) + + def get_console_limit(self): + return self.get_config_int(''console-limit'', 1024) + + def get_vnclisten_address(self): + return self.get_config_string(''vnc-listen'', self.xend_vnc_listen_default) + + def get_vncpasswd_default(self): + return self.get_config_string(''vncpasswd'', + self.vncpasswd_default) + +class XendOptionsFile(XendOptions): + + """Default path to the config file.""" + config_default = "/etc/xen/xend-config.sxp" + + """Environment variable used to override config_default.""" + config_var = "XEND_CONFIG" + + def set_config(self): + """If the config file exists, read it. If not, ignore it. + + The config file is a sequence of sxp forms. + """ + self.config_path = os.getenv(self.config_var, self.config_default) + if os.path.exists(self.config_path): + try: + fin = file(self.config_path, ''rb'') + try: + config = sxp.parse(fin) + finally: + fin.close() + if config is None: + config = [''xend-config''] + else: + config.insert(0, ''xend-config'') + self.config = config + 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_value(self, name, val=None): + """Get the value of an atomic configuration element. + + @param name: element name + @param val: default value (optional, defaults to None) + @return: value + """ + return sxp.child_value(self.config, name, val=val) + + def get_config_bool(self, name, val=None): + v = string.lower(str(self.get_config_value(name, val))) + if v in [''yes'', ''y'', ''1'', ''on'', ''true'', ''t'']: + return True + if v in [''no'', ''n'', ''0'', ''off'', ''false'', ''f'']: + return False + raise XendError("invalid xend config %s: expected bool: %s" % (name, v)) + + def get_config_int(self, name, val=None): + v = self.get_config_value(name, val) + try: + return int(v) + except Exception: + raise XendError("invalid xend config %s: expected int: %s" % (name, v)) + + def get_config_string(self, name, val=None): + return get_config_value(self, name, val) + + def get_xen_api_server(self): + """Get the Xen-API server configuration. + """ + return self.get_config_value(''xen-api-server'', + self.xen_api_server_default) + +if os.uname()[0] == ''SunOS'': + class XendOptionsSMF(XendOptions): + + def set_config(self): + pass + + def get_config_bool(self, name, val=None): + try: + return scf.get_bool(name) + except scf.error, e: + if e[0] == scf.SCF_ERROR_NOT_FOUND: + return val + else: + raise XendError("option %s: %s:%s" % (name, e[1], e[2])) + + def get_config_int(self, name, val=None): + try: + return scf.get_int(name) + except scf.error, e: + if e[0] == scf.SCF_ERROR_NOT_FOUND: + return val + else: + raise XendError("option %s: %s:%s" % (name, e[1], e[2])) + + def get_config_string(self, name, val=None): + try: + return scf.get_string(name) + except scf.error, e: + if e[0] == scf.SCF_ERROR_NOT_FOUND: + return val + else: + raise XendError("option %s: %s:%s" % (name, e[1], e[2])) + + def get_xen_api_server(self): + # When the new server is a supported configuration, we should + # expand this. + return [["unix"]] + +def instance(): + """Get an instance of XendOptions. + Use this instead of the constructor. + """ + global inst + try: + inst + except: + if os.uname()[0] == ''SunOS'': + inst = XendOptionsSMF() + else: + inst = XendOptionsFile() + return inst diff --git a/tools/python/xen/xend/XendPIF.py b/tools/python/xen/xend/XendPIF.py --- a/tools/python/xen/xend/XendPIF.py +++ b/tools/python/xen/xend/XendPIF.py @@ -20,7 +20,6 @@ import re import re import socket -from xen.xend.XendRoot import instance as xendroot from xen.xend.XendLogging import log MAC_RE = '':''.join([''[0-9a-f]{2}''] * 6) diff --git a/tools/python/xen/xend/XendProtocol.py b/tools/python/xen/xend/XendProtocol.py --- a/tools/python/xen/xend/XendProtocol.py +++ b/tools/python/xen/xend/XendProtocol.py @@ -24,7 +24,7 @@ from encode import * from encode import * from xen.xend import sxp -from xen.xend import XendRoot +from xen.xend import XendOptions DEBUG = 0 @@ -34,7 +34,7 @@ HTTP_NO_CONTENT = 2 HTTP_NO_CONTENT = 204 -xroot = XendRoot.instance() +xoptions = XendOptions.instance() class XendError(RuntimeError): @@ -218,7 +218,7 @@ class UnixXendClientProtocol(HttpXendCli def __init__(self, path=None): if path is None: - path = xroot.get_xend_unix_path() + path = xoptions.get_xend_unix_path() self.path = path def makeConnection(self, _): diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py deleted file mode 100644 --- a/tools/python/xen/xend/XendRoot.py +++ /dev/null @@ -1,322 +0,0 @@ -#===========================================================================-# This library is free software; you can redistribute it and/or -# modify it under the terms of version 2.1 of the GNU Lesser General Public -# License as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -#===========================================================================-# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com> -# Copyright (C) 2005 XenSource Ltd -#===========================================================================- -"""Xend root class. -Creates the servers 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 -import os.path -import string -import sys - -from xen.xend import sxp, osdep, XendLogging -from xen.xend.XendError import XendError - -class XendRoot: - """Root of the management classes.""" - - """Default path to the config file.""" - config_default = "/etc/xen/xend-config.sxp" - - """Environment variable used to override config_default.""" - config_var = "XEND_CONFIG" - - """Where network control scripts live.""" - network_script_dir = osdep.scripts_dir - - """Where block control scripts live.""" - block_script_dir = osdep.scripts_dir - - """Default path to the log file. """ - logfile_default = "/var/log/xen/xend.log" - - """Default level of information to be logged.""" - loglevel_default = ''DEBUG'' - - """Default Xen-API server configuration. """ - xen_api_server_default = [[''unix'']] - - """Default for the flag indicating whether xend should run an http server - (deprecated).""" - xend_http_server_default = ''no'' - - xend_tcp_xmlrpc_server_default = ''no'' - - xend_unix_xmlrpc_server_default = ''yes'' - - """Default interface address xend listens at. """ - xend_address_default = '''' - - """Default for the flag indicating whether xend should run a relocation server.""" - xend_relocation_server_default = ''no'' - - """Default interface address the xend relocation server listens at. """ - xend_relocation_address_default = '''' - - """Default port xend serves HTTP at. """ - xend_port_default = ''8000'' - - """Default port xend serves relocation at. """ - xend_relocation_port_default = ''8002'' - - xend_relocation_hosts_allow_default = '''' - - """Default for the flag indicating whether xend should run a unix-domain - server (deprecated).""" - xend_unix_server_default = ''no'' - - """Default external migration tool """ - external_migration_tool_default = '''' - - """Default path the unix-domain server listens at.""" - xend_unix_path_default = ''/var/lib/xend/xend-socket'' - - dom0_min_mem_default = ''0'' - - dom0_vcpus_default = ''0'' - - vncpasswd_default = None - - """Default interface to listen for VNC connections on""" - xend_vnc_listen_default = ''127.0.0.1'' - - """Default session storage path.""" - xend_domains_path_default = ''/var/lib/xend/domains'' - - """Default xend management state storage.""" - xend_state_path_default = ''/var/lib/xend/state'' - - components = {} - - def __init__(self): - self.config_path = None - self.config = None - self.configure() - - - def _logError(self, fmt, *args): - """Logging function to log to stderr. We use this for XendRoot log - messages because they may be logged before the logger has been - configured. Other components can safely use the logger. - """ - print >>sys.stderr, "xend [ERROR]", fmt % args - - - def configure(self): - self.set_config() - XendLogging.init(self.get_config_value("logfile", - self.logfile_default), - self.get_config_value("loglevel", - self.loglevel_default)) - - - def set_config(self): - """If the config file exists, read it. If not, ignore it. - - The config file is a sequence of sxp forms. - """ - self.config_path = os.getenv(self.config_var, self.config_default) - if os.path.exists(self.config_path): - try: - fin = file(self.config_path, ''rb'') - try: - config = sxp.parse(fin) - finally: - fin.close() - if config is None: - config = [''xend-config''] - else: - config.insert(0, ''xend-config'') - self.config = config - 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): - """Get the configuration element with the given name, or - the whole configuration if no name is given. - - @param name: element name (optional) - @return: config or none - """ - if name is None: - val = self.config - else: - val = sxp.child(self.config, name) - return val - - def get_config_value(self, name, val=None): - """Get the value of an atomic configuration element. - - @param name: element name - @param val: default value (optional, defaults to None) - @return: value - """ - return sxp.child_value(self.config, name, val=val) - - def get_config_bool(self, name, val=None): - v = string.lower(str(self.get_config_value(name, val))) - if v in [''yes'', ''y'', ''1'', ''on'', ''true'', ''t'']: - return True - if v in [''no'', ''n'', ''0'', ''off'', ''false'', ''f'']: - return False - raise XendError("invalid xend config %s: expected bool: %s" % (name, v)) - - def get_config_int(self, name, val=None): - v = self.get_config_value(name, val) - try: - return int(v) - except Exception: - raise XendError("invalid xend config %s: expected int: %s" % (name, v)) - - def get_xen_api_server(self): - """Get the Xen-API server configuration. - """ - return self.get_config_value(''xen-api-server'', - self.xen_api_server_default) - - def get_xend_http_server(self): - """Get the flag indicating whether xend should run an http server. - """ - return self.get_config_bool("xend-http-server", self.xend_http_server_default) - - def get_xend_tcp_xmlrpc_server(self): - return self.get_config_bool("xend-tcp-xmlrpc-server", - self.xend_tcp_xmlrpc_server_default) - - def get_xend_unix_xmlrpc_server(self): - return self.get_config_bool("xend-unix-xmlrpc-server", - self.xend_unix_xmlrpc_server_default) - - def get_xend_relocation_server(self): - """Get the flag indicating whether xend should run a relocation server. - """ - return self.get_config_bool("xend-relocation-server", - self.xend_relocation_server_default) - - def get_xend_port(self): - """Get the port xend listens at for its HTTP interface. - """ - return self.get_config_int(''xend-port'', self.xend_port_default) - - def get_xend_relocation_port(self): - """Get the port xend listens at for connection to its relocation server. - """ - return self.get_config_int(''xend-relocation-port'', - self.xend_relocation_port_default) - - def get_xend_relocation_hosts_allow(self): - return self.get_config_value("xend-relocation-hosts-allow", - self.xend_relocation_hosts_allow_default) - - def get_xend_address(self): - """Get the address xend listens at for its HTTP port. - 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 port. - """ - return self.get_config_value(''xend-address'', self.xend_address_default) - - def get_xend_relocation_address(self): - """Get the address xend listens at for its relocation server port. - 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 relocation port. - """ - return self.get_config_value(''xend-relocation-address'', self.xend_relocation_address_default) - - def get_xend_unix_server(self): - """Get the flag indicating whether xend should run a unix-domain server. - """ - return self.get_config_bool("xend-unix-server", self.xend_unix_server_default) - - def get_xend_unix_path(self): - """Get the path the xend unix-domain server listens at. - """ - return self.get_config_value("xend-unix-path", self.xend_unix_path_default) - - def get_xend_domains_path(self): - """ Get the path for persistent domain configuration storage - """ - return self.get_config_value("xend-domains-path", self.xend_domains_path_default) - - def get_xend_state_path(self): - """ Get the path for persistent domain configuration storage - """ - return self.get_config_value("xend-state-path", self.xend_state_path_default) - - def get_network_script(self): - """@return the script used to alter the network configuration when - Xend starts and stops, or None if no such script is specified.""" - - s = self.get_config_value(''network-script'') - - if s: - result = s.split(" ") - result[0] = os.path.join(self.network_script_dir, result[0]) - return result - else: - return None - - def get_external_migration_tool(self): - """@return the name of the tool to handle virtual TPM migration.""" - return self.get_config_value(''external-migration-tool'', self.external_migration_tool_default) - - def get_enable_dump(self): - return self.get_config_bool(''enable-dump'', ''no'') - - def get_vif_script(self): - return self.get_config_value(''vif-script'', ''vif-bridge'') - - def get_dom0_min_mem(self): - return self.get_config_int(''dom0-min-mem'', self.dom0_min_mem_default) - - def get_dom0_vcpus(self): - return self.get_config_int(''dom0-cpus'', self.dom0_vcpus_default) - - def get_console_limit(self): - return self.get_config_int(''console-limit'', 1024) - - def get_vnclisten_address(self): - return self.get_config_value(''vnc-listen'', self.xend_vnc_listen_default) - - def get_vncpasswd_default(self): - return self.get_config_value(''vncpasswd'', - self.vncpasswd_default) - -def instance(): - """Get an instance of XendRoot. - Use this instead of the constructor. - """ - global inst - try: - inst - except: - inst = XendRoot() - return inst diff --git a/tools/python/xen/xend/balloon.py b/tools/python/xen/xend/balloon.py --- a/tools/python/xen/xend/balloon.py +++ b/tools/python/xen/xend/balloon.py @@ -22,7 +22,7 @@ import xen.lowlevel.xc import xen.lowlevel.xc import XendDomain -import XendRoot +import XendOptions from XendLogging import log from XendError import VmError @@ -107,11 +107,11 @@ def free(need_mem): # usage, so we recheck the required alloc each time around the loop, but # track the last used value so that we don''t trigger too many watches. - xroot = XendRoot.instance() + xoptions = XendOptions.instance() xc = xen.lowlevel.xc.xc() try: - dom0_min_mem = xroot.get_dom0_min_mem() * 1024 + dom0_min_mem = xoptions.get_dom0_min_mem() * 1024 retries = 0 sleep_time = SLEEP_TIME_GROWTH diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -459,14 +459,14 @@ class HVMImageHandler(ImageHandler): vnclisten = imageConfig.get(''vnclisten'') if not(vnclisten): - vnclisten = (xen.xend.XendRoot.instance(). + vnclisten = (xen.xend.XendOptions.instance(). get_vnclisten_address()) if vnclisten: ret += [''-vnclisten'', vnclisten] vncpasswd = vncpasswd_vmconfig if vncpasswd is None: - vncpasswd = (xen.xend.XendRoot.instance(). + vncpasswd = (xen.xend.XendOptions.instance(). get_vncpasswd_default()) if vncpasswd is None: raise VmError(''vncpasswd is not set up in '' + diff --git a/tools/python/xen/xend/server/DevController.py b/tools/python/xen/xend/server/DevController.py --- a/tools/python/xen/xend/server/DevController.py +++ b/tools/python/xen/xend/server/DevController.py @@ -19,7 +19,7 @@ from threading import Event from threading import Event import types -from xen.xend import sxp, XendRoot +from xen.xend import sxp, XendOptions from xen.xend.XendError import VmError from xen.xend.XendLogging import log @@ -50,7 +50,7 @@ xenbusState = { ''Closed'' : 6, } -xroot = XendRoot.instance() +xoptions = XendOptions.instance() xenbusState.update(dict(zip(xenbusState.values(), xenbusState.keys()))) @@ -324,7 +324,7 @@ class DevController: Make sure that the migration has finished and only then return from the call. """ - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool: log.info("Calling external migration tool for step %d" % step) fd = os.popen("%s -type %s -step %d -host %s -domname %s" % @@ -341,7 +341,7 @@ class DevController: """ Recover from device migration. The given step was the last one that was successfully executed. """ - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool: log.info("Calling external migration tool") fd = os.popen("%s -type %s -step %d -host %s -domname %s -recover" % diff --git a/tools/python/xen/xend/server/SrvRoot.py b/tools/python/xen/xend/server/SrvRoot.py --- a/tools/python/xen/xend/server/SrvRoot.py +++ b/tools/python/xen/xend/server/SrvRoot.py @@ -25,7 +25,7 @@ class SrvRoot(SrvDir): """Server sub-components. Each entry is (name, class), where ''name'' is the entry name and ''class'' is the name of its class. """ - #todo Get this list from the XendRoot config. + #todo Get this list from the XendOptions config. subdirs = [ (''node'', ''SrvNode'' ), (''domain'', ''SrvDomainDir'' ), diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -48,7 +48,7 @@ from threading import Thread from xen.web.httpserver import HttpServer, UnixHttpServer -from xen.xend import XendRoot, XendAPI +from xen.xend import XendOptions, XendAPI from xen.xend import Vifctl from xen.xend.XendLogging import log from xen.xend.XendClient import XEN_API_SOCKET @@ -57,7 +57,7 @@ from SrvRoot import SrvRoot from SrvRoot import SrvRoot from XMLRPCServer import XMLRPCServer -xroot = XendRoot.instance() +xoptions = XendOptions.instance() class XendServers: @@ -163,7 +163,7 @@ class XendServers: log.info("Restarting all XML-RPC and Xen-API servers...") self.cleaningUp = False self.reloadingConfig = False - xroot.set_config() + xoptions.set_config() new_servers = [x for x in self.servers if isinstance(x, HttpServer)] self.servers = new_servers @@ -172,16 +172,16 @@ class XendServers: break def _loadConfig(servers, root, reload): - if not reload and xroot.get_xend_http_server(): + if not reload and xoptions.get_xend_http_server(): servers.add(HttpServer(root, - xroot.get_xend_address(), - xroot.get_xend_port())) - if not reload and xroot.get_xend_unix_server(): - path = xroot.get_xend_unix_path() + xoptions.get_xend_address(), + xoptions.get_xend_port())) + if not reload and xoptions.get_xend_unix_server(): + path = xoptions.get_xend_unix_path() log.info(''unix path='' + path) servers.add(UnixHttpServer(root, path)) - api_cfg = xroot.get_xen_api_server() + api_cfg = xoptions.get_xen_api_server() if api_cfg: try: addrs = [(str(x[0]).split('':''), @@ -216,10 +216,10 @@ def _loadConfig(servers, root, reload): except TypeError, exn: log.error(''Xen-API server configuration %s is invalid.'', api_cfg) - if xroot.get_xend_tcp_xmlrpc_server(): + if xoptions.get_xend_tcp_xmlrpc_server(): servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False, True)) - if xroot.get_xend_unix_xmlrpc_server(): + if xoptions.get_xend_unix_xmlrpc_server(): servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False)) diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -24,10 +24,10 @@ import random import random import re -from xen.xend import XendRoot +from xen.xend import XendOptions from xen.xend.server.DevController import DevController -xroot = XendRoot.instance() +xoptions = XendOptions.instance() def randomMAC(): """Generate a random MAC address. @@ -138,8 +138,8 @@ class NetifController(DevController): def getDeviceDetails(self, config): """@see DevController.getDeviceDetails""" - script = os.path.join(xroot.network_script_dir, - config.get(''script'', xroot.get_vif_script())) + script = os.path.join(xoptions.network_script_dir, + config.get(''script'', xoptions.get_vif_script())) typ = config.get(''type'') bridge = config.get(''bridge'') mac = config.get(''mac'') @@ -190,7 +190,7 @@ class NetifController(DevController): (script, ip, bridge, mac, typ, vifname, rate, uuid) = devinfo if script: - network_script_dir = xroot.network_script_dir + os.sep + network_script_dir = xoptions.network_script_dir + os.sep result[''script''] = script.replace(network_script_dir, "") if ip: result[''ip''] = ip diff --git a/tools/python/xen/xend/server/relocate.py b/tools/python/xen/xend/server/relocate.py --- a/tools/python/xen/xend/server/relocate.py +++ b/tools/python/xen/xend/server/relocate.py @@ -24,7 +24,7 @@ from xen.web import protocol, tcp, unix from xen.xend import sxp from xen.xend import XendDomain -from xen.xend import XendRoot +from xen.xend import XendOptions from xen.xend.XendError import XendError from xen.xend.XendLogging import log @@ -114,15 +114,15 @@ class RelocationProtocol(protocol.Protoc def listenRelocation(): - xroot = XendRoot.instance() - if xroot.get_xend_unix_server(): + xoptions = XendOptions.instance() + if xoptions.get_xend_unix_server(): path = ''/var/lib/xend/relocation-socket'' unix.UnixListener(path, RelocationProtocol) - if xroot.get_xend_relocation_server(): - port = xroot.get_xend_relocation_port() - interface = xroot.get_xend_relocation_address() + if xoptions.get_xend_relocation_server(): + port = xoptions.get_xend_relocation_port() + interface = xoptions.get_xend_relocation_address() - hosts_allow = xroot.get_xend_relocation_hosts_allow() + hosts_allow = xoptions.get_xend_relocation_hosts_allow() if hosts_allow == '''': hosts_allow = None else: diff --git a/tools/python/xen/xend/server/tests/test_controllers.py b/tools/python/xen/xend/server/tests/test_controllers.py --- a/tools/python/xen/xend/server/tests/test_controllers.py +++ b/tools/python/xen/xend/server/tests/test_controllers.py @@ -2,9 +2,9 @@ import re import re import unittest -import xen.xend.XendRoot +import xen.xend.XendOptions -xen.xend.XendRoot.XendRoot.config_default = ''/dev/null'' +xen.xend.XendOptions.XendOptions.config_default = ''/dev/null'' from xen.xend.server import netif @@ -13,7 +13,7 @@ FAKE_DEVID = 63 FAKE_DEVID = 63 -xroot = xen.xend.XendRoot.instance() +xoptions = xen.xend.XendOptions.instance() class test_controllers(unittest.TestCase): @@ -36,8 +36,8 @@ class test_controllers(unittest.TestCase self.assertEqual(backdets[''handle''], str(FAKE_DEVID)) self.assertEqual(backdets[''script''], - os.path.join(xroot.network_script_dir, - xroot.get_vif_script())) + os.path.join(xoptions.network_script_dir, + xoptions.get_vif_script())) self.assertValidMac(backdets[''mac''], expectedMac) self.assertEqual(frontdets[''handle''], str(FAKE_DEVID)) diff --git a/tools/python/xen/xend/server/tpmif.py b/tools/python/xen/xend/server/tpmif.py --- a/tools/python/xen/xend/server/tpmif.py +++ b/tools/python/xen/xend/server/tpmif.py @@ -20,7 +20,7 @@ """Support for virtual TPM interfaces.""" -from xen.xend import XendRoot +from xen.xend import XendOptions from xen.xend.XendLogging import log from xen.xend.XendError import XendError from xen.xend.XendConstants import DEV_MIGRATE_TEST, VTPM_DELETE_SCRIPT @@ -29,7 +29,7 @@ import os import os import re -xroot = XendRoot.instance() +xoptions = XendOptions.instance() def destroy_vtpmstate(name): if os.path.exists(VTPM_DELETE_SCRIPT): @@ -88,7 +88,7 @@ class TPMifController(DevController): def migrate(self, deviceConfig, network, dst, step, domName): """@see DevContoller.migrate""" if network: - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool != '''': log.info("Request to network-migrate device to %s. step=%d.", dst, step) @@ -116,7 +116,7 @@ class TPMifController(DevController): def recover_migrate(self, deviceConfig, network, dst, step, domName): """@see DevContoller.recover_migrate""" if network: - tool = xroot.get_external_migration_tool() + tool = xoptions.get_external_migration_tool() if tool != '''': log.info("Request to recover network-migrated device. last good step=%d.", step) diff --git a/tools/python/xen/xend/server/vfbif.py b/tools/python/xen/xend/server/vfbif.py --- a/tools/python/xen/xend/server/vfbif.py +++ b/tools/python/xen/xend/server/vfbif.py @@ -52,7 +52,7 @@ class VfbifController(DevController): if config.has_key("vncpasswd"): passwd = config["vncpasswd"] else: - passwd = xen.xend.XendRoot.instance().get_vncpasswd_default() + passwd = xen.xend.XendOptions.instance().get_vncpasswd_default() if passwd: self.vm.storeVm("vncpasswd", passwd) log.debug("Stored a VNC password for vfb access") @@ -66,7 +66,7 @@ class VfbifController(DevController): elif config.has_key("vncdisplay"): args += ["--vncport", "%d" % (5900 + config["vncdisplay"])] vnclisten = config.get("vnclisten", - xen.xend.XendRoot.instance().get_vnclisten_address()) + xen.xend.XendOptions.instance().get_vnclisten_address()) args += [ "--listen", vnclisten ] spawn_detached(args[0], args + std_args, os.environ) elif t == "sdl": diff --git a/tools/python/xen/xm/tests/test_create.py b/tools/python/xen/xm/tests/test_create.py --- a/tools/python/xen/xm/tests/test_create.py +++ b/tools/python/xen/xm/tests/test_create.py @@ -3,9 +3,9 @@ import tempfile import tempfile import unittest -import xen.xend.XendRoot - -xen.xend.XendRoot.XendRoot.config_default = ''/dev/null'' +import xen.xend.XendOptions + +xen.xend.XendOptions.XendOptions.config_default = ''/dev/null'' import xen.xm.create _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ewan Mellor
2007-Jan-05 10:57 UTC
Re: [Xen-devel] [PATCH] Support xend configuration via Solaris SMF
On Fri, Dec 29, 2006 at 02:51:17PM +0000, John Levon wrote:> > Ooops, fixed patch. > > john > > # HG changeset patch > # User john.levon@sun.com > # Date 1167403005 28800 > # Node ID a18e42ef75a880637414d697102f534f8653b61a > # Parent 819689bd07959241a860c29c01bf7d8a259f00ff > Enable xend to pick up properties from SMF on Solaris. Also rename XendRoot > to the much clearer XendOptions. > > Signed-off-by: John Levon <john.levon@sun.com>Could you please submit this patch without the renaming of XendRoot, or submit the renaming separately? You''ve added 600 lines of unnecessary change, mixed in with your real changes, and I''d much prefer it if they were separate changesets. Cheers, Ewan. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
John Levon
2007-Jan-05 15:06 UTC
Re: [Xen-devel] [PATCH] Support xend configuration via Solaris SMF
On Fri, Jan 05, 2007 at 10:57:30AM +0000, Ewan Mellor wrote:> Could you please submit this patch without the renaming of XendRoot, or submit > the renaming separately? You''ve added 600 lines of unnecessary change, mixed > in with your real changes, and I''d much prefer it if they were separate > changesets.Fair enough, I''ll send a renaming patch first. regards john _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel