merge with xen-unstable.hg (staging)

This commit is contained in:
Alex Williamson committed 2007-06-11 13:46:42 -06:00
commit 6fe1b92429
648 files changed
+7102 -173652

No files matched your search

+111 -5
View File
@@ -1,10 +1,11 @@
/****************************************************************
* acm.c
*
* Copyright (C) 2006 IBM Corporation
* Copyright (C) 2006,2007 IBM Corporation
*
* Authors:
* Reiner Sailer <sailer@watson.ibm.com>
* Stefan Berger <stefanb@us.ibm.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -53,7 +54,6 @@ void * __getssid(int domid, uint32_t *buflen)
goto out2;
}
memset(buf, 0, SSID_BUFFER_SIZE);
getssid.interface_version = ACM_INTERFACE_VERSION;
set_xen_guest_handle(getssid.ssidbuf, buf);
getssid.ssidbuf_size = SSID_BUFFER_SIZE;
getssid.get_ssid_by = ACM_GETBY_domainid;
@@ -163,7 +163,6 @@ static PyObject *getdecision(PyObject * self, PyObject * args)
(strcmp(arg2_name, "domid") && strcmp(arg2_name, "ssidref")))
return NULL;
getdecision.interface_version = ACM_INTERFACE_VERSION;
getdecision.hook = ACMHOOK_sharing;
if (!strcmp(arg1_name, "domid")) {
getdecision.get_decision_by1 = ACM_GETBY_domainid;
@@ -199,13 +198,120 @@ static PyObject *getdecision(PyObject * self, PyObject * args)
return Py_BuildValue("s", decision);
}
/* error messages for exceptions */
const char bad_arg[] = "Bad function argument.";
const char ctrlif_op[] = "Could not open control interface.";
const char hv_op_err[] = "Error from hypervisor operation.";
static PyObject *chgpolicy(PyObject *self, PyObject *args)
{
struct acm_change_policy chgpolicy;
int xc_handle, rc;
char *bin_pol = NULL, *del_arr = NULL, *chg_arr = NULL;
int bin_pol_len = 0, del_arr_len = 0, chg_arr_len = 0;
uint errarray_mbrs = 20 * 2;
uint32_t error_array[errarray_mbrs];
PyObject *result;
uint len;
memset(&chgpolicy, 0x0, sizeof(chgpolicy));
if (!PyArg_ParseTuple(args, "s#s#s#" ,&bin_pol, &bin_pol_len,
&del_arr, &del_arr_len,
&chg_arr, &chg_arr_len)) {
PyErr_SetString(PyExc_TypeError, bad_arg);
return NULL;
}
chgpolicy.policy_pushcache_size = bin_pol_len;
chgpolicy.delarray_size = del_arr_len;
chgpolicy.chgarray_size = chg_arr_len;
chgpolicy.errarray_size = sizeof(error_array);
set_xen_guest_handle(chgpolicy.policy_pushcache, bin_pol);
set_xen_guest_handle(chgpolicy.del_array, del_arr);
set_xen_guest_handle(chgpolicy.chg_array, chg_arr);
set_xen_guest_handle(chgpolicy.err_array, error_array);
if ((xc_handle = xc_interface_open()) <= 0) {
PyErr_SetString(PyExc_IOError, ctrlif_op);
return NULL;
}
rc = xc_acm_op(xc_handle, ACMOP_chgpolicy, &chgpolicy, sizeof(chgpolicy));
xc_interface_close(xc_handle);
/* only pass the filled error codes */
for (len = 0; (len + 1) < errarray_mbrs; len += 2) {
if (error_array[len] == 0) {
len *= sizeof(error_array[0]);
break;
}
}
result = Py_BuildValue("is#", rc, error_array, len);
return result;
}
static PyObject *relabel_domains(PyObject *self, PyObject *args)
{
struct acm_relabel_doms reldoms;
int xc_handle, rc;
char *relabel_rules = NULL;
int rel_rules_len = 0;
uint errarray_mbrs = 20 * 2;
uint32_t error_array[errarray_mbrs];
PyObject *result;
uint len;
memset(&reldoms, 0x0, sizeof(reldoms));
if (!PyArg_ParseTuple(args, "s#" ,&relabel_rules, &rel_rules_len)) {
PyErr_SetString(PyExc_TypeError, bad_arg);
return NULL;
}
reldoms.relabel_map_size = rel_rules_len;
reldoms.errarray_size = sizeof(error_array);
set_xen_guest_handle(reldoms.relabel_map, relabel_rules);
set_xen_guest_handle(reldoms.err_array, error_array);
if ((xc_handle = xc_interface_open()) <= 0) {
PyErr_SetString(PyExc_IOError, ctrlif_op);
return NULL;
}
rc = xc_acm_op(xc_handle, ACMOP_relabeldoms, &reldoms, sizeof(reldoms));
xc_interface_close(xc_handle);
/* only pass the filled error codes */
for (len = 0; (len + 1) < errarray_mbrs; len += 2) {
if (error_array[len] == 0) {
len *= sizeof(error_array[0]);
break;
}
}
result = Py_BuildValue("is#", rc, error_array, len);
return result;
}
/*=================General Python Extension Declarations=================*/
/* methods */
static PyMethodDef acmMethods[] = {
{"policy", policy, METH_VARARGS, "Retrieve Active ACM Policy Reference Name"},
{"getssid", getssid, METH_VARARGS, "Retrieve label information and ssidref for a domain"},
{"policy", policy, METH_VARARGS, "Retrieve Active ACM Policy Reference Name"},
{"getssid", getssid, METH_VARARGS, "Retrieve label information and ssidref for a domain"},
{"getdecision", getdecision, METH_VARARGS, "Retrieve ACM access control decision"},
{"chgpolicy", chgpolicy, METH_VARARGS, "Change the policy in one step"},
{"relabel_domains", relabel_domains, METH_VARARGS, "Relabel domains"},
/* end of list (extend list above this line) */
{NULL, NULL, 0, NULL}
};
+59 -8
View File
@@ -54,9 +54,9 @@ static PyObject *pyxc_error_to_exception(void)
return PyErr_SetFromErrno(xc_error_obj);
if ( err->message[0] != '\0' )
pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
else
pyerr = Py_BuildValue("(is)", err->code, desc);
pyerr = Py_BuildValue("(is)", err->code, desc);
xc_clear_last_error();
@@ -163,6 +163,16 @@ static PyObject *pyxc_domain_unpause(XcObject *self, PyObject *args)
return dom_op(self, args, xc_domain_unpause);
}
static PyObject *pyxc_domain_destroy_hook(XcObject *self, PyObject *args)
{
#ifdef __ia64__
dom_op(self, args, xc_ia64_save_to_nvram);
#endif
Py_INCREF(zero);
return zero;
}
static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
{
return dom_op(self, args, xc_domain_destroy);
@@ -407,6 +417,7 @@ static PyObject *pyxc_linux_build(XcObject *self,
unsigned long console_mfn = 0;
PyObject* elfnote_dict;
PyObject* elfnote = NULL;
PyObject* ret;
int i;
static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
@@ -425,7 +436,7 @@ static PyObject *pyxc_linux_build(XcObject *self,
xc_dom_loginit();
if (!(dom = xc_dom_allocate(cmdline, features)))
return pyxc_error_to_exception();
return pyxc_error_to_exception();
if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
ramdisk, flags, store_evtchn, &store_mfn,
@@ -455,12 +466,22 @@ static PyObject *pyxc_linux_build(XcObject *self,
Py_DECREF(elfnote);
}
ret = Py_BuildValue("{s:i,s:i,s:N}",
"store_mfn", store_mfn,
"console_mfn", console_mfn,
"notes", elfnote_dict);
if ( dom->arch_hooks->native_protocol )
{
PyObject *native_protocol =
Py_BuildValue("s", dom->arch_hooks->native_protocol);
PyDict_SetItemString(ret, "native_protocol", native_protocol);
Py_DECREF(native_protocol);
}
xc_dom_release(dom);
return Py_BuildValue("{s:i,s:i,s:N}",
"store_mfn", store_mfn,
"console_mfn", console_mfn,
"notes", elfnote_dict);
return ret;
out:
xc_dom_release(dom);
@@ -487,6 +508,23 @@ static PyObject *pyxc_get_hvm_param(XcObject *self,
}
#ifdef __ia64__
static PyObject *pyxc_nvram_init(XcObject *self,
PyObject *args)
{
char *dom_name;
uint32_t dom;
if ( !PyArg_ParseTuple(args, "si", &dom_name, &dom) )
return NULL;
xc_ia64_nvram_init(self->xc_handle, dom_name, dom);
Py_INCREF(zero);
return zero;
}
#endif /* __ia64__ */
static PyObject *pyxc_hvm_build(XcObject *self,
PyObject *args,
PyObject *kwds)
@@ -1145,6 +1183,13 @@ static PyMethodDef pyxc_methods[] = {
" dom [int]: Identifier of domain to be destroyed.\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "domain_destroy_hook",
(PyCFunction)pyxc_domain_destroy_hook,
METH_VARARGS, "\n"
"Add a hook for arch stuff before destroy a domain.\n"
" dom [int]: Identifier of domain to be destroyed.\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "domain_resume",
(PyCFunction)pyxc_domain_resume,
METH_VARARGS, "\n"
@@ -1386,7 +1431,13 @@ static PyMethodDef pyxc_methods[] = {
" dom [int]: Identifier of domain.\n"
" mem_kb [long]: .\n"
"Returns: [int] 0 on success; -1 on error.\n" },
#ifdef __ia64__
{ "nvram_init",
(PyCFunction)pyxc_nvram_init,
METH_VARARGS, "\n"
"Init nvram in IA64 platform\n"
"Returns: [int] 0 on success; -1 on error.\n" },
#endif /* __ia64__ */
{ "domain_ioport_permission",
(PyCFunction)pyxc_domain_ioport_permission,
METH_VARARGS | METH_KEYWORDS, "\n"
+20 -6
View File
@@ -882,7 +882,8 @@ class XendAPI(object):
host_attr_rw = ['name_label',
'name_description',
'other_config']
'other_config',
'logging']
host_methods = [('disable', None),
('enable', None),
@@ -957,7 +958,11 @@ class XendAPI(object):
return xen_api_success(XendNode.instance().get_vcpus_policy())
def host_get_cpu_configuration(self, _, host_ref):
return xen_api_success(XendNode.instance().get_cpu_configuration())
def host_set_logging(self, _, host_ref, logging):
return xen_api_todo()
def host_get_logging(self, _, host_ref):
return xen_api_todo()
# object methods
def host_disable(self, session, host_ref):
XendDomain.instance().set_allow_new_domains(False)
@@ -1010,7 +1015,10 @@ class XendAPI(object):
'metrics': node.host_metrics_uuid,
'capabilities': node.get_capabilities(),
'supported_bootloaders': ['pygrub'],
'sched_policy': node.get_vcpus_policy()}
'sched_policy': node.get_vcpus_policy(),
'logging': {},
'PIFs': XendPIF.get_all(),
'PBDs': XendPBD.get_all()}
return xen_api_success(record)
# class methods
@@ -1133,7 +1141,8 @@ class XendAPI(object):
'tools_version',
'domid',
'is_control_domain',
'metrics'
'metrics',
'crash_dumps',
]
VM_attr_rw = ['name_label',
@@ -1572,6 +1581,9 @@ class XendAPI(object):
else:
return xen_api_success_void()
def VM_get_crash_dumps(self, _, vm_ref):
return xen_api_todo()
# class methods
def VM_get_all(self, session):
refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
@@ -1636,7 +1648,8 @@ class XendAPI(object):
'other_config': xeninfo.info.get('other_config', {}),
'domid': domid is None and -1 or domid,
'is_control_domain': xeninfo.info['is_control_domain'],
'metrics': xeninfo.get_metrics()
'metrics': xeninfo.get_metrics(),
'crash_dumps': []
}
return xen_api_success(record)
@@ -1767,6 +1780,7 @@ class XendAPI(object):
return_cfg[k] = cfg[k]
return_cfg['metrics'] = vbd_ref
return_cfg['runtime_properties'] = {} #todo
return xen_api_success(return_cfg)
@@ -1836,7 +1850,7 @@ class XendAPI(object):
try:
devid = int(device['id'])
device_sxps = dominfo.getDeviceSxprs('vbd')
device_dicts = [dict(device_sxp[1][1:]) for device_sxp in device_sxps]
device_dicts = [dict(device_sxp[1][0:]) for device_sxp in device_sxps]
device_dict = [device_dict
for device_dict in device_dicts
if int(device_dict['virtual-device']) == devid][0]
+1 -1
View File
@@ -87,7 +87,7 @@ class XendAuthSessions:
pam_auth.start("login")
pam_auth.set_item(PAM.PAM_USER, username)
def _pam_conv(auth, query_list, user_data):
def _pam_conv(auth, query_list, user_data = None):
resp = []
for i in range(len(query_list)):
query, qtype = query_list[i]
+4 -3
View File
@@ -111,7 +111,8 @@ def save(fd, dominfo, network, live, dst, checkpoint=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)
qemu_fd = os.open("/var/lib/xen/qemu-save.%d" % dominfo.getDomid(),
os.O_RDONLY)
while True:
buf = os.read(qemu_fd, dm_batch)
if len(buf):
@@ -119,7 +120,7 @@ def save(fd, dominfo, network, live, dst, checkpoint=False):
else:
break
os.close(qemu_fd)
os.remove("/tmp/xen.qemu-dm.%d" % dominfo.getDomid())
os.remove("/var/lib/xen/qemu-save.%d" % dominfo.getDomid())
if checkpoint:
dominfo.resumeDomain()
@@ -238,7 +239,7 @@ def restore(xd, fd, dominfo = None, paused = False):
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(),
qemu_fd = os.open("/var/lib/xen/qemu-save.%d" % dominfo.getDomid(),
os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
while True:
buf = os.read(fd, dm_batch)
+64 -25
View File
@@ -27,6 +27,7 @@ from xen.xend.XendError import VmError
from xen.xend.XendDevices import XendDevices
from xen.xend.PrettyPrint import prettyprintstring
from xen.xend.XendConstants import DOM_STATE_HALTED
from xen.xend.server.netif import randomMAC
log = logging.getLogger("xend.XendConfig")
log.setLevel(logging.WARN)
@@ -587,30 +588,46 @@ class XendConfig(dict):
else:
cfg['cpus'] = str(cfg['cpu'])
# convert 'cpus' string to list of ints
# 'cpus' supports a list of ranges (0-3), seperated by
# commas, and negation, (^1).
# Precedence is settled by order of the string:
# "0-3,^1" -> [0,2,3]
# "0-3,^1,1" -> [0,1,2,3]
try:
if 'cpus' in cfg and type(cfg['cpus']) != list:
cpus = []
for c in cfg['cpus'].split(','):
if c.find('-') != -1:
(x, y) = c.split('-')
for i in range(int(x), int(y)+1):
cpus.append(int(i))
else:
# remove this element from the list
if c[0] == '^':
cpus = [x for x in cpus if x != int(c[1:])]
# Convert 'cpus' to list of ints
if 'cpus' in cfg:
cpus = []
if type(cfg['cpus']) == list:
# If sxp_cfg was created from config.sxp,
# the form of 'cpus' is list of string.
# Convert 'cpus' to list of ints.
# ['1'] -> [1]
# ['0','2','3'] -> [0,2,3]
try:
for c in cfg['cpus']:
cpus.append(int(c))
cfg['cpus'] = cpus
except ValueError, e:
raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
else:
# Convert 'cpus' string to list of ints
# 'cpus' supports a list of ranges (0-3),
# seperated by commas, and negation, (^1).
# Precedence is settled by order of the
# string:
# "0-3,^1" -> [0,2,3]
# "0-3,^1,1" -> [0,1,2,3]
try:
for c in cfg['cpus'].split(','):
if c.find('-') != -1:
(x, y) = c.split('-')
for i in range(int(x), int(y)+1):
cpus.append(int(i))
else:
cpus.append(int(c))
cfg['cpus'] = cpus
except ValueError, e:
raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
# remove this element from the list
if c[0] == '^':
cpus = [x for x in cpus if x != int(c[1:])]
else:
cpus.append(int(c))
cfg['cpus'] = cpus
except ValueError, e:
raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
if 'security' in cfg and isinstance(cfg['security'], str):
cfg['security'] = sxp.from_string(cfg['security'])
@@ -842,6 +859,8 @@ class XendConfig(dict):
if name in self and self[name] not in (None, []):
if typ == dict:
s = self[name].items()
elif typ == list:
s = self[name]
else:
s = str(self[name])
sxpr.append([name, s])
@@ -975,6 +994,10 @@ class XendConfig(dict):
else:
dev_info['driver'] = 'paravirtualised'
if dev_type == 'vif':
if not dev_info.get('mac'):
dev_info['mac'] = randomMAC()
# create uuid if it doesn't exist
dev_uuid = dev_info.get('uuid', None)
if not dev_uuid:
@@ -1033,8 +1056,9 @@ class XendConfig(dict):
dev_info = {}
dev_uuid = ''
if dev_type == 'vif':
if cfg_xenapi.get('MAC'): # don't add if blank
dev_info['mac'] = cfg_xenapi.get('MAC')
dev_info['mac'] = cfg_xenapi.get('MAC')
if not dev_info['mac']:
dev_info['mac'] = randomMAC()
# vifname is the name on the guest, not dom0
# TODO: we don't have the ability to find that out or
# change it from dom0
@@ -1250,6 +1274,21 @@ class XendConfig(dict):
return False
def device_remove(self, dev_uuid):
"""Remove an existing device referred by dev_uuid.
"""
if dev_uuid in self['devices']:
dev_config = self['devices'].get(dev_uuid)
dev_type = dev_config[0]
del self['devices'][dev_uuid]
# Remove dev references for certain device types (see device_add)
if dev_type in ('vif', 'vbd', 'vtpm'):
param = '%s_refs' % dev_type
if param in self:
if dev_uuid in self[param]:
self[param].remove(dev_uuid)
def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None):
"""Get Device SXPR by either giving the device UUID or (type, config).
+1 -1
View File
@@ -79,7 +79,7 @@ DOM_STATES_OLD = [
STATE_DOM_OK = 1
STATE_DOM_SHUTDOWN = 2
SHUTDOWN_TIMEOUT = 30.0
SHUTDOWN_TIMEOUT = (60.0 * 5)
ZOMBIE_PREFIX = 'Zombie-'
+24 -3
View File
@@ -985,10 +985,16 @@ class XendDomain:
dominfo.start(is_managed = True)
finally:
self.domains_lock.release()
dominfo.waitForDevices()
try:
dominfo.waitForDevices()
except Exception, ex:
log.warn("Failed to setup devices for " + str(dominfo) + ": " + str(ex))
dominfo.destroy()
raise
if not start_paused:
dominfo.unpause()
def domain_delete(self, domid):
"""Remove a managed domain from database
@@ -1082,6 +1088,9 @@ class XendDomain:
try:
return XendCheckpoint.restore(self, fd, paused=paused)
except XendError, e:
log.exception("Restore failed")
raise
except:
# I don't really want to log this exception here, but the error
# handling in the relocation-socket handling code (relocate.py) is
@@ -1402,6 +1411,8 @@ class XendDomain:
@type cap: int
@rtype: 0
"""
set_weight = False
set_cap = False
dominfo = self.domain_lookup_nr(domid)
if not dominfo:
raise XendInvalidDomain(str(domid))
@@ -1410,16 +1421,26 @@ class XendDomain:
weight = int(0)
elif weight < 1 or weight > 65535:
raise XendError("weight is out of range")
else:
set_weight = True
if cap is None:
cap = int(~0)
elif cap < 0 or cap > dominfo.getVCpuCount() * 100:
raise XendError("cap is out of range")
else:
set_cap = True
assert type(weight) == int
assert type(cap) == int
return xc.sched_credit_domain_set(dominfo.getDomid(), weight, cap)
rc = xc.sched_credit_domain_set(dominfo.getDomid(), weight, cap)
if rc == 0:
if set_weight:
dominfo.setWeight(weight)
if set_cap:
dominfo.setCap(cap)
return rc
except Exception, ex:
log.exception(ex)
raise XendError(str(ex))
+56 -35
View File
@@ -357,6 +357,8 @@ class XendDomainInfo:
self.console_port = None
self.console_mfn = None
self.native_protocol = None
self.vmWatch = None
self.shutdownWatch = None
self.shutdownStartTime = None
@@ -545,20 +547,33 @@ class XendDomainInfo:
def destroyDevice(self, deviceClass, devid, force = False):
try:
devid = int(devid)
dev = int(devid)
except ValueError:
# devid is not a number, let's search for it in xenstore.
devicePath = '%s/device/%s' % (self.dompath, deviceClass)
for entry in xstransact.List(devicePath):
backend = xstransact.Read('%s/%s' % (devicePath, entry),
"backend")
devName = xstransact.Read(backend, "dev")
if devName == devid:
# We found the integer matching our devid, use it instead
devid = entry
break
return self.getDeviceController(deviceClass).destroyDevice(devid, force)
# devid is not a number but a string containing either device
# name (e.g. xvda) or device_type/device_id (e.g. vbd/51728)
dev = type(devid) is str and devid.split('/')[-1] or None
if dev == None:
log.debug("Could not find the device %s", devid)
return None
log.debug("dev = %s", dev)
dev_control = self.getDeviceController(deviceClass)
dev_uuid = dev_control.readBackend(dev, 'uuid')
ret = None
try:
ret = dev_control.destroyDevice(dev, force)
except EnvironmentError:
# We failed to detach the device
raise VmError("Failed to detach device %d" % dev)
# update XendConfig
if dev_uuid:
self.info.device_remove(dev_uuid)
return ret
def getDeviceSxprs(self, deviceClass):
if self._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED):
@@ -572,7 +587,6 @@ class XendDomainInfo:
dev_num += 1
return sxprs
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@param target: In MiB.
@@ -600,7 +614,7 @@ class XendDomainInfo:
raise XendError('Invalid memory size')
MiB = 1024 * 1024
self.info['memory_static_max'] = limit * MiB
self._safe_set_memory('memory_static_max', limit * MiB)
if self.domid >= 0:
maxmem = int(limit) * 1024
@@ -1007,9 +1021,15 @@ class XendDomainInfo:
def getCap(self):
return self.info.get('cpu_cap', 0)
def setCap(self, cpu_cap):
self.info['cpu_cap'] = cpu_cap
def getWeight(self):
return self.info.get('cpu_weight', 256)
def setWeight(self, cpu_weight):
self.info['cpu_weight'] = cpu_weight
def setResume(self, state):
self._resume = state
@@ -1110,8 +1130,8 @@ class XendDomainInfo:
# failed. Ignore this domain.
pass
else:
# Domain is alive. If we are shutting it down, then check
# the timeout on that, and destroy it if necessary.
# Domain is alive. If we are shutting it down, log a message
# if it seems unresponsive.
if xeninfo['paused']:
self._stateSet(DOM_STATE_PAUSED)
else:
@@ -1120,11 +1140,11 @@ class XendDomainInfo:
if self.shutdownStartTime:
timeout = (SHUTDOWN_TIMEOUT - time.time() +
self.shutdownStartTime)
if timeout < 0:
if (timeout < 0 and not self.readDom('xend/unresponsive')):
log.info(
"Domain shutdown timeout expired: name=%s id=%s",
self.info['name_label'], self.domid)
self.destroy()
self.storeDom('xend/unresponsive', 'True')
finally:
self.refresh_shutdown_lock.release()
@@ -1330,20 +1350,19 @@ class XendDomainInfo:
self.image.destroy(suspend)
return
while True:
t = xstransact("%s/device" % self.dompath)
for devclass in XendDevices.valid_devices():
for dev in t.list(devclass):
try:
t.remove(dev)
except:
# Log and swallow any exceptions in removal --
# there's nothing more we can do.
log.exception(
"Device release failed: %s; %s; %s",
self.info['name_label'], devclass, dev)
if t.commit():
break
t = xstransact("%s/device" % self.dompath)
for devclass in XendDevices.valid_devices():
for dev in t.list(devclass):
try:
log.debug("Removing %s", dev);
self.destroyDevice(devclass, dev, False);
except:
# Log and swallow any exceptions in removal --
# there's nothing more we can do.
log.exception("Device release failed: %s; %s; %s",
self.info['name_label'], devclass, dev)
def getDeviceController(self, name):
"""Get the device controller for this domain, and if it
@@ -1520,6 +1539,8 @@ class XendDomainInfo:
self.console_mfn = channel_details['console_mfn']
if 'notes' in channel_details:
self.info.set_notes(channel_details['notes'])
if 'native_protocol' in channel_details:
self.native_protocol = channel_details['native_protocol'];
self._introduceDomain()
@@ -1662,6 +1683,7 @@ class XendDomainInfo:
self._cleanupVm()
if self.dompath is not None:
xc.domain_destroy_hook(self.domid)
self.destroyDomain()
self._cleanup_phantom_devs(paths)
@@ -1680,7 +1702,6 @@ class XendDomainInfo:
try:
if self.domid is not None:
xc.domain_destroy(self.domid)
self.domid = None
for state in DOM_STATES_OLD:
self.info[state] = 0
self._stateSet(DOM_STATE_HALTED)
@@ -2061,7 +2082,7 @@ class XendDomainInfo:
raise VmError('Invalid VM Name')
dom = XendDomain.instance().domain_lookup_nr(name)
if dom and dom.info['uuid'] != self.info['uuid']:
if dom and dom.domid != self.domid:
raise VmError("VM name '%s' already exists%s" %
(name,
dom.domid is not None and
+4 -3
View File
@@ -195,7 +195,7 @@ class XendNode:
network_uuid, 'network')
if network.get_name_label() == bridge_name:
XendPIF.create_phy(network_uuid, name,
mtu, mac)
mac, mtu)
break
else:
log.debug("Cannot find network for bridge %s "
@@ -233,8 +233,9 @@ class XendNode:
## self.save_networks()
## def get_PIF_refs(self):
## return self.pifs[:]
def get_PIF_refs(self):
log.debug(XendPIF.get_all())
return XendPIF.get_all()
## def _PIF_create(self, name, mtu, vlan, mac, network, persist = True,
## pif_uuid = None, metrics_uuid = None):
+1 -1
View File
@@ -117,7 +117,7 @@ class XendVMMetrics(XendBase):
except Exception, err:
# ignore missing domain
log.trace("domain_getinfo(%d) failed, ignoring: %s", domid, str(err))
return ""
return []
def get_VCPUs_params(self):
domid = self.xend_domain_instance.getDomid()
+4 -1
View File
@@ -102,6 +102,7 @@ def free(need_mem):
retries = 0
sleep_time = SLEEP_TIME_GROWTH
last_new_alloc = None
last_free = None
rlimit = RETRY_LIMIT
while retries < rlimit:
physinfo = xc.physinfo()
@@ -140,7 +141,9 @@ def free(need_mem):
time.sleep(sleep_time)
if retries < 2 * RETRY_LIMIT:
sleep_time += SLEEP_TIME_GROWTH
retries += 1
if last_free != None and last_free >= free_mem + scrub_mem:
retries += 1
last_free = free_mem + scrub_mem
# Not enough memory; diagnose the problem.
if dom0_min_mem == 0:
+6 -3
View File
@@ -27,7 +27,6 @@ from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
from xen.xend.XendError import VmError, XendError, HVMRequired
from xen.xend.XendLogging import log
from xen.xend.XendOptions import instance as xenopts
from xen.xend.server.netif import randomMAC
from xen.xend.xenstore.xswatch import xswatch
from xen.xend import arch
@@ -351,7 +350,7 @@ class HVMImageHandler(ImageHandler):
nics += 1
mac = devinfo.get('mac')
if mac is None:
mac = randomMAC()
raise VmError("MAC address not specified or generated.")
bridge = devinfo.get('bridge', 'xenbr0')
model = devinfo.get('model', 'rtl8139')
ret.append("-net")
@@ -429,7 +428,7 @@ class HVMImageHandler(ImageHandler):
(self.getRequiredInitialReservation() / 1024) ])
args = args + self.dmargs
if restore:
args = args + ([ "-loadvm", "/tmp/xen.qemu-dm.%d" %
args = args + ([ "-loadvm", "/var/lib/xen/qemu-save.%d" %
self.vm.getDomid() ])
env = dict(os.environ)
if self.display:
@@ -469,6 +468,10 @@ class HVMImageHandler(ImageHandler):
class IA64_HVM_ImageHandler(HVMImageHandler):
def buildDomain(self):
xc.nvram_init(self.vm.getName(), self.vm.getDomid())
return HVMImageHandler.buildDomain(self)
def getRequiredAvailableMemory(self, mem_kb):
page_kb = 16
# ROM size for guest firmware, io page, xenstore page
+45 -3
View File
@@ -29,6 +29,7 @@ from xen.xend.xenstore.xswatch import xswatch
import os
DEVICE_CREATE_TIMEOUT = 100
DEVICE_DESTROY_TIMEOUT = 10
HOTPLUG_STATUS_NODE = "hotplug-status"
HOTPLUG_ERROR_NODE = "hotplug-error"
HOTPLUG_STATUS_ERROR = "error"
@@ -211,17 +212,34 @@ class DevController:
devid = int(devid)
frontpath = self.frontendPath(devid)
if frontpath:
backpath = xstransact.Read(frontpath, "backend")
# Modify online status /before/ updating state (latter is watched by
# drivers, so this ordering avoids a race).
self.writeBackend(devid, 'online', "0")
self.writeBackend(devid, 'state', str(xenbusState['Closing']))
if force:
frontpath = self.frontendPath(devid)
backpath = xstransact.Read(frontpath, "backend")
if backpath:
xstransact.Remove(backpath)
xstransact.Remove(frontpath)
if frontpath:
xstransact.Remove(frontpath)
return
# Wait till both frontpath and backpath are removed from
# xenstore, or timed out
if frontpath:
status = self.waitUntilDestroyed(frontpath)
if status == Timeout:
# Exception will be caught by destroyDevice in XendDomainInfo.py
raise EnvironmentError
if backpath:
status = self.waitUntilDestroyed(backpath)
if status == Timeout:
# Exception will be caught by destroyDevice in XendDomainInfo.py
raise EnvironmentError
self.vm._removeVm("device/%s/%d" % (self.deviceClass, devid))
@@ -459,6 +477,8 @@ class DevController:
'state' : str(xenbusState['Initialising'])
})
if self.vm.native_protocol:
frontDetails.update({'protocol' : self.vm.native_protocol})
backDetails.update({
'domain' : self.vm.getName(),
@@ -506,6 +526,16 @@ class DevController:
return (Missing, None)
def waitUntilDestroyed(self, path):
ev = Event()
result = { 'path': path, 'status': Timeout }
xswatch(path, destroyCallback, ev, result)
ev.wait(DEVICE_DESTROY_TIMEOUT)
return result['status']
def backendPath(self, backdom, devid):
"""Construct backend path given the backend domain and device id.
@@ -535,6 +565,18 @@ class DevController:
self.deviceClass)
def destroyCallback(devPath, ev, result):
log.debug("destroyCallback %s.", devPath)
list = xstransact.List(result['path'])
if list:
return 1
result['status'] = Missing
ev.set()
log.debug("destroyCallback %s is destroyed", result['path'])
return 0
def hotplugStatusCallback(statusPath, ev, result):
log.debug("hotplugStatusCallback %s.", statusPath)
+1 -1
View File
@@ -112,7 +112,7 @@ class NetifController(DevController):
typ = xoptions.netback_type
if not mac:
mac = randomMAC()
raise VmError("MAC address not specified or generated.")
devid = self.allocateDeviceID()
+2 -3
View File
@@ -62,9 +62,8 @@
##
# To bridge network traffic, like this:
#
# dom0: fake eth0 -> vif0.0 -+
# |
# bridge -> real eth0 -> the network
#
# dom0: ----------------- bridge -> real eth0 -> the network
# |
# domU: fake eth0 -> vifN.0 -+
#
+73 -31
View File
@@ -231,6 +231,7 @@ SUBCOMMAND_OPTIONS = {
),
'start': (
('-p', '--paused', 'Do not unpause domain after starting it'),
('-c', '--console_autoconnect', 'Connect to the console after the domain is created'),
),
'resume': (
('-p', '--paused', 'Do not unpause domain after resuming it'),
@@ -731,10 +732,13 @@ def xm_restore(args):
err("xm restore: Unable to read file %s" % savefile)
sys.exit(1)
if serverType == SERVER_XEN_API:
server.xenapi.VM.restore(savefile, paused)
else:
server.xend.domain.restore(savefile, paused)
try:
if serverType == SERVER_XEN_API:
server.xenapi.VM.restore(savefile, paused)
else:
server.xend.domain.restore(savefile, paused)
except Exception, ex:
err("%s" % ex.faultString)
def datetime_to_secs(v):
@@ -916,10 +920,10 @@ def domid_match(domid, info):
domid == str(info['domid'])
def xm_brief_list(doms):
print '%-40s %3s %5s %5s %10s %9s' % \
print '%-40s %5s %5s %5s %10s %9s' % \
('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)')
format = "%(name)-40s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s " \
format = "%(name)-40s %(domid)5s %(mem)5d %(vcpus)5d %(state)10s " \
"%(cpu_time)8.1f"
for dom in doms:
@@ -927,11 +931,11 @@ def xm_brief_list(doms):
print format % d
def xm_label_list(doms):
print '%-32s %3s %5s %5s %5s %9s %-8s' % \
print '%-32s %5s %5s %5s %5s %9s %-8s' % \
('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)', 'Label')
output = []
format = '%(name)-32s %(domid)3s %(mem)5d %(vcpus)5d %(state)10s ' \
format = '%(name)-32s %(domid)5s %(mem)5d %(vcpus)5d %(state)10s ' \
'%(cpu_time)8.1f %(seclabel)9s'
if serverType != SERVER_XEN_API:
@@ -1021,10 +1025,10 @@ def xm_vcpu_list(args):
doms = server.xend.domains(False)
dominfo = map(server.xend.domain.getVCPUInfo, doms)
print '%-32s %3s %5s %5s %5s %9s %s' % \
print '%-32s %5s %5s %5s %5s %9s %s' % \
('Name', 'ID', 'VCPU', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
format = '%(name)-32s %(domid)3d %(number)5d %(c)5s %(s)5s ' \
format = '%(name)-32s %(domid)5d %(number)5d %(c)5s %(s)5s ' \
' %(cpu_time)8.1f %(cpumap)s'
for dom in dominfo:
@@ -1125,29 +1129,67 @@ def xm_vcpu_list(args):
print format % locals()
def start_do_console(domain_name):
cpid = os.fork()
if cpid != 0:
for i in range(10):
# Catch failure of the create process
time.sleep(1)
(p, rv) = os.waitpid(cpid, os.WNOHANG)
if os.WIFEXITED(rv):
if os.WEXITSTATUS(rv) != 0:
sys.exit(os.WEXITSTATUS(rv))
try:
# Acquire the console of the created dom
if serverType == SERVER_XEN_API:
domid = server.xenapi.VM.get_domid(
get_single_vm(domain_name))
else:
dom = server.xend.domain(domain_name)
domid = int(sxp.child_value(dom, 'domid', '-1'))
console.execConsole(domid)
except:
pass
print("Could not start console\n");
sys.exit(0)
def xm_start(args):
arg_check(args, "start", 1, 2)
paused = False
console_autoconnect = False
try:
(options, params) = getopt.gnu_getopt(args, 'p', ['paused'])
(options, params) = getopt.gnu_getopt(args, 'cp', ['console_autoconnect','paused'])
for (k, v) in options:
if k in ('-p', '--paused'):
paused = True
if k in ('-c', '--console_autoconnect'):
console_autoconnect = True
if len(params) != 1:
raise OptionError("Expects 1 argument")
except getopt.GetoptError, opterr:
err(opterr)
usage('start')
paused = False
for (k, v) in options:
if k in ['-p', '--paused']:
paused = True
if len(params) != 1:
err("Wrong number of parameters")
usage('start')
dom = params[0]
if serverType == SERVER_XEN_API:
server.xenapi.VM.start(get_single_vm(dom), paused)
else:
server.xend.domain.start(dom, paused)
if console_autoconnect:
start_do_console(dom)
try:
if serverType == SERVER_XEN_API:
server.xenapi.VM.start(get_single_vm(dom), paused)
domid = int(server.xenapi.VM.get_domid(get_single_vm(dom)))
else:
server.xend.domain.start(dom, paused)
info = server.xend.domain(dom)
domid = int(sxp.child_value(info, 'domid', '-1'))
except:
raise
if domid == -1:
raise xmlrpclib.Fault(0, "Domain '%s' is not started" % dom)
def xm_delete(args):
arg_check(args, "delete", 1)
@@ -1384,7 +1426,7 @@ def xm_sched_sedf(args):
info['period'] = ns_to_ms(info['period'])
info['slice'] = ns_to_ms(info['slice'])
info['latency'] = ns_to_ms(info['latency'])
print( ("%(name)-32s %(domid)3d %(period)9.1f %(slice)9.1f" +
print( ("%(name)-32s %(domid)5d %(period)9.1f %(slice)9.1f" +
" %(latency)7.1f %(extratime)6d %(weight)6d") % info)
check_sched_type('sedf')
@@ -1430,7 +1472,7 @@ def xm_sched_sedf(args):
# print header if we aren't setting any parameters
if len(opts.keys()) == 0:
print '%-33s %-2s %-4s %-4s %-7s %-5s %-6s' % \
print '%-33s %4s %-4s %-4s %-7s %-5s %-6s' % \
('Name','ID','Period(ms)', 'Slice(ms)', 'Lat(ms)',
'Extra','Weight')
@@ -1494,7 +1536,7 @@ def xm_sched_credit(args):
err("Domain '%s' does not exist." % domid)
usage('sched-credit')
# print header if we aren't setting any parameters
print '%-33s %-2s %-6s %-4s' % ('Name','ID','Weight','Cap')
print '%-33s %4s %6s %4s' % ('Name','ID','Weight','Cap')
for d in doms:
try:
@@ -1516,7 +1558,7 @@ def xm_sched_credit(args):
info['name'] = d['name']
info['domid'] = int(d['domid'])
print( ("%(name)-32s %(domid)3d %(weight)6d %(cap)4d") % info)
print( ("%(name)-32s %(domid)5d %(weight)6d %(cap)4d") % info)
else:
if domid is None:
# place holder for system-wide scheduler parameters
@@ -1679,7 +1721,7 @@ def xm_uptime(args):
doms = getDomains(params, 'running')
if short_mode == 0:
print 'Name ID Uptime'
print '%-33s %4s %s ' % ('Name','ID','Uptime')
for dom in doms:
d = parse_doms_info(dom)
@@ -1713,7 +1755,7 @@ def xm_uptime(args):
upstring += ", " + d['name'] + " (" + d['domid'] + ")"
else:
upstring += ':%(seconds)02d' % vars()
upstring = ("%(name)-32s %(domid)3s " % d) + upstring
upstring = ("%(name)-32s %(domid)5s " % d) + upstring
print upstring
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.