mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
Merged
This commit is contained in:
commit
e57d870ddd
80 files changed
+1910
-1514
No files matched your search
@@ -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),
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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))
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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,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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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)])
|
||||
@@ -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
@@ -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):
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||