# HG changeset patch
# User Ewan Mellor <ewan@xxxxxxxxxxxxx>
# Date 1169132871 0
# Node ID 074170d7284c310b9b2b9acd6b9f671e83c400f1
# Parent a18ae238eb53e2e0a970c62cb4d2f3ee25ff516a
Allow xend configuration via Solaris SMF as well as the config file.
Signed-off-by: John Levon <john.levon@xxxxxxx>
---
tools/python/setup.py | 13 +
tools/python/xen/lowlevel/scf/scf.c | 156 ++++++++++++++++
tools/python/xen/xend/XendOptions.py | 335 +++++++++++++++++++----------------
3 files changed, 358 insertions(+), 146 deletions(-)
diff -r a18ae238eb53 -r 074170d7284c tools/python/setup.py
--- a/tools/python/setup.py Thu Jan 18 15:03:06 2007 +0000
+++ b/tools/python/setup.py Thu Jan 18 15:07:51 2007 +0000
@@ -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 -r a18ae238eb53 -r 074170d7284c tools/python/xen/lowlevel/scf/scf.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/python/xen/lowlevel/scf/scf.c Thu Jan 18 15:07:51 2007 +0000
@@ -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 -r a18ae238eb53 -r 074170d7284c tools/python/xen/xend/XendOptions.py
--- a/tools/python/xen/xend/XendOptions.py Thu Jan 18 15:03:06 2007 +0000
+++ b/tools/python/xen/xend/XendOptions.py Thu Jan 18 15:07:51 2007 +0000
@@ -20,7 +20,7 @@ Creates the servers and handles configur
Creates the servers and handles configuration.
Other classes get config variables by importing this module,
-using instance() to get a XendRoot instance, and then
+using instance() to get a XendOptions instance, and then
the config functions (e.g. get_xend_port()) to get
configured values.
"""
@@ -33,14 +33,11 @@ from xen.xend import sxp, osdep, XendLog
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"
+if os.uname()[0] == 'SunOS':
+ from xen.lowlevel import scf
+
+class XendOptions:
+ """Configuration options."""
"""Where network control scripts live."""
network_script_dir = osdep.scripts_dir
@@ -75,10 +72,10 @@ class XendRoot:
xend_relocation_address_default = ''
"""Default port xend serves HTTP at. """
- xend_port_default = '8000'
+ xend_port_default = 8000
"""Default port xend serves relocation at. """
- xend_relocation_port_default = '8002'
+ xend_relocation_port_default = 8002
xend_relocation_hosts_allow_default = ''
@@ -92,9 +89,9 @@ class XendRoot:
"""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'
+ dom0_min_mem_default = 0
+
+ dom0_vcpus_default = 0
vncpasswd_default = None
@@ -107,16 +104,11 @@ class XendRoot:
"""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
+ """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.
"""
@@ -125,11 +117,142 @@ class XendRoot:
def configure(self):
self.set_config()
- XendLogging.init(self.get_config_value("logfile",
+ XendLogging.init(self.get_config_string("logfile",
self.logfile_default),
- self.get_config_value("loglevel",
+ 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.
@@ -158,19 +281,6 @@ class XendRoot:
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.
@@ -195,128 +305,63 @@ class XendRoot:
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)
- 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)
+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 XendRoot.
+ """Get an instance of XendOptions.
Use this instead of the constructor.
"""
global inst
try:
inst
except:
- inst = XendRoot()
+ if os.uname()[0] == 'SunOS':
+ inst = XendOptionsSMF()
+ else:
+ inst = XendOptionsFile()
return inst
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|