Merge with xen-ia64-unstable.hg

This commit is contained in:
kfraser@localhost.localdomain committed 2007-01-18 18:25:04 +00:00
commit 0511df5aec
70 files changed
+3366 -347

No files matched your search

+12 -1
View File
@@ -30,6 +30,13 @@ 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" ],
@@ -37,6 +44,10 @@ acm = Extension("acm",
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',
description = 'Xen',
@@ -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')
+156
View File
@@ -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);
}
+22
View File
@@ -160,6 +160,20 @@ static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
return dom_op(self, args, xc_domain_destroy);
}
static PyObject *pyxc_domain_shutdown(XcObject *self, PyObject *args)
{
uint32_t dom, reason;
if (!PyArg_ParseTuple(args, "ii", &dom, &reason))
return NULL;
if (xc_domain_shutdown(self->xc_handle, dom, reason) != 0)
return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
}
static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
PyObject *args,
@@ -1029,6 +1043,14 @@ static PyMethodDef pyxc_methods[] = {
" dom [int]: Identifier of domain to be destroyed.\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "domain_shutdown",
(PyCFunction)pyxc_domain_shutdown,
METH_VARARGS, "\n"
"Shutdown a domain.\n"
" dom [int, 0]: Domain identifier to use.\n"
" reason [int, 0]: Reason for shutdown.\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "vcpu_setaffinity",
(PyCFunction)pyxc_vcpu_setaffinity,
METH_VARARGS | METH_KEYWORDS, "\n"
+1
View File
@@ -256,6 +256,7 @@ class UnixXMLRPCRequestHandler(XMLRPCRequestHandler):
class UnixXMLRPCServer(TCPXMLRPCServer):
address_family = socket.AF_UNIX
allow_address_reuse = True
def __init__(self, addr, allowed, xenapi, logRequests = 1):
mkdir.parents(os.path.dirname(addr), stat.S_IRWXU, True)
+7 -3
View File
@@ -294,8 +294,6 @@ class HttpServer:
backlog = 5
closed = False
def __init__(self, root, interface, port=8080):
self.root = root
self.interface = interface
@@ -303,6 +301,7 @@ class HttpServer:
# ready indicates when we are ready to begin accept connections
# it should be set after a successful bind
self.ready = False
self.closed = False
def run(self):
self.bind()
@@ -317,7 +316,6 @@ class HttpServer:
def stop(self):
self.close()
def bind(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
flags = fcntl.fcntl(self.socket.fileno(), fcntl.F_GETFD)
@@ -334,7 +332,10 @@ class HttpServer:
def close(self):
self.closed = True
self.ready = False
try:
# shutdown socket explicitly to allow reuse
self.socket.shutdown(socket.SHUT_RDWR)
self.socket.close()
except:
pass
@@ -345,6 +346,9 @@ class HttpServer:
def getResource(self, req):
return self.root.getRequestResource(req)
def shutdown(self):
self.close()
class UnixHttpServer(HttpServer):
+2 -2
View File
@@ -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)
+81 -6
View File
@@ -22,11 +22,14 @@ from xen.xend.XendConfig import XendConfig
from xen.xend.XendConstants import *
SIGNATURE = "LinuxGuestRecord"
QEMU_SIGNATURE = "QemuDeviceModelRecord"
dm_batch = 512
XC_SAVE = "xc_save"
XC_RESTORE = "xc_restore"
sizeof_int = calcsize("i")
sizeof_unsigned_int = calcsize("I")
sizeof_unsigned_long = calcsize("L")
@@ -69,6 +72,11 @@ def save(fd, dominfo, network, live, dst):
"could not write guest state file: config len")
write_exact(fd, config, "could not write guest state file: config")
image_cfg = dominfo.info.get('image', {})
hvm = image_cfg.has_key('hvm')
if hvm:
log.info("save hvm domain")
# xc_save takes three customization parameters: maxit, max_f, and
# flags the last controls whether or not save is 'live', while the
# first two further customize behaviour when 'live' save is
@@ -76,7 +84,7 @@ def save(fd, dominfo, network, live, dst):
# libxenguest; see the comments and/or code in xc_linux_save() for
# more information.
cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd),
str(dominfo.getDomid()), "0", "0", str(int(live)) ]
str(dominfo.getDomid()), "0", "0", str(int(live) | (int(hvm) << 2)) ]
log.debug("[xc_save]: %s", string.join(cmd))
def saveInputHandler(line, tochild):
@@ -90,12 +98,29 @@ def save(fd, dominfo, network, live, dst):
log.info("Domain %d suspended.", dominfo.getDomid())
dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP3,
domain_name)
#send signal to device model for save
if hvm:
log.info("release_devices for hvm domain")
dominfo._releaseDevices(True)
tochild.write("done\n")
tochild.flush()
log.debug('Written done')
forkHelper(cmd, fd, saveInputHandler, False)
# put qemu device model state
if hvm:
write_exact(fd, QEMU_SIGNATURE, "could not write qemu signature")
qemu_fd = os.open("/tmp/xen.qemu-dm.%d" % dominfo.getDomid(), os.O_RDONLY)
while True:
buf = os.read(qemu_fd, dm_batch)
if len(buf):
write_exact(fd, buf, "could not write device model state")
else:
break
os.close(qemu_fd)
os.remove("/tmp/xen.qemu-dm.%d" % dominfo.getDomid())
dominfo.destroyDomain()
try:
dominfo.setName(domain_name)
@@ -149,19 +174,49 @@ def restore(xd, fd, dominfo = None, paused = False):
nr_pfns = (dominfo.getMemoryTarget() + 3) / 4
# if hvm, pass mem size to calculate the store_mfn
hvm = 0
apic = 0
pae = 0
image_cfg = dominfo.info.get('image', {})
hvm = image_cfg.has_key('hvm')
if hvm:
# the 'memory' in config has been removed
hvm = dominfo.info['memory_static_min']
apic = dominfo.info['image']['hvm'].get('apic', 0)
pae = dominfo.info['image']['hvm'].get('pae', 0)
log.info("restore hvm domain %d, mem=%d, apic=%d, pae=%d",
dominfo.domid, hvm, apic, pae)
try:
l = read_exact(fd, sizeof_unsigned_long,
"not a valid guest state file: pfn count read")
if hvm:
l = read_exact(fd, sizeof_unsigned_int,
"not a valid hvm guest state file: pfn count read")
nr_pfns = unpack("I", l)[0] # native sizeof int
else:
l = read_exact(fd, sizeof_unsigned_long,
"not a valid guest state file: pfn count read")
max_pfn = unpack("L", l)[0] # native sizeof long
if max_pfn > 16*1024*1024: # XXX
raise XendError(
"not a valid guest state file: pfn count out of range")
balloon.free(xc.pages_to_kib(nr_pfns))
shadow = dominfo.info['shadow_memory']
log.debug("restore:shadow=0x%x, _static_max=0x%x, _static_min=0x%x, "
"nr_pfns=0x%x.", dominfo.info['shadow_memory'],
dominfo.info['memory_static_max'],
dominfo.info['memory_static_min'], nr_pfns)
balloon.free(xc.pages_to_kib(nr_pfns) + shadow * 1024)
shadow_cur = xc.shadow_mem_control(dominfo.getDomid(), shadow)
dominfo.info['shadow_memory'] = shadow_cur
cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE),
fd, dominfo.getDomid(), max_pfn,
store_port, console_port])
store_port, console_port, hvm, pae, apic])
log.debug("[xc_restore]: %s", string.join(cmd))
handler = RestoreInputHandler()
@@ -171,10 +226,30 @@ def restore(xd, fd, dominfo = None, paused = False):
if handler.store_mfn is None or handler.console_mfn is None:
raise XendError('Could not read store/console MFN')
os.read(fd, 1) # Wait for source to close connection
dominfo.waitForDevices() # Wait for backends to set up
if not paused:
dominfo.unpause()
# get qemu state and create a tmp file for dm restore
if hvm:
qemu_signature = read_exact(fd, len(QEMU_SIGNATURE),
"invalid device model signature read")
if qemu_signature != QEMU_SIGNATURE:
raise XendError("not a valid device model state: found '%s'" %
qemu_signature)
qemu_fd = os.open("/tmp/xen.qemu-dm.%d" % dominfo.getDomid(),
os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
while True:
buf = os.read(fd, dm_batch)
if len(buf):
write_exact(qemu_fd, buf,
"could not write dm state to tmp file")
else:
break
os.close(qemu_fd)
os.read(fd, 1) # Wait for source to close connection
dominfo.completeRestore(handler.store_mfn, handler.console_mfn)
+27 -18
View File
@@ -78,6 +78,25 @@ def scrub_password(data):
else:
return data
#
# CPU fields:
#
# vcpus_number -- the maximum number of vcpus that this domain may ever have.
# aka XendDomainInfo.getVCpuCount().
# vcpus -- the legacy configuration name for above.
# max_vcpu_id -- vcpus_number - 1. This is given to us by Xen.
#
# cpus -- the list of pCPUs available to each vCPU.
#
# vcpu_avail: a bitmap telling the guest domain whether it may use each of
# its VCPUs. This is translated to
# <dompath>/cpu/<id>/availability = {online,offline} for use
# by the guest domain.
# online_vpcus -- the number of VCPUs currently up, as reported by Xen. This
# is changed by changing vcpu_avail, and waiting for the
# domain to respond.
#
# Mapping from XendConfig configuration keys to the old
# legacy configuration keys that map directly.
@@ -185,7 +204,7 @@ LEGACY_CFG_TYPES = {
'uuid': str,
'name': str,
'vcpus': int,
'vcpu_avail': int,
'vcpu_avail': long,
'memory': int,
'shadow_memory': int,
'maxmem': int,
@@ -355,9 +374,6 @@ class XendConfig(dict):
'cpu_weight': 256,
'cpu_cap': 0,
'vcpus_number': 1,
'online_vcpus': 1,
'max_vcpu_id': 0,
'vcpu_avail': 1,
'console_refs': [],
'vif_refs': [],
'vbd_refs': [],
@@ -389,7 +405,7 @@ class XendConfig(dict):
event)
def _vcpus_sanity_check(self):
if self.get('vcpus_number') != None:
if 'vcpus_number' in self and 'vcpu_avail' not in self:
self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
def _uuid_sanity_check(self):
@@ -405,7 +421,7 @@ class XendConfig(dict):
def _dominfo_to_xapi(self, dominfo):
self['domid'] = dominfo['domid']
self['online_vcpus'] = dominfo['online_vcpus']
self['max_vcpu_id'] = dominfo['max_vcpu_id']
self['vcpus_number'] = dominfo['max_vcpu_id'] + 1
self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024
self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024
self['cpu_time'] = dominfo['cpu_time']/1e9
@@ -636,9 +652,6 @@ class XendConfig(dict):
self['memory_dynamic_max'] = self['memory_static_max']
self['memory_dynamic_min'] = self['memory_static_min']
# make sure max_vcpu_id is set correctly
self['max_vcpu_id'] = self['vcpus_number'] - 1
# set device references in the configuration
self['devices'] = cfg.get('devices', {})
@@ -720,13 +733,11 @@ class XendConfig(dict):
_set_cfg_if_exists('on_xend_stop')
_set_cfg_if_exists('on_xend_start')
_set_cfg_if_exists('vcpu_avail')
_set_cfg_if_exists('max_vcpu_id') # needed for vcpuDomDetails
_set_cfg_if_exists('cpu_weight')
_set_cfg_if_exists('cpu_cap')
# Parse and store runtime configuration
_set_cfg_if_exists('start_time')
_set_cfg_if_exists('online_vcpus')
_set_cfg_if_exists('cpu_time')
_set_cfg_if_exists('shutdown_reason')
_set_cfg_if_exists('up_time')
@@ -1115,19 +1126,17 @@ class XendConfig(dict):
# configuration
log.debug("update_with_image_sxp(%s)" % scrub_password(image_sxp))
kernel_args = ""
# user-specified args must come last: previous releases did this and
# some domU kernels rely upon the ordering.
kernel_args = sxp.child_value(image_sxp, 'args', '')
# attempt to extract extra arguments from SXP config
arg_ip = sxp.child_value(image_sxp, 'ip')
if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
kernel_args += 'ip=%s ' % arg_ip
kernel_args = 'ip=%s ' % arg_ip + kernel_args
arg_root = sxp.child_value(image_sxp, 'root')
if arg_root and not re.search(r'root=', kernel_args):
kernel_args += 'root=%s ' % arg_root
# user-specified args must come last: previous releases did this and
# some domU kernels rely upon the ordering.
kernel_args += sxp.child_value(image_sxp, 'args', '')
kernel_args = 'root=%s ' % arg_root + kernel_args
if bootloader:
self['_temp_using_bootloader'] = '1'
+6 -6
View File
@@ -32,7 +32,7 @@ import threading
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.util import mkdir, security
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
@@ -1164,7 +1164,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))
+35 -29
View File
@@ -38,7 +38,7 @@ from xen.util.blkif import blkdev_uname_to_file
from xen.util import security
from xen.xend import balloon, sxp, uuid, image, arch, osdep
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,31 +54,12 @@ MIGRATE_TIMEOUT = 30.0
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)
#
# There are a number of CPU-related fields:
#
# vcpus: the number of virtual CPUs this domain is configured to use.
# vcpu_avail: a bitmap telling the guest domain whether it may use each of
# its VCPUs. This is translated to
# <dompath>/cpu/<id>/availability = {online,offline} for use
# by the guest domain.
# cpumap: a list of bitmaps, one for each VCPU, giving the physical
# CPUs that that VCPU may use.
# cpu: a configuration setting requesting that VCPU 0 is pinned to
# the specified physical CPU.
#
# vcpus and vcpu_avail settings persist with the VM (i.e. they are persistent
# across save, restore, migrate, and restart). The other settings are only
# specific to the domain, so are lost when the VM moves.
#
def create(config):
"""Creates and start a VM using the supplied configuration.
@@ -451,6 +432,16 @@ class XendDomainInfo:
self._removeVm('xend/previous_restart_time')
self.storeDom("control/shutdown", reason)
## shutdown hypercall for hvm domain desides xenstore write
image_cfg = self.info.get('image', {})
hvm = image_cfg.has_key('hvm')
if hvm:
for code in DOMAIN_SHUTDOWN_REASONS.keys():
if DOMAIN_SHUTDOWN_REASONS[code] == reason:
break
xc.domain_shutdown(self.domid, code)
def pause(self):
"""Pause domain
@@ -614,7 +605,7 @@ class XendDomainInfo:
['name', self.info['name_label']],
['vcpu_count', self.info['vcpus_number']]]
for i in range(0, self.info['max_vcpu_id']+1):
for i in range(0, self.info['vcpus_number']):
info = xc.vcpu_getinfo(self.domid, i)
sxpr.append(['vcpu',
@@ -739,7 +730,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)
}
@@ -898,8 +889,9 @@ class XendDomainInfo:
self._writeDom(self._vcpuDomDetails())
else:
self.info['vcpus_number'] = vcpus
self.info['online_vcpus'] = vcpus
xen.xend.XendDomain.instance().managed_config_save(self)
log.info("Set VCPU count on domain %s to %d", self.info['name_label'],
vcpus)
def getLabel(self):
return security.get_security_info(self.info, 'label')
@@ -976,7 +968,7 @@ class XendDomainInfo:
self.info['name_label'], self.domid)
self._writeVm(LAST_SHUTDOWN_REASON, 'crash')
if xroot.get_enable_dump():
if xoptions.get_enable_dump():
try:
self.dumpCore()
except XendError:
@@ -1228,8 +1220,11 @@ class XendDomainInfo:
if self.image:
self.image.createDeviceModel()
def _releaseDevices(self):
def _releaseDevices(self, suspend = False):
"""Release all domain's devices. Nothrow guarantee."""
if suspend and self.image:
self.image.destroy(suspend)
return
while True:
t = xstransact("%s/device" % self.dompath)
@@ -1381,7 +1376,7 @@ class XendDomainInfo:
# this is done prior to memory allocation to aide in memory
# distribution for NUMA systems.
if self.info['cpus'] is not None and len(self.info['cpus']) > 0:
for v in range(0, self.info['max_vcpu_id']+1):
for v in range(0, self.info['vcpus_number']):
xc.vcpu_setaffinity(self.domid, v, self.info['cpus'])
# Use architecture- and image-specific calculations to determine
@@ -1395,6 +1390,7 @@ class XendDomainInfo:
self.info['shadow_memory'] * 1024,
self.info['memory_static_max'] * 1024)
log.debug("_initDomain:shadow_memory=0x%x, memory_static_max=0x%x, memory_static_min=0x%x.", self.info['shadow_memory'], self.info['memory_static_max'], self.info['memory_static_min'],)
# Round shadow up to a multiple of a MiB, as shadow_mem_control
# takes MiB and we must not round down and end up under-providing.
shadow = ((shadow + 1023) / 1024) * 1024
@@ -1494,6 +1490,16 @@ class XendDomainInfo:
self.console_mfn = console_mfn
self._introduceDomain()
image_cfg = self.info.get('image', {})
hvm = image_cfg.has_key('hvm')
if hvm:
self.image = image.create(self,
self.info,
self.info['image'],
self.info['devices'])
if self.image:
self.image.createDeviceModel(True)
self.image.register_shutdown_watch()
self._storeDomDetails()
self._registerWatches()
self.refreshShutdown()
@@ -2028,8 +2034,8 @@ class XendDomainInfo:
# TODO: spec says that key is int, however, python does not allow
# non-string keys to dictionaries.
vcpu_util = {}
if 'max_vcpu_id' in self.info and self.domid != None:
for i in range(0, self.info['max_vcpu_id']+1):
if 'vcpus_number' in self.info and self.domid != None:
for i in range(0, self.info['vcpus_number']):
info = xc.vcpu_getinfo(self.domid, i)
vcpu_util[str(i)] = info['cpu_time']/1000000000.0
+2 -2
View File
@@ -24,7 +24,7 @@ from xen.util import Brctl
from xen.xend import uuid
from xen.xend.XendError import XendError, NetworkAlreadyConnected
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 *
@@ -45,7 +45,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')
@@ -20,7 +20,7 @@
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 @@ import sys
from xen.xend import sxp, osdep, XendLogging
from xen.xend.XendError import XendError
class XendRoot:
"""Root of the management classes."""
if os.uname()[0] == 'SunOS':
from xen.lowlevel import scf
"""Default path to the config file."""
config_default = "/etc/xen/xend-config.sxp"
"""Environment variable used to override config_default."""
config_var = "XEND_CONFIG"
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_min_mem_default = 0
dom0_vcpus_default = '0'
dom0_vcpus_default = 0
vncpasswd_default = None
@@ -107,16 +104,17 @@ class XendRoot:
"""Default xend management state storage."""
xend_state_path_default = '/var/lib/xend/state'
components = {}
"""Default type of backend network interfaces"""
netback_type = osdep.netback_type
"""Default script to configure a backend network interface"""
vif_script = osdep.vif_script
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,81 +123,25 @@ 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):
"""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)
raise NotImplementedError()
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))
raise NotImplementedError()
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))
raise NotImplementedError()
def get_config_string(self, name, val=None):
raise NotImplementedError()
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)
raise NotImplementedError()
def get_xend_http_server(self):
"""Get the flag indicating whether xend should run an http server.
@@ -232,7 +174,7 @@ class XendRoot:
self.xend_relocation_port_default)
def get_xend_relocation_hosts_allow(self):
return self.get_config_value("xend-relocation-hosts-allow",
return self.get_config_string("xend-relocation-hosts-allow",
self.xend_relocation_hosts_allow_default)
def get_xend_address(self):
@@ -241,7 +183,7 @@ class XendRoot:
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)
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.
@@ -249,7 +191,7 @@ class XendRoot:
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)
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.
@@ -259,23 +201,23 @@ class XendRoot:
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)
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_value("xend-domains-path", self.xend_domains_path_default)
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_value("xend-state-path", self.xend_state_path_default)
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_value('network-script')
s = self.get_config_string('network-script')
if s:
result = s.split(" ")
@@ -286,13 +228,13 @@ class XendRoot:
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)
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_value('vif-script', 'vif-bridge')
return self.get_config_string('vif-script', self.vif_script)
def get_dom0_min_mem(self):
return self.get_config_int('dom0-min-mem', self.dom0_min_mem_default)
@@ -304,19 +246,128 @@ class XendRoot:
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)
return self.get_config_string('vnc-listen', self.xend_vnc_listen_default)
def get_vncpasswd_default(self):
return self.get_config_value('vncpasswd',
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 self.get_config_value(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 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
+3 -3
View File
@@ -24,7 +24,7 @@ import types
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_ACCEPTED = 202
HTTP_NO_CONTENT = 204
xroot = XendRoot.instance()
xoptions = XendOptions.instance()
class XendError(RuntimeError):
@@ -218,7 +218,7 @@ class UnixXendClientProtocol(HttpXendClientProtocol):
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, _):
+3 -3
View File
@@ -22,7 +22,7 @@ import time
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
+16 -9
View File
@@ -173,7 +173,7 @@ class ImageHandler:
"""Build the domain. Define in subclass."""
raise NotImplementedError()
def createDeviceModel(self):
def createDeviceModel(self, restore = False):
"""Create device model for the domain (define in subclass if needed)."""
pass
@@ -377,11 +377,12 @@ class HVMImageHandler(ImageHandler):
# xm config file
def parseDeviceModelArgs(self, imageConfig, deviceConfig):
dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
'localtime', 'serial', 'stdvga', 'isa', 'vcpus',
'localtime', 'serial', 'stdvga', 'isa',
'acpi', 'usb', 'usbdevice', 'keymap' ]
ret = []
hvmDeviceConfig = imageConfig['hvm']['devices']
ret = ['-vcpus', str(self.vm.getVCpuCount())]
for a in dmargs:
v = hvmDeviceConfig.get(a)
@@ -461,14 +462,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 ' +
@@ -478,7 +479,7 @@ class HVMImageHandler(ImageHandler):
return ret
def createDeviceModel(self):
def createDeviceModel(self, restore = False):
if self.pid:
return
# Execute device model.
@@ -487,6 +488,8 @@ class HVMImageHandler(ImageHandler):
args = args + ([ "-d", "%d" % self.vm.getDomid(),
"-m", "%s" % (self.getRequiredInitialReservation() / 1024)])
args = args + self.dmargs
if restore:
args = args + ([ "-loadvm", "/tmp/xen.qemu-dm.%d" % self.vm.getDomid() ])
env = dict(os.environ)
if self.display:
env['DISPLAY'] = self.display
@@ -505,12 +508,16 @@ class HVMImageHandler(ImageHandler):
self.register_reboot_feature_watch()
self.pid = self.vm.gatherDom(('image/device-model-pid', int))
def destroy(self):
def destroy(self, suspend = False):
self.unregister_shutdown_watch()
self.unregister_reboot_feature_watch();
if self.pid:
try:
os.kill(self.pid, signal.SIGKILL)
sig = signal.SIGKILL
if suspend:
log.info("use sigusr1 to signal qemu %d", self.pid)
sig = signal.SIGUSR1
os.kill(self.pid, sig)
except OSError, exn:
log.exception(exn)
try:
+10
View File
@@ -33,9 +33,19 @@ _pygrub_path = {
"SunOS": "/usr/lib/xen/bin/pygrub"
}
_netback_type = {
"SunOS": "SUNW_mac"
}
_vif_script = {
"SunOS": "vif-vnic"
}
def _get(var, default=None):
return var.get(os.uname()[0], default)
scripts_dir = _get(_scripts_dir, "/etc/xen/scripts")
xend_autorestart = _get(_xend_autorestart)
pygrub_path = _get(_pygrub_path, "/usr/bin/pygrub")
netback_type = _get(_netback_type, "netfront")
vif_script = _get(_vif_script, "vif-bridge")
@@ -19,7 +19,7 @@
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" %
+1 -1
View File
@@ -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' ),
+22 -36
View File
@@ -48,7 +48,7 @@ from threading import Thread
from xen.web.httpserver import HttpServer, UnixHttpServer
from xen.xend import XendNode, XendRoot, XendAPI
from xen.xend import XendNode, 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 xen.web.SrvDir import SrvDir
from SrvRoot import SrvRoot
from XMLRPCServer import XMLRPCServer
xroot = XendRoot.instance()
xoptions = XendOptions.instance()
class XendServers:
@@ -65,6 +65,7 @@ class XendServers:
def __init__(self, root):
self.servers = []
self.root = root
self.running = False
self.cleaningUp = False
self.reloadingConfig = False
@@ -79,6 +80,7 @@ class XendServers:
server.shutdown()
except:
pass
self.running = False
def reloadConfig(self, signum = 0, frame = None):
log.debug("SrvServer.reloadConfig()")
@@ -107,13 +109,12 @@ class XendServers:
if server.ready:
continue
thread = Thread(target=server.run, name=server.__class__.__name__)
if isinstance(server, HttpServer):
thread.setDaemon(True)
thread = Thread(target=server.run,
name=server.__class__.__name__)
thread.setDaemon(True)
thread.start()
threads.append(thread)
# check for when all threads have initialized themselves and then
# close the status pipe
@@ -143,47 +144,32 @@ class XendServers:
status.close()
status = None
# Interruptible Thread.join - Python Bug #1167930
# Replaces: for t in threads: t.join()
# Reason: The above will cause python signal handlers to be
# blocked so we're not able to catch SIGTERM in any
# way for cleanup
runningThreads = threads
while len(runningThreads) > 0:
try:
for t in threads:
t.join(1.0)
runningThreads = [t for t in threads
if t.isAlive() and not t.isDaemon()]
if self.cleaningUp and len(runningThreads) > 0:
log.debug("Waiting for %s." %
[x.getName() for x in runningThreads])
except:
pass
# loop to keep main thread alive until it receives a SIGTERM
self.running = True
while self.running:
time.sleep(100000000)
if self.reloadingConfig:
log.info("Restarting all XML-RPC and Xen-API servers...")
self.cleaningUp = False
self.reloadingConfig = False
xroot.set_config()
new_servers = [x for x in self.servers
if isinstance(x, HttpServer)]
self.servers = new_servers
xoptions.set_config()
self.servers = []
_loadConfig(self, self.root, True)
else:
break
def _loadConfig(servers, root, reload):
if not reload and xroot.get_xend_http_server():
if 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 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(':'),
@@ -218,10 +204,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))
+9 -6
View File
@@ -179,21 +179,24 @@ class XMLRPCServer:
# Custom runloop so we can cleanup when exiting.
# -----------------------------------------------------------------
try:
self.server.socket.settimeout(1.0)
while self.running:
self.server.handle_request()
finally:
self.cleanup()
self.shutdown()
def cleanup(self):
log.debug("XMLRPCServer.cleanup()")
log.debug('XMLRPCServer.cleanup()')
try:
self.server.socket.close()
if hasattr(self, 'server'):
# shutdown socket explicitly to allow reuse
self.server.socket.shutdown(socket.SHUT_RDWR)
self.server.socket.close()
except Exception, exn:
log.exception(exn)
pass
def shutdown(self):
self.running = False
self.ready = False
if self.ready:
self.ready = False
self.cleanup()
+6 -7
View File
@@ -24,10 +24,10 @@ import os
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')
@@ -150,9 +150,8 @@ class NetifController(DevController):
devid = self.allocateDeviceID()
# The default type is 'netfront'.
if not typ:
typ = 'netfront'
typ = xoptions.netback_type
if not mac:
mac = randomMAC()
@@ -190,7 +189,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
+7 -7
View File
@@ -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.Protocol):
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:
@@ -2,9 +2,9 @@ import os
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_DOMID = 42
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))
+4 -4
View File
@@ -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 @@ from xen.xend.server.DevController import DevController
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)
+2 -2
View File
@@ -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 + int(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":
+5 -1
View File
@@ -190,6 +190,10 @@ gopts.var('vcpus', val='VCPUS',
fn=set_int, default=1,
use="# of Virtual CPUS in domain.")
gopts.var('vcpu_avail', val='VCPUS',
fn=set_long, default=None,
use="Bitmask for virtual CPUs to make available immediately.")
gopts.var('cpu_cap', val='CAP',
fn=set_int, default=None,
use="""Set the maximum amount of cpu.
@@ -740,7 +744,7 @@ def make_config(vals):
map(add_conf, ['name', 'memory', 'maxmem', 'shadow_memory',
'restart', 'on_poweroff',
'on_reboot', 'on_crash', 'vcpus', 'features',
'on_reboot', 'on_crash', 'vcpus', 'vcpu_avail', 'features',
'on_xend_start', 'on_xend_stop'])
if vals.uuid is not None:
+8 -5
View File
@@ -693,12 +693,15 @@ def parse_doms_info(info):
up_time = time.time() - start_time
return {
'domid' : get_info('domid', str, ''),
'name' : get_info('name', str, '??'),
'domid' : get_info('domid', str, ''),
'name' : get_info('name', str, '??'),
'mem' : get_info('memory_dynamic_min', int, 0),
'vcpus' : get_info('online_vcpus', int, 0),
'state' : get_info('state', str, ''),
'cpu_time' : get_info('cpu_time', float, 0),
'state' : get_info('state', str, ''),
'cpu_time' : get_info('cpu_time', float, 0.0),
# VCPUs is the number online when the VM is up, or the number
# configured otherwise.
'vcpus' : get_info('online_vcpus', int,
get_info('vcpus', int, 0)),
'up_time' : up_time,
'seclabel' : security.get_security_printlabel(info),
}
+8
View File
@@ -571,6 +571,14 @@ def set_int(opt, k, v):
opt.opts.err('Invalid value: ' + str(v))
opt.set(v)
def set_long(opt, k, v):
"""Set an option to a long integer value."""
try:
v = long(v)
except:
opt.opts.err('Invalid value: ' + str(v))
opt.set(v)
def set_float(opt, k, v):
"""Set an option to a float value."""
try:
+2 -2
View File
@@ -3,9 +3,9 @@ import os.path
import tempfile
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'
import xen.xm.create
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.