This commit is contained in:
djm@kirby.fc.hp.com committed 2005-10-11 16:57:44 -06:00
commit e57d870ddd
80 files changed
+1910 -1514

No files matched your search

+94 -81
View File
@@ -80,8 +80,8 @@ static inline PyObject *pyvalue_str(char *val) {
static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwd_spec[] = { "path", NULL };
static char *arg_spec = "s|";
static char *kwd_spec[] = { "transaction", "path", NULL };
static char *arg_spec = "ss";
char *path = NULL;
struct xs_handle *xh = xshandle(self);
@@ -89,13 +89,19 @@ static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
unsigned int xsval_n = 0;
PyObject *val = NULL;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&path))
&thstr, &path))
goto exit;
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
xsval = xs_read(xh, path, &xsval_n);
xsval = xs_read(xh, th, path, &xsval_n);
Py_END_ALLOW_THREADS
if (!xsval) {
if (errno == ENOENT) {
@@ -123,8 +129,8 @@ static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwd_spec[] = { "path", "data", NULL };
static char *arg_spec = "ss#";
static char *kwd_spec[] = { "transaction", "path", "data", NULL };
static char *arg_spec = "sss#";
char *path = NULL;
char *data = NULL;
int data_n = 0;
@@ -133,13 +139,19 @@ static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds)
PyObject *val = NULL;
int xsval = 0;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&path, &data, &data_n))
&thstr, &path, &data, &data_n))
goto exit;
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
xsval = xs_write(xh, path, data, data_n);
xsval = xs_write(xh, th, path, data, data_n);
Py_END_ALLOW_THREADS
if (!xsval) {
PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -162,8 +174,8 @@ static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds)
static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwd_spec[] = { "path", NULL };
static char *arg_spec = "s|";
static char *kwd_spec[] = { "transaction", "path", NULL };
static char *arg_spec = "ss";
char *path = NULL;
struct xs_handle *xh = xshandle(self);
@@ -172,12 +184,20 @@ static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
unsigned int xsval_n = 0;
int i;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&thstr, &path))
goto exit;
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
xsval = xs_directory(xh, path, &xsval_n);
xsval = xs_directory(xh, th, path, &xsval_n);
Py_END_ALLOW_THREADS
if (!xsval) {
if (errno == ENOENT) {
@@ -205,20 +225,27 @@ static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
static PyObject *xspy_mkdir(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwd_spec[] = { "path", NULL };
static char *arg_spec = "s|";
static char *kwd_spec[] = { "transaction", "path", NULL };
static char *arg_spec = "ss";
char *path = NULL;
struct xs_handle *xh = xshandle(self);
PyObject *val = NULL;
int xsval = 0;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&thstr, &path))
goto exit;
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
xsval = xs_mkdir(xh, path);
xsval = xs_mkdir(xh, th, path);
Py_END_ALLOW_THREADS
if (!xsval) {
PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -240,20 +267,27 @@ static PyObject *xspy_mkdir(PyObject *self, PyObject *args, PyObject *kwds)
static PyObject *xspy_rm(PyObject *self, PyObject *args, PyObject *kwds)
{
static char *kwd_spec[] = { "path", NULL };
static char *arg_spec = "s|";
static char *kwd_spec[] = { "transaction", "path", NULL };
static char *arg_spec = "ss";
char *path = NULL;
struct xs_handle *xh = xshandle(self);
PyObject *val = NULL;
int xsval = 0;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&thstr, &path))
goto exit;
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
xsval = xs_rm(xh, path);
xsval = xs_rm(xh, th, path);
Py_END_ALLOW_THREADS
if (!xsval && errno != ENOENT) {
PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -276,8 +310,8 @@ static PyObject *xspy_rm(PyObject *self, PyObject *args, PyObject *kwds)
static PyObject *xspy_get_permissions(PyObject *self, PyObject *args,
PyObject *kwds)
{
static char *kwd_spec[] = { "path", NULL };
static char *arg_spec = "s|";
static char *kwd_spec[] = { "transaction", "path", NULL };
static char *arg_spec = "ss";
char *path = NULL;
struct xs_handle *xh = xshandle(self);
@@ -286,12 +320,19 @@ static PyObject *xspy_get_permissions(PyObject *self, PyObject *args,
unsigned int perms_n = 0;
int i;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&thstr, &path))
goto exit;
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
perms = xs_get_permissions(xh, path, &perms_n);
perms = xs_get_permissions(xh, th, path, &perms_n);
Py_END_ALLOW_THREADS
if (!perms) {
PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -321,8 +362,8 @@ static PyObject *xspy_get_permissions(PyObject *self, PyObject *args,
static PyObject *xspy_set_permissions(PyObject *self, PyObject *args,
PyObject *kwds)
{
static char *kwd_spec[] = { "path", "perms", NULL };
static char *arg_spec = "sO";
static char *kwd_spec[] = { "transaction", "path", "perms", NULL };
static char *arg_spec = "ssO";
char *path = NULL;
PyObject *perms = NULL;
static char *perm_names[] = { "dom", "read", "write", NULL };
@@ -335,11 +376,17 @@ static PyObject *xspy_set_permissions(PyObject *self, PyObject *args,
PyObject *tuple0 = NULL;
PyObject *val = NULL;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&path, &perms))
&thstr, &path, &perms))
goto exit;
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
if (!PyList_Check(perms)) {
PyErr_SetString(PyExc_RuntimeError, "perms must be a list");
goto exit;
@@ -369,7 +416,7 @@ static PyObject *xspy_set_permissions(PyObject *self, PyObject *args,
xsperms[i].perms |= XS_PERM_WRITE;
}
Py_BEGIN_ALLOW_THREADS
xsval = xs_set_permissions(xh, path, xsperms, xsperms_n);
xsval = xs_set_permissions(xh, th, path, xsperms, xsperms_n);
Py_END_ALLOW_THREADS
if (!xsval) {
PyErr_SetFromErrno(PyExc_RuntimeError);
@@ -442,9 +489,6 @@ static PyObject *xspy_watch(PyObject *self, PyObject *args, PyObject *kwds)
#define xspy_read_watch_doc "\n" \
"Read a watch notification.\n" \
"The notification must be acknowledged by passing\n" \
"the token to acknowledge_watch().\n" \
" path [string]: xenstore path.\n" \
"\n" \
"Returns: [tuple] (path, token).\n" \
"Raises RuntimeError on error.\n" \
@@ -495,44 +539,6 @@ static PyObject *xspy_read_watch(PyObject *self, PyObject *args,
return val;
}
#define xspy_acknowledge_watch_doc "\n" \
"Acknowledge a watch notification that has been read.\n" \
" token [string] : from the watch notification\n" \
"\n" \
"Returns None on success.\n" \
"Raises RuntimeError on error.\n" \
"\n"
static PyObject *xspy_acknowledge_watch(PyObject *self, PyObject *args,
PyObject *kwds)
{
static char *kwd_spec[] = { "token", NULL };
static char *arg_spec = "O";
PyObject *token;
char token_str[MAX_STRLEN(unsigned long) + 1];
struct xs_handle *xh = xshandle(self);
PyObject *val = NULL;
int xsval = 0;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &token))
goto exit;
sprintf(token_str, "%li", (unsigned long)token);
Py_BEGIN_ALLOW_THREADS
xsval = xs_acknowledge_watch(xh, token_str);
Py_END_ALLOW_THREADS
if (!xsval) {
PyErr_SetFromErrno(PyExc_RuntimeError);
goto exit;
}
Py_INCREF(Py_None);
val = Py_None;
exit:
return val;
}
#define xspy_unwatch_doc "\n" \
"Stop watching a path.\n" \
" path [string] : xenstore path.\n" \
@@ -584,9 +590,8 @@ static PyObject *xspy_unwatch(PyObject *self, PyObject *args, PyObject *kwds)
#define xspy_transaction_start_doc "\n" \
"Start a transaction.\n" \
"Only one transaction can be active at a time.\n" \
"\n" \
"Returns None on success.\n" \
"Returns transaction handle on success.\n" \
"Raises RuntimeError on error.\n" \
"\n"
@@ -599,21 +604,23 @@ static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
struct xs_handle *xh = xshandle(self);
PyObject *val = NULL;
int xsval = 0;
struct xs_transaction_handle *th;
char thstr[20];
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &path))
goto exit;
Py_BEGIN_ALLOW_THREADS
xsval = xs_transaction_start(xh);
th = xs_transaction_start(xh);
Py_END_ALLOW_THREADS
if (!xsval) {
if (th == NULL) {
PyErr_SetFromErrno(PyExc_RuntimeError);
goto exit;
}
Py_INCREF(Py_None);
val = Py_None;
sprintf(thstr, "%lX", (unsigned long)th);
val = PyString_FromString(thstr);
exit:
return val;
}
@@ -630,20 +637,27 @@ static PyObject *xspy_transaction_start(PyObject *self, PyObject *args,
static PyObject *xspy_transaction_end(PyObject *self, PyObject *args,
PyObject *kwds)
{
static char *kwd_spec[] = { "abort", NULL };
static char *arg_spec = "|i";
static char *kwd_spec[] = { "transaction", "abort", NULL };
static char *arg_spec = "s|i";
int abort = 0;
struct xs_handle *xh = xshandle(self);
PyObject *val = NULL;
int xsval = 0;
struct xs_transaction_handle *th;
char *thstr;
if (!xh)
goto exit;
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, &abort))
if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec,
&thstr, &abort))
goto exit;
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
Py_BEGIN_ALLOW_THREADS
xsval = xs_transaction_end(xh, abort);
xsval = xs_transaction_end(xh, th, abort);
Py_END_ALLOW_THREADS
if (!xsval) {
if (errno == EAGAIN) {
@@ -833,7 +847,6 @@ static PyMethodDef xshandle_methods[] = {
XSPY_METH(set_permissions),
XSPY_METH(watch),
XSPY_METH(read_watch),
XSPY_METH(acknowledge_watch),
XSPY_METH(unwatch),
XSPY_METH(transaction_start),
XSPY_METH(transaction_end),
-1
View File
@@ -5,7 +5,6 @@ import os.path
import re
import sys
os.defpath = os.defpath + ':/sbin:/usr/sbin:/usr/local/sbin'
CMD_IFCONFIG = 'ifconfig'
CMD_ROUTE = 'route'
CMD_BRCTL = 'brctl'
+27
View File
@@ -0,0 +1,27 @@
#===========================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2005 XenSource Ltd
#============================================================================
def isCharConvertible(c):
"""Assert that the given value is convertible to a character using the %c
conversion. This implies that c is either an integer, or a character
(i.e. a string of length 1).
"""
assert (isinstance(c, int) or
(isinstance(c, str) and
len(c) == 1)), "%s is not convertible to a character" % c
+44
View File
@@ -0,0 +1,44 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2005 XenSource Ltd
#============================================================================
LIB_BIN_32 = "/usr/lib/xen/bin"
LIB_BIN_64 = "/usr/lib64/xen/bin"
import os
import os.path
def execute(exe, args = None):
exepath = pathTo(exe)
a = [ exepath ]
if args:
a.extend(args)
os.execv(exepath, a)
def pathTo(exe):
return os.path.join(path(), exe)
def path():
machine = os.uname()[4]
if machine.find('64') != -1 and os.path.exists(LIB_BIN_64):
return LIB_BIN_64
else:
return LIB_BIN_32
+8 -4
View File
@@ -14,6 +14,8 @@ from struct import pack, unpack, calcsize
from xen.util.xpopen import xPopen3
import xen.util.auxbin
import xen.lowlevel.xc
from xen.xend.xenstore.xsutil import IntroduceDomain
@@ -21,9 +23,11 @@ from xen.xend.xenstore.xsutil import IntroduceDomain
from XendError import XendError
from XendLogging import log
SIGNATURE = "LinuxGuestRecord"
PATH_XC_SAVE = "/usr/libexec/xen/xc_save"
PATH_XC_RESTORE = "/usr/libexec/xen/xc_restore"
XC_SAVE = "xc_save"
XC_RESTORE = "xc_restore"
sizeof_int = calcsize("i")
sizeof_unsigned_long = calcsize("L")
@@ -64,7 +68,7 @@ def save(fd, dominfo, live):
# enabled. Passing "0" simply uses the defaults compiled into
# libxenguest; see the comments and/or code in xc_linux_save() for
# more information.
cmd = [PATH_XC_SAVE, str(xc.handle()), str(fd),
cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(xc.handle()), str(fd),
str(dominfo.getDomid()), "0", "0", str(int(live)) ]
log.debug("[xc_save]: %s", string.join(cmd))
@@ -129,7 +133,7 @@ def restore(xd, fd):
store_evtchn = dominfo.store_channel
console_evtchn = dominfo.console_channel
cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
cmd = [xen.util.auxbin.pathTo(XC_RESTORE), str(xc.handle()), str(fd),
str(dominfo.getDomid()), str(nr_pfns),
str(store_evtchn), str(console_evtchn)]
log.debug("[xc_restore]: %s", string.join(cmd))
+3
View File
@@ -196,6 +196,9 @@ class Xend:
def xend_domains(self):
return self.xendGet(self.domainurl())
def xend_list_domains(self):
return self.xendGet(self.domainurl(), {'detail': '1'})
def xend_domain_create(self, conf):
return self.xendPost(self.domainurl(),
{'op' : 'create',
-83
View File
@@ -359,20 +359,6 @@ class XendDomain:
raise XendError(str(ex))
def domain_shutdown(self, domid, reason = 'poweroff'):
"""Shutdown domain (nicely).
@param reason: shutdown reason: poweroff, reboot, suspend, halt
"""
self.callInfo(domid, XendDomainInfo.XendDomainInfo.shutdown, reason)
def domain_sysrq(self, domid, key):
"""Send a SysRq to the specified domain."""
return self.callInfo(domid, XendDomainInfo.XendDomainInfo.send_sysrq,
key)
def domain_destroy(self, domid):
"""Terminate domain immediately."""
@@ -475,37 +461,6 @@ class XendDomain:
raise XendError(str(ex))
def domain_device_create(self, domid, devconfig):
"""Create a new device for the specified domain.
"""
return self.callInfo(domid,
XendDomainInfo.XendDomainInfo.device_create,
devconfig)
def domain_device_configure(self, domid, devconfig, devid):
"""Configure an existing device in the specified domain.
@return: updated device configuration
"""
return self.callInfo(domid,
XendDomainInfo.XendDomainInfo.device_configure,
devconfig, devid)
def domain_device_destroy(self, domid, devtype, devid):
"""Destroy a device."""
return self.callInfo(domid,
XendDomainInfo.XendDomainInfo.destroyDevice,
devtype, devid)
def domain_devtype_ls(self, domid, devtype):
"""Get list of device sxprs for the specified domain."""
return self.callInfo(domid,
XendDomainInfo.XendDomainInfo.getDeviceSxprs,
devtype)
def domain_vif_limit_set(self, domid, vif, credit, period):
"""Limit the vif's transmission rate
"""
@@ -537,44 +492,6 @@ class XendDomain:
except Exception, ex:
raise XendError(str(ex))
def domain_mem_target_set(self, domid, mem):
"""Set the memory target for a domain.
@param mem: memory target (in MiB)
"""
self.callInfo(domid, XendDomainInfo.XendDomainInfo.setMemoryTarget,
mem << 10)
def domain_vcpu_hotplug(self, domid, vcpu, state):
"""Enable or disable specified VCPU in specified domain
@param vcpu: target VCPU in domain
@param state: which state VCPU will become
"""
self.callInfo(domid, XendDomainInfo.XendDomainInfo.vcpu_hotplug, vcpu,
state)
def domain_dumpcore(self, domid):
"""Save a core dump for a crashed domain."""
self.callInfo(domid, XendDomainInfo.XendDomainInfo.dumpCore)
## private:
def callInfo(self, domid, fn, *args, **kwargs):
try:
self.refresh()
dominfo = self.domains.get(domid)
if dominfo:
return fn(dominfo, *args, **kwargs)
except XendError:
raise
except Exception, exn:
log.exception("")
raise XendError(str(exn))
def instance():
"""Singleton constructor. Use this instead of the class constructor.
+32 -29
View File
@@ -30,6 +30,7 @@ import threading
import errno
import xen.lowlevel.xc
from xen.util import asserts
from xen.util.blkif import blkdev_uname_to_file
from xen.xend import image
@@ -41,7 +42,8 @@ from xen.xend.XendLogging import log
from xen.xend.XendError import XendError, VmError
from xen.xend.XendRoot import get_component
from xen.xend.uuid import getUuid
from uuid import getUuid
from xen.xend.xenstore.xstransact import xstransact
from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
@@ -217,17 +219,12 @@ def recreate(xeninfo):
def restore(config):
"""Create a domain and a VM object to do a restore.
@param config: domain configuration
@param config: domain configuration
"""
log.debug("XendDomainInfo.restore(%s)", config)
try:
uuid = sxp.child_value(config, 'uuid')
ssidref = int(sxp.child_value(config, 'ssidref'))
except TypeError, exn:
raise VmError('Invalid ssidref in config: %s' % exn)
uuid = sxp.child_value(config, 'uuid')
vm = XendDomainInfo(uuid, parseConfig(config))
try:
vm.construct()
@@ -257,7 +254,7 @@ def parseConfig(config):
return val
log.debug("parseConfig: config is %s" % str(config))
log.debug("parseConfig: config is %s", config)
result = {}
@@ -315,7 +312,7 @@ def parseConfig(config):
log.warn("Ignoring malformed and deprecated config option "
"restart = %s", restart)
log.debug("parseConfig: result is %s" % str(result))
log.debug("parseConfig: result is %s", result)
return result
@@ -529,7 +526,7 @@ class XendDomainInfo:
except KeyError, exn:
log.exception(exn)
raise VmError('Unspecified domain detail: %s' % str(exn))
raise VmError('Unspecified domain detail: %s' % exn)
def readVm(self, *args):
@@ -579,7 +576,7 @@ class XendDomainInfo:
if self.infoIsSet(k):
to_store[k] = str(self.info[k])
log.debug("Storing VM details: %s" % str(to_store))
log.debug("Storing VM details: %s", to_store)
self.writeVm(to_store)
@@ -605,7 +602,7 @@ class XendDomainInfo:
for v in range(0, self.info['vcpus']):
to_store["cpu/%d/availability" % v] = availability(v)
log.debug("Storing domain details: %s" % str(to_store))
log.debug("Storing domain details: %s", to_store)
self.writeDom(to_store)
@@ -746,7 +743,7 @@ class XendDomainInfo:
def shutdown(self, reason):
if not reason in shutdown_reasons.values():
raise XendError('invalid reason:' + reason)
raise XendError('Invalid reason: %s' % reason)
self.storeDom("control/shutdown", reason)
if reason != 'suspend':
self.storeDom('xend/shutdown_start_time', time.time())
@@ -793,10 +790,12 @@ class XendDomainInfo:
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@param target In KiB.
@param target In MiB.
"""
self.info['memory_KiB'] = target
self.storeDom("memory/target", target)
# Internally we use KiB, but the command interface uses MiB.
t = target << 10
self.info['memory_KiB'] = t
self.storeDom("memory/target", t)
def update(self, info = None):
@@ -986,8 +985,8 @@ class XendDomainInfo:
"""
log.debug('XendDomainInfo.construct: %s %s',
str(self.domid),
str(self.info['ssidref']))
self.domid,
self.info['ssidref'])
self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'])
@@ -1004,9 +1003,9 @@ class XendDomainInfo:
def initDomain(self):
log.debug('XendDomainInfo.initDomain: %s %s %s',
str(self.domid),
str(self.info['memory_KiB']),
str(self.info['cpu_weight']))
self.domid,
self.info['memory_KiB'],
self.info['cpu_weight'])
if not self.infoIsSet('image'):
raise VmError('Missing image in configuration')
@@ -1085,14 +1084,15 @@ class XendDomainInfo:
def destroy(self):
"""Cleanup VM and destroy domain. Nothrow guarantee."""
log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
log.debug("XendDomainInfo.destroy: domid=%s", self.domid)
self.cleanupVm()
self.destroyDomain()
if self.dompath is not None:
self.destroyDomain()
def destroyDomain(self):
log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
log.debug("XendDomainInfo.destroyDomain(%s)", self.domid)
try:
if self.domid is not None:
@@ -1366,7 +1366,10 @@ class XendDomainInfo:
self.storeVm('vcpu_avail', self.info['vcpu_avail'])
self.storeDom("cpu/%d/availability" % vcpu, availability)
def send_sysrq(self, key=0):
def send_sysrq(self, key):
asserts.isCharConvertible(key)
self.storeDom("control/sysrq", '%c' % key)
@@ -1388,18 +1391,18 @@ class XendDomainInfo:
dom = 0
# get max number of vcpus to use for dom0 from config
target = int(xroot.get_dom0_vcpus())
log.debug("number of vcpus to use is %d" % (target))
log.debug("number of vcpus to use is %d", target)
# target = 0 means use all processors
if target > 0:
# count the number of online vcpus (cpu values in v2c map >= 0)
vcpu_to_cpu = dom_get(dom)['vcpu_to_cpu']
vcpus_online = len(filter(lambda x: x >= 0, vcpu_to_cpu))
log.debug("found %d vcpus online" % (vcpus_online))
log.debug("found %d vcpus online", vcpus_online)
# disable any extra vcpus that are online over the requested target
for vcpu in range(target, vcpus_online):
log.info("enforcement is disabling DOM%d VCPU%d" % (dom, vcpu))
log.info("enforcement is disabling DOM%d VCPU%d", dom, vcpu)
self.vcpu_hotplug(vcpu, 0)
+72 -67
View File
@@ -13,79 +13,84 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 XenSource Ltd
#============================================================================
import tempfile
import types
import logging
from logging import Formatter, StreamHandler
from logging.handlers import RotatingFileHandler
import logging.handlers
class XendLogging:
KB = 1024
MB = 1024 * KB
maxBytes = 1 * MB
backupCount = 5
__all__ = [ 'log', 'init', 'getLogFilename', 'addLogStderr',
'removeLogStderr' ]
logStderrFormat = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
logFileFormat = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
dateFormat = "%Y-%m-%d %H:%M:%S"
def __init__(self, filename, level=logging.INFO, maxBytes=None, backupCount=None):
"""Initialise logging. Logs to 'filename' by default, but does not log to
stderr unless addLogStderr() is called.
"""
self.setLevel(level)
if maxBytes:
self.maxBytes = maxBytes
if backupCount:
self.backupCount = backupCount
self.initLogFile(filename)
self.initLogStderr()
def setLevel(self, level):
if isinstance(level, types.StringType):
level = logging._levelNames[level]
self.getLogger().setLevel(level)
self.level = level
def getLogger(self):
return logging.getLogger("xend")
def initLogFile(self, filename):
"""Create the file logger and add it.
"""
self.logfile = RotatingFileHandler(filename,
mode='a',
maxBytes=self.maxBytes,
backupCount=self.backupCount)
self.logfilename = filename
self.logfile.setFormatter(Formatter(self.logFileFormat, self.dateFormat))
self.getLogger().addHandler(self.logfile)
def getLogFile(self):
return self.logfile
def getLogFilename(self):
return self.logfilename
def initLogStderr(self):
"""Create the stderr logger, but don't add it.
"""
self.logstderr = StreamHandler()
self.logstderr.setFormatter(Formatter(self.logStderrFormat, self.dateFormat))
def addLogStderr(self):
"""Add logging to stderr."""
self.getLogger().addHandler(self.logstderr)
def removeLogStderr(self):
"""Remove logging to stderr."""
self.getLogger().removeHandler(self.logstderr)
def getLogStderr(self):
return self.logstderr
log = logging.getLogger("xend")
DEFAULT_MAX_BYTES = 1 << 20 # 1MB
DEFAULT_BACKUP_COUNT = 5
STDERR_FORMAT = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
LOGFILE_FORMAT = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
stderrHandler = logging.StreamHandler()
stderrHandler.setFormatter(logging.Formatter(STDERR_FORMAT, DATE_FORMAT))
logfilename = None
def init(filename, level=logging.INFO, maxBytes=None, backupCount=None):
"""Initialise logging. Logs to 'filename' by default, but does not log to
stderr unless addLogStderr() is called.
"""
global logfilename
def openFileHandler(fname):
return logging.handlers.RotatingFileHandler(fname,
mode='a',
maxBytes=maxBytes,
backupCount=backupCount)
if not maxBytes:
maxBytes = DEFAULT_MAX_BYTES
if not backupCount:
backupCount = DEFAULT_BACKUP_COUNT
# Rather unintuitively, getLevelName will get the number corresponding to
# a level name, as well as getting the name corresponding to a level
# number. setLevel seems to take the number only though, so convert if we
# are given a string.
if isinstance(level, types.StringType):
level = logging.getLevelName(level)
log.setLevel(level)
try:
fileHandler = openFileHandler(filename)
logfilename = filename
except IOError:
logfilename = tempfile.mkstemp("-xend.log")[1]
fileHandler = openFileHandler(logfilename)
fileHandler.setFormatter(logging.Formatter(LOGFILE_FORMAT, DATE_FORMAT))
log.addHandler(fileHandler)
def getLogFilename():
return logfilename
def addLogStderr():
"""Add logging to stderr."""
log.addHandler(stderrHandler)
def removeLogStderr():
"""Remove logging to stderr."""
log.removeHandler(stderrHandler)
+13 -79
View File
@@ -13,6 +13,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 XenSource Ltd
#============================================================================
"""Xend root class.
@@ -29,7 +30,7 @@ import os.path
import string
import sys
from XendLogging import XendLogging
import XendLogging
from XendError import XendError
import sxp
@@ -92,7 +93,6 @@ class XendRoot:
def __init__(self):
self.config_path = None
self.config = None
self.logging = None
self.configure()
@@ -114,84 +114,22 @@ class XendRoot:
"""
return self.components.get(name)
def _format(self, msg, args):
if args:
return str(msg) % args
else:
return str(msg)
def _log(self, mode, fmt, args):
"""Logging function that uses the logger if it exists, otherwise
logs to stderr. We use this for XendRoot log messages because
they may be logged before the logger has been configured.
Other components can safely use the logger.
def _logError(self, fmt, args):
"""Logging function to log to stderr. We use this for XendRoot log
messages because they may be logged before the logger has been
configured. Other components can safely use the logger.
"""
log = self.get_logger()
if mode not in ['warning', 'info', 'debug', 'error']:
mode = 'info'
level = mode.upper()
if log:
getattr(log, mode)(fmt, *args)
else:
print >>sys.stderr, "xend", "[%s]" % level, self._format(fmt, args)
def logDebug(self, fmt, *args):
"""Log a debug message.
@param fmt: message format
@param args: arguments
"""
self._log('debug', fmt, args)
def logInfo(self, fmt, *args):
"""Log an info message.
@param fmt: message format
@param args: arguments
"""
self._log('info', fmt, args)
def logWarning(self, fmt, *args):
"""Log a warning message.
@param fmt: message format
@param args: arguments
"""
self._log('warning', fmt, args)
def logError(self, fmt, *args):
"""Log an error message.
@param fmt: message format
@param args: arguments
"""
self._log('error', fmt, args)
def event_handler(self, event, val):
self.logInfo("EVENT> %s %s", str(event), str(val))
print >>sys.stderr, "xend [ERROR]", fmt % args
def configure(self):
self.set_config()
self.configure_logger()
def configure_logger(self):
logfile = self.get_config_value("logfile", self.logfile_default)
loglevel = self.get_config_value("loglevel", self.loglevel_default)
self.logging = XendLogging(logfile, level=loglevel)
XendLogging.init(logfile, level = loglevel)
from xen.xend.server import params
if params.XEND_DEBUG:
self.logging.addLogStderr()
def get_logging(self):
"""Get the XendLogging instance.
"""
return self.logging
def get_logger(self):
"""Get the logger.
"""
return self.logging and self.logging.getLogger()
XendLogging.addLogStderr()
def set_config(self):
"""If the config file exists, read it. If not, ignore it.
@@ -200,7 +138,6 @@ class XendRoot:
"""
self.config_path = os.getenv(self.config_var, self.config_default)
if os.path.exists(self.config_path):
#self.logInfo('Reading config file %s', self.config_path)
try:
fin = file(self.config_path, 'rb')
try:
@@ -210,10 +147,12 @@ class XendRoot:
config.insert(0, 'xend-config')
self.config = config
except Exception, ex:
self.logError('Reading config file %s: %s', self.config_path, str(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._logError('Config file does not exist: %s',
self.config_path)
self.config = ['xend-config']
def get_config(self, name=None):
@@ -339,11 +278,6 @@ def instance():
inst = XendRoot()
return inst
def logger():
"""Get the logger.
"""
return instance().get_logger()
def add_component(name, val):
"""Register a component with XendRoot.
This is used to work-round import cycles.
+1 -1
View File
@@ -38,7 +38,7 @@ class Daemon:
pythonex = '(?P<python>\S*python\S*)'
cmdex = '(?P<cmd>.*)'
procre = re.compile('^\s*' + pidex + '\s*' + pythonex + '\s*' + cmdex + '$')
xendre = re.compile('^/usr/sbin/xend\s*(start|restart)\s*.*$')
xendre = re.compile('^\S+/xend\s*(start|restart)\s*.*$')
procs = os.popen('ps -e -o pid,args 2>/dev/null')
for proc in procs:
pm = procre.match(proc)
+38 -57
View File
@@ -51,40 +51,28 @@ class SrvDomain(SrvDir):
val = self.xd.domain_pause(self.dom.domid)
return val
def op_shutdown(self, op, req):
fn = FormFn(self.xd.domain_shutdown,
[['dom', 'int'],
['reason', 'str']])
val = fn(req.args, {'dom': self.dom.domid})
def acceptCommand(self, req):
req.setResponseCode(http.ACCEPTED)
req.setHeader("Location", "%s/.." % req.prePathURL())
return val
def op_shutdown(self, op, req):
self.acceptCommand(req)
return self.dom.shutdown(req.args['reason'][0])
def op_sysrq(self, op, req):
fn = FormFn(self.xd.domain_sysrq,
[['dom', 'int'],
['key', 'int']])
val = fn(req.args, {'dom' : self.dom.domid})
req.setResponseCode(http.ACCEPTED)
req.setHeader("Location", "%s/.." % req.prePathURL())
return val
self.acceptCommand(req)
return self.dom.send_sysrq(int(req.args['key'][0]))
def op_destroy(self, op, req):
fn = FormFn(self.xd.domain_destroy,
[['dom', 'int']])
val = fn(req.args, {'dom': self.dom.domid})
req.setHeader("Location", "%s/.." % req.prePathURL())
return val
self.acceptCommand(req)
return self.xd.domain_destroy(self.dom.domid)
def op_save(self, op, req):
self.acceptCommand(req)
return req.threadRequest(self.do_save, op, req)
def do_save(self, op, req):
fn = FormFn(self.xd.domain_save,
[['dom', 'int'],
['file', 'str']])
val = fn(req.args, {'dom': self.dom.domid})
return 0
return self.xd.domain_save(self.dom.domid, req.args['file'][0])
def op_migrate(self, op, req):
return req.threadRequest(self.do_migrate, op, req)
@@ -134,43 +122,39 @@ class SrvDomain(SrvDir):
['memory', 'int']])
val = fn(req.args, {'dom': self.dom.domid})
return val
def call(self, fn, args, req):
return FormFn(fn, args)(req.args)
def op_mem_target_set(self, op, req):
fn = FormFn(self.xd.domain_mem_target_set,
[['dom', 'int'],
['target', 'int']])
val = fn(req.args, {'dom': self.dom.domid})
return val
return self.call(self.dom.setMemoryTarget,
[['target', 'int']],
req)
def op_devices(self, op, req):
fn = FormFn(self.xd.domain_devtype_ls,
[['dom', 'int'],
['type', 'str']])
val = fn(req.args, {'dom': self.dom.domid})
return val
return self.call(self.dom.getDeviceSxprs,
[['type', 'str']],
req)
def op_device_create(self, op, req):
fn = FormFn(self.xd.domain_device_create,
[['dom', 'int'],
['config', 'sxpr']])
val = fn(req.args, {'dom': self.dom.domid})
return val
return self.call(self.dom.device_create,
[['config', 'sxpr']],
req)
def op_device_destroy(self, op, req):
fn = FormFn(self.xd.domain_device_destroy,
[['dom', 'int'],
['type', 'str'],
['dev', 'str']])
val = fn(req.args, {'dom': self.dom.domid})
return val
return self.call(self.dom.destroyDevice,
[['type', 'str'],
['dev', 'int']],
req)
def op_device_configure(self, op, req):
fn = FormFn(self.xd.domain_device_configure,
[['dom', 'int'],
['config', 'sxpr'],
['dev', 'str']])
val = fn(req.args, {'dom': self.dom.domid})
return val
return self.call(self.dom.device_configure,
[['config', 'sxpr'],
['dev', 'int']],
req)
def op_vif_limit_set(self, op, req):
fn = FormFn(self.xd.domain_vif_limit_set,
@@ -182,12 +166,10 @@ class SrvDomain(SrvDir):
return val
def op_vcpu_hotplug(self, op, req):
fn = FormFn(self.xd.domain_vcpu_hotplug,
[['dom', 'int'],
['vcpu', 'int'],
['state', 'int']])
val = fn(req.args, {'dom': self.dom.domid})
return val
return self.call(self.dom.vcpu_hotplug,
[['vcpu', 'int'],
['state', 'int']],
req)
def render_POST(self, req):
return self.perform(req)
@@ -201,7 +183,6 @@ class SrvDomain(SrvDir):
#
# if op and op[0] in ['vifs', 'vif', 'vbds', 'vbd', 'mem_target_set']:
# return self.perform(req)
self.dom.update()
if self.use_sxp(req):
req.setHeader("Content-Type", sxp.mime_type)
sxp.show(self.dom.sxpr(), out=req)
+21 -5
View File
@@ -22,6 +22,7 @@ from xen.web import http
from xen.xend import sxp
from xen.xend import XendDomain
from xen.xend.XendDomainInfo import XendDomainInfo
from xen.xend.Args import FormFn
from xen.xend.XendError import XendError
from xen.xend.XendLogging import log
@@ -29,6 +30,7 @@ from xen.xend.XendLogging import log
from xen.web.SrvDir import SrvDir
from SrvDomain import SrvDomain
class SrvDomainDir(SrvDir):
"""Service that manages the domain directory.
"""
@@ -124,28 +126,41 @@ class SrvDomainDir(SrvDir):
out.close()
return val
def op_list(self, _, req):
"""List the details for this domain."""
self._list(req, True)
def render_POST(self, req):
return self.perform(req)
def render_GET(self, req):
self._list(req, 'detail' in req.args and req.args['detail'] == ['1'])
def _list(self, req, detail):
if self.use_sxp(req):
req.setHeader("Content-Type", sxp.mime_type)
self.ls_domain(req, 1)
self.ls_domain(req, detail, True)
else:
req.write("<html><head></head><body>")
self.print_path(req)
self.ls(req)
self.ls_domain(req)
self.ls_domain(req, detail, False)
self.form(req)
req.write("</body></html>")
def ls_domain(self, req, use_sxp=0):
def ls_domain(self, req, detail, use_sxp):
url = req.prePathURL()
if not url.endswith('/'):
url += '/'
if use_sxp:
domains = self.xd.list_names()
sxp.show(domains, out=req)
if detail:
sxp.show(map(XendDomainInfo.sxpr, self.xd.list()), out=req)
else:
sxp.show(self.xd.list_names(), out=req)
else:
domains = self.xd.list_sorted()
req.write('<ul>')
@@ -158,6 +173,7 @@ class SrvDomainDir(SrvDir):
req.write('</li>')
req.write('</ul>')
def form(self, req):
"""Generate the form(s) for domain dir operations.
"""
@@ -1,4 +1,3 @@
#!/usr/bin/python
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
+4 -3
View File
@@ -13,11 +13,12 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 XenSource Ltd
#============================================================================
from xen.web import static
from xen.xend import XendRoot
from xen.xend import XendLogging
from xen.web.SrvDir import SrvDir
@@ -27,8 +28,8 @@ class SrvXendLog(SrvDir):
def __init__(self):
SrvDir.__init__(self)
logging = XendRoot.instance().get_logging()
self.logfile = static.File(logging.getLogFilename(), defaultType="text/plain")
self.logfile = static.File(XendLogging.getLogFilename(),
defaultType="text/plain")
self.logfile.type = "text/plain"
self.logfile.encoding = None
+3 -3
View File
@@ -25,6 +25,7 @@ from xen.xend import scheduler
from xen.xend import sxp
from xen.xend import PrettyPrint
from xen.xend.XendError import XendError
from xen.xend import XendLogging
from xen.xend import XendRoot
@@ -146,11 +147,10 @@ class EventProtocol(protocol.Protocol):
def op_log_stderr(self, _, v):
mode = v[1]
logging = xroot.get_logging()
if mode == 'on':
logging.addLogStderr()
XendLogging.addLogStderr()
else:
logging.removeLogStderr()
XendLogging.removeLogStderr()
def op_domain_ls(self, _1, _2):
xd = xroot.get_component("xen.xend.XendDomain")
+1 -1
View File
@@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
+18 -42
View File
@@ -13,14 +13,19 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 XenSource Ltd
#============================================================================
"""Universal(ly) Unique Identifiers (UUIDs).
"""
import commands
import random
def uuidgen(random=True):
def getUuidUuidgen(random = True):
"""Generate a UUID using the command uuidgen.
If random is true (default) generates a random uuid.
@@ -33,50 +38,21 @@ def uuidgen(random=True):
cmd += " -t"
return commands.getoutput(cmd)
class UuidFactoryUuidgen:
"""A uuid factory using uuidgen."""
def getUuidRandom():
"""Generate a random UUID."""
bytes = [ random.randint(0, 255) for i in range(0, 16) ]
# Encode the variant.
bytes[6] = (bytes[6] & 0x0f) | 0x40
bytes[8] = (bytes[8] & 0x3f) | 0x80
f = "%02x"
return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(bytes) )
def __init__(self):
pass
def getUuid(self):
return uuidgen()
#uuidFactory = getUuidUuidgen
uuidFactory = getUuidRandom
class UuidFactoryRandom:
"""A random uuid factory."""
def __init__(self):
f = file("/dev/urandom", "r")
seed = f.read(16)
f.close()
self.rand = random.Random(seed)
def randBytes(self, n):
return [ self.rand.randint(0, 255) for i in range(0, n) ]
def getUuid(self):
bytes = self.randBytes(16)
# Encode the variant.
bytes[6] = (bytes[6] & 0x0f) | 0x40
bytes[8] = (bytes[8] & 0x3f) | 0x80
f = "%02x"
return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(bytes) )
def getFactory():
"""Get the factory to use for creating uuids.
This is so it's easy to change the uuid factory.
For example, for testing we might want repeatable uuids
rather than the random ones we normally use.
"""
global uuidFactory
try:
uuidFactory
except:
#uuidFactory = UuidFactoryUuidgen()
uuidFactory = UuidFactoryRandom()
return uuidFactory
def getUuid():
return getFactory().getUuid()
return uuidFactory()
+19 -14
View File
@@ -14,29 +14,34 @@ from xen.xend.xenstore.xsutil import xshandle
class xstransact:
def __init__(self, path):
self.in_transaction = False
self.path = path.rstrip("/")
xshandle().transaction_start()
self.transaction = xshandle().transaction_start()
self.in_transaction = True
def __del__(self):
if self.in_transaction:
xshandle().transaction_end(True)
xshandle().transaction_end(self.transaction, True)
def commit(self):
if not self.in_transaction:
raise RuntimeError
self.in_transaction = False
return xshandle().transaction_end(False)
rc = xshandle().transaction_end(self.transaction, False)
self.transaction = "0"
return rc
def abort(self):
if not self.in_transaction:
return True
self.in_transaction = False
return xshandle().transaction_end(True)
rc = xshandle().transaction_end(self.transaction, True)
self.transaction = "0"
return rc
def _read(self, key):
path = "%s/%s" % (self.path, key)
try:
return xshandle().read(path)
return xshandle().read(self.transaction, path)
except RuntimeError, ex:
raise RuntimeError(ex.args[0],
'%s, while reading %s' % (ex.args[1], path))
@@ -50,7 +55,7 @@ class xstransact:
instead.
"""
if len(args) == 0:
return xshandle().read(self.path)
return xshandle().read(self.transaction, self.path)
if len(args) == 1:
return self._read(args[0])
ret = []
@@ -61,7 +66,7 @@ class xstransact:
def _write(self, key, data):
path = "%s/%s" % (self.path, key)
try:
xshandle().write(path, data)
xshandle().write(self.transaction, path, data)
except RuntimeError, ex:
raise RuntimeError(ex.args[0],
('%s, while writing %s : %s' %
@@ -93,7 +98,7 @@ class xstransact:
def _remove(self, key):
path = "%s/%s" % (self.path, key)
return xshandle().rm(path)
return xshandle().rm(self.transaction, path)
def remove(self, *args):
"""If no arguments are given, remove this transaction's path.
@@ -101,14 +106,14 @@ class xstransact:
path, and remove each of those instead.
"""
if len(args) == 0:
xshandle().rm(self.path)
xshandle().rm(self.transaction, self.path)
else:
for key in args:
self._remove(key)
def _list(self, key):
path = "%s/%s" % (self.path, key)
l = xshandle().ls(path)
l = xshandle().ls(self.transaction, path)
if l:
return map(lambda x: key + "/" + x, l)
return []
@@ -120,7 +125,7 @@ class xstransact:
path, and return the cumulative listing of each of those instead.
"""
if len(args) == 0:
ret = xshandle().ls(self.path)
ret = xshandle().ls(self.transaction, self.path)
if ret is None:
return []
else:
@@ -136,11 +141,11 @@ class xstransact:
ret = []
for key in keys:
new_subdir = subdir + "/" + key
l = xshandle().ls(new_subdir)
l = xshandle().ls(self.transaction, new_subdir)
if l:
ret.append([key, self.list_recursive_(new_subdir, l)])
else:
ret.append([key, xshandle().read(new_subdir)])
ret.append([key, xshandle().read(self.transaction, new_subdir)])
return ret
+3 -6
View File
@@ -8,6 +8,7 @@
import select
import threading
from xen.lowlevel import xs
from xen.xend.xenstore.xsutil import xshandle
class xswatch:
@@ -27,10 +28,7 @@ class xswatch:
if cls.watchThread:
cls.xslock.release()
return
# XXX: When we fix xenstored to have better watch semantics,
# this can change to shared xshandle(). Currently that would result
# in duplicate watch firings, thus failed extra xs.acknowledge_watch.
cls.xs = xs.open()
cls.xs = xshandle()
cls.watchThread = threading.Thread(name="Watcher",
target=cls.watchMain)
cls.watchThread.setDaemon(True)
@@ -43,11 +41,10 @@ class xswatch:
while True:
try:
we = cls.xs.read_watch()
watch = we[1]
cls.xs.acknowledge_watch(watch)
except RuntimeError, ex:
print ex
raise
watch = we[1]
watch.fn(*watch.args, **watch.kwargs)
watchMain = classmethod(watchMain)
+26
View File
@@ -0,0 +1,26 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2005 XenSource Ltd
#============================================================================
XENCONSOLE = "xenconsole"
import xen.util.auxbin
def execConsole(domid):
xen.util.auxbin.execute(XENCONSOLE, [str(domid)])
+7 -2
View File
@@ -14,11 +14,14 @@
#============================================================================
# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
# Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com>
# Copyright (C) 2005 XenSource Ltd
#============================================================================
"""Domain creation.
"""
import random
import os
import os.path
import string
import sys
import socket
@@ -36,6 +39,9 @@ from xen.util import blkif
from xen.xm.opts import *
import console
gopts = Opts(use="""[options] [vars]
Create a domain.
@@ -879,8 +885,7 @@ def main(argv):
dom = make_domain(opts, config)
if opts.vals.console_autoconnect:
cmd = "/usr/libexec/xen/xenconsole %d" % dom
os.execvp('/usr/libexec/xen/xenconsole', cmd.split())
console.execConsole(dom)
if __name__ == '__main__':
main(sys.argv)
+17 -19
View File
@@ -38,6 +38,8 @@ from xen.xend import PrettyPrint
from xen.xend import sxp
from xen.xm.opts import *
import console
shorthelp = """Usage: xm <subcommand> [args]
Control, list, and manipulate Xen guest instances
@@ -225,25 +227,22 @@ def xm_list(args):
if k in ['-v', '--vcpus']:
show_vcpus = 1
domsinfo = []
from xen.xend.XendClient import server
if n == 0:
doms = server.xend_domains()
doms.sort()
doms = server.xend_list_domains()
else:
doms = params
for dom in doms:
info = server.xend_domain(dom)
domsinfo.append(parse_doms_info(info))
doms = map(server.xend_domain, params)
if use_long:
for dom in doms:
info = server.xend_domain(dom)
PrettyPrint.prettyprint(info)
elif show_vcpus:
xm_show_vcpus(domsinfo)
PrettyPrint.prettyprint(doms)
else:
xm_brief_list(domsinfo)
domsinfo = map(parse_doms_info, doms)
if show_vcpus:
xm_show_vcpus(domsinfo)
else:
xm_brief_list(domsinfo)
def parse_doms_info(info):
dominfo = {}
@@ -279,12 +278,12 @@ def parse_doms_info(info):
return dominfo
def xm_brief_list(domsinfo):
print 'Name Id Mem(MB) CPU VCPU(s) State Time(s)'
print 'Name ID Mem(MiB) CPU VCPUs State Time(s)'
for dominfo in domsinfo:
if dominfo.has_key("ssidref1"):
print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo)
print ("%(name)-16s %(dom)3d %(mem)8d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo)
else:
print ("%(name)-16s %(dom)3d %(mem)7d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f" % dominfo)
print ("%(name)-16s %(dom)3d %(mem)8d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f" % dominfo)
def xm_show_vcpus(domsinfo):
print 'Name Id VCPU CPU CPUMAP'
@@ -445,12 +444,11 @@ def xm_console(args):
from xen.xend.XendClient import server
info = server.xend_domain(dom)
domid = int(sxp.child_value(info, 'domid', '-1'))
cmd = "/usr/libexec/xen/xenconsole %d" % domid
os.execvp('/usr/libexec/xen/xenconsole', cmd.split())
console = sxp.child(info, "console")
console.execConsole(domid)
def xm_top(args):
os.execv('/usr/sbin/xentop', ['/usr/sbin/xentop'])
os.execvp('xentop', ['xentop'])
def xm_dmesg(args):
+2 -7
View File
@@ -1,17 +1,12 @@
# (C) Matthew Bloch <matthew@bytemark.co.uk> 2004
# Copyright (C) 2005 XenSource Ltd
"""Domain shutdown.
"""Domain sysrq.
"""
import string
import sys
import time
from xen.xend.XendClient import server
from xen.xm.opts import *
DOM0_NAME = 'Domain-0'
DOM0_ID = '0'
gopts = Opts(use="""[DOM] [letter]
Sends a Linux sysrq to a domain.
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.