# HG changeset patch
# User john.levon@sun.com
# Date 1168012582 28800
# Node ID f13eb28a48af6959452a546574a4cb520e0eab5f
# Parent 1ca5153952db953ca99fa28c2a09aa24d31e439a
Allow xend configuration via Solaris SMF as well as the config file.
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/XendOptions.py
b/tools/python/xen/xend/XendOptions.py
--- a/tools/python/xen/xend/XendOptions.py
+++ b/tools/python/xen/xend/XendOptions.py
@@ -33,14 +33,11 @@ from xen.xend import sxp, osdep, XendLog
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:
"""Configuration options."""
-
- """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
@@ -75,10 +72,10 @@ class XendOptions:
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 XendOptions:
"""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,13 +104,8 @@ class XendOptions:
"""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
XendOptions log
@@ -125,11 +117,142 @@ class XendOptions:
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 XendOptions:
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,120 +305,52 @@ class XendOptions:
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 XendOptions.
@@ -318,5 +360,8 @@ def instance():
try:
inst
except:
- inst = XendOptions()
+ if os.uname()[0] == ''SunOS'':
+ inst = XendOptionsSMF()
+ else:
+ inst = XendOptionsFile()
return inst
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel