mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
Merge latest xen-unstable into xen-ia64-unstable to prep
for push back to xen-unstable
This commit is contained in:
commit
6be63db55d
83 files changed
+1051
-1372
No files matched your search
@@ -74,6 +74,7 @@ static inline PyObject *pyvalue_str(char *val) {
|
||||
" path [string]: xenstore path\n" \
|
||||
"\n" \
|
||||
"Returns: [string] data read.\n" \
|
||||
" None if key doesn't exist.\n" \
|
||||
"Raises RuntimeError on error.\n" \
|
||||
"\n"
|
||||
|
||||
@@ -97,7 +98,11 @@ static PyObject *xspy_read(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
xsval = xs_read(xh, path, &xsval_n);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (!xsval) {
|
||||
PyErr_SetFromErrno(PyExc_RuntimeError);
|
||||
if (errno == ENOENT) {
|
||||
Py_INCREF(Py_None);
|
||||
val = Py_None;
|
||||
} else
|
||||
PyErr_SetFromErrno(PyExc_RuntimeError);
|
||||
goto exit;
|
||||
}
|
||||
val = PyString_FromStringAndSize(xsval, xsval_n);
|
||||
@@ -160,6 +165,7 @@ static PyObject *xspy_write(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
" path [string]: path to list.\n" \
|
||||
"\n" \
|
||||
"Returns: [string array] list of subdirectory names.\n" \
|
||||
" None if key doesn't exist.\n" \
|
||||
"Raises RuntimeError on error.\n" \
|
||||
"\n"
|
||||
|
||||
@@ -183,12 +189,17 @@ static PyObject *xspy_ls(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
xsval = xs_directory(xh, path, &xsval_n);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (!xsval) {
|
||||
PyErr_SetFromErrno(PyExc_RuntimeError);
|
||||
goto exit;
|
||||
if (errno == ENOENT) {
|
||||
Py_INCREF(Py_None);
|
||||
val = Py_None;
|
||||
} else
|
||||
PyErr_SetFromErrno(PyExc_RuntimeError);
|
||||
goto exit;
|
||||
}
|
||||
val = PyList_New(xsval_n);
|
||||
for (i = 0; i < xsval_n; i++)
|
||||
PyList_SetItem(val, i, PyString_FromString(xsval[i]));
|
||||
free(xsval);
|
||||
exit:
|
||||
return val;
|
||||
}
|
||||
@@ -253,7 +264,7 @@ static PyObject *xspy_rm(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
xsval = xs_rm(xh, path);
|
||||
Py_END_ALLOW_THREADS
|
||||
if (!xsval) {
|
||||
if (!xsval && errno != ENOENT) {
|
||||
PyErr_SetFromErrno(PyExc_RuntimeError);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ from string import join
|
||||
from struct import pack, unpack, calcsize
|
||||
from xen.util.xpopen import xPopen3
|
||||
import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
|
||||
from xen.xend.xenstore.xsutil import IntroduceDomain
|
||||
|
||||
from XendError import XendError
|
||||
from XendLogging import log
|
||||
@@ -48,7 +49,7 @@ def save(xd, fd, dominfo, live):
|
||||
# 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),
|
||||
str(dominfo.id), "0", "0", str(int(live)) ]
|
||||
str(dominfo.domid), "0", "0", str(int(live)) ]
|
||||
log.info("[xc_save] " + join(cmd))
|
||||
child = xPopen3(cmd, True, -1, [fd, xc.handle()])
|
||||
|
||||
@@ -68,18 +69,10 @@ def save(xd, fd, dominfo, live):
|
||||
if fd == child.fromchild.fileno():
|
||||
l = child.fromchild.readline()
|
||||
if l.rstrip() == "suspend":
|
||||
log.info("suspending %d" % dominfo.id)
|
||||
xd.domain_shutdown(dominfo.id, reason='suspend')
|
||||
log.info("suspending %d" % dominfo.domid)
|
||||
xd.domain_shutdown(dominfo.domid, reason='suspend')
|
||||
dominfo.state_wait("suspended")
|
||||
log.info("suspend %d done" % dominfo.id)
|
||||
if dominfo.store_channel:
|
||||
try:
|
||||
dominfo.db.releaseDomain(dominfo.id)
|
||||
except Exception, ex:
|
||||
log.warning(
|
||||
"error in domain release on xenstore: %s",
|
||||
ex)
|
||||
pass
|
||||
log.info("suspend %d done" % dominfo.domid)
|
||||
child.tochild.write("done\n")
|
||||
child.tochild.flush()
|
||||
if filter(lambda (fd, event): event & select.POLLHUP, r):
|
||||
@@ -90,12 +83,8 @@ def save(xd, fd, dominfo, live):
|
||||
if child.wait() != 0:
|
||||
raise XendError("xc_save failed: %s" % lasterr)
|
||||
|
||||
if dominfo.store_channel:
|
||||
dominfo.store_channel.close()
|
||||
dominfo.db['store_channel'].delete()
|
||||
dominfo.db.saveDB(save=True)
|
||||
dominfo.store_channel = None
|
||||
xd.domain_destroy(dominfo.id)
|
||||
dominfo.setStoreChannel(None)
|
||||
xd.domain_destroy(dominfo.domid)
|
||||
return None
|
||||
|
||||
def restore(xd, fd):
|
||||
@@ -137,7 +126,7 @@ def restore(xd, fd):
|
||||
console_evtchn = 0
|
||||
|
||||
cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
|
||||
str(dominfo.id), str(nr_pfns),
|
||||
str(dominfo.domid), str(nr_pfns),
|
||||
str(store_evtchn), str(console_evtchn)]
|
||||
log.info("[xc_restore] " + join(cmd))
|
||||
child = xPopen3(cmd, True, -1, [fd, xc.handle()])
|
||||
@@ -163,16 +152,15 @@ def restore(xd, fd):
|
||||
m = re.match(r"^(store-mfn) (\d+)\n$", l)
|
||||
if m:
|
||||
if dominfo.store_channel:
|
||||
dominfo.store_mfn = int(m.group(2))
|
||||
dominfo.setStoreRef(int(m.group(2)))
|
||||
if dominfo.store_mfn >= 0:
|
||||
dominfo.db.introduceDomain(dominfo.id,
|
||||
dominfo.store_mfn,
|
||||
dominfo.store_channel)
|
||||
dominfo.exportToDB(save=True, sync=True)
|
||||
IntroduceDomain(dominfo.domid,
|
||||
dominfo.store_mfn,
|
||||
dominfo.store_channel.port1,
|
||||
dominfo.path)
|
||||
m = re.match(r"^(console-mfn) (\d+)\n$", l)
|
||||
if m:
|
||||
dominfo.console_mfn = int(m.group(2))
|
||||
dominfo.exportToDB(save=True, sync=True)
|
||||
dominfo.setConsoleRef(int(m.group(2)))
|
||||
try:
|
||||
l = child.fromchild.readline()
|
||||
except:
|
||||
|
||||
@@ -130,8 +130,11 @@ class XendDomain:
|
||||
doms = self.xen_domains()
|
||||
self.dbmap.readDB()
|
||||
for domdb in self.dbmap.values():
|
||||
if not domdb.has_key("xend"):
|
||||
continue
|
||||
db = domdb.addChild("xend")
|
||||
try:
|
||||
domid = int(domdb.id)
|
||||
domid = int(domdb["domid"].getData())
|
||||
except:
|
||||
domid = None
|
||||
# XXX if domid in self.domains, then something went wrong
|
||||
@@ -139,7 +142,8 @@ class XendDomain:
|
||||
domdb.delete()
|
||||
elif domid in doms:
|
||||
try:
|
||||
self._new_domain(domdb, doms[domid])
|
||||
self._new_domain(domdb["uuid"].getData(), domid, db,
|
||||
doms[domid])
|
||||
except Exception, ex:
|
||||
log.exception("Error recreating domain info: id=%d", domid)
|
||||
self._delete_domain(domid)
|
||||
@@ -155,15 +159,15 @@ class XendDomain:
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def _new_domain(self, db, info):
|
||||
def _new_domain(self, uuid, domid, db, info):
|
||||
"""Create a domain entry from saved info.
|
||||
|
||||
@param db: saved info from the db
|
||||
@param info: domain info from xen
|
||||
@return: domain
|
||||
"""
|
||||
dominfo = XendDomainInfo.recreate(db, info)
|
||||
self.domains[dominfo.id] = dominfo
|
||||
dominfo = XendDomainInfo.recreate(uuid, domid, db, info)
|
||||
self.domains[dominfo.domid] = dominfo
|
||||
return dominfo
|
||||
|
||||
def _add_domain(self, info, notify=True):
|
||||
@@ -174,15 +178,15 @@ class XendDomain:
|
||||
"""
|
||||
# Remove entries under the wrong id.
|
||||
for i, d in self.domains.items():
|
||||
if i != d.id:
|
||||
if i != d.domid:
|
||||
del self.domains[i]
|
||||
self.dbmap.delete(d.uuid)
|
||||
if info.id in self.domains:
|
||||
if info.domid in self.domains:
|
||||
notify = False
|
||||
self.domains[info.id] = info
|
||||
self.domains[info.domid] = info
|
||||
info.exportToDB(save=True)
|
||||
if notify:
|
||||
eserver.inject('xend.domain.create', [info.name, info.id])
|
||||
eserver.inject('xend.domain.create', [info.name, info.domid])
|
||||
|
||||
def _delete_domain(self, id, notify=True):
|
||||
"""Remove a domain from the tables.
|
||||
@@ -201,11 +205,14 @@ class XendDomain:
|
||||
info.cleanup()
|
||||
info.delete()
|
||||
if notify:
|
||||
eserver.inject('xend.domain.died', [info.name, info.id])
|
||||
eserver.inject('xend.domain.died', [info.name, info.domid])
|
||||
# XXX this should not be needed
|
||||
for domdb in self.dbmap.values():
|
||||
if not domdb.has_key("xend"):
|
||||
continue
|
||||
db = domdb.addChild("xend")
|
||||
try:
|
||||
domid = int(domdb.id)
|
||||
domid = int(domdb["domid"].getData())
|
||||
except:
|
||||
domid = None
|
||||
if (domid is None) or (domid == id):
|
||||
@@ -261,13 +268,13 @@ class XendDomain:
|
||||
# Update entries for existing domains.
|
||||
do_domain_restarts = False
|
||||
for d in self.domains.values():
|
||||
info = doms.get(d.id)
|
||||
info = doms.get(d.domid)
|
||||
if info:
|
||||
d.update(info)
|
||||
elif d.restart_pending():
|
||||
do_domain_restarts = True
|
||||
else:
|
||||
self._delete_domain(d.id)
|
||||
self._delete_domain(d.domid)
|
||||
if cleanup and do_domain_restarts:
|
||||
scheduler.now(self.domain_restarts)
|
||||
|
||||
@@ -298,20 +305,20 @@ class XendDomain:
|
||||
|
||||
@param dominfo: domain object
|
||||
"""
|
||||
log.info("Restarting domain: name=%s id=%s", dominfo.name, dominfo.id)
|
||||
log.info("Restarting domain: name=%s id=%s", dominfo.name, dominfo.domid)
|
||||
eserver.inject("xend.domain.restart",
|
||||
[dominfo.name, dominfo.id, "begin"])
|
||||
[dominfo.name, dominfo.domid, "begin"])
|
||||
try:
|
||||
dominfo.restart()
|
||||
log.info('Restarted domain name=%s id=%s', dominfo.name, dominfo.id)
|
||||
log.info('Restarted domain name=%s id=%s', dominfo.name, dominfo.domid)
|
||||
eserver.inject("xend.domain.restart",
|
||||
[dominfo.name, dominfo.id, "success"])
|
||||
self.domain_unpause(dominfo.id)
|
||||
[dominfo.name, dominfo.domid, "success"])
|
||||
self.domain_unpause(dominfo.domid)
|
||||
except Exception, ex:
|
||||
log.exception("Exception restarting domain: name=%s id=%s",
|
||||
dominfo.name, dominfo.id)
|
||||
dominfo.name, dominfo.domid)
|
||||
eserver.inject("xend.domain.restart",
|
||||
[dominfo.name, dominfo.id, "fail"])
|
||||
[dominfo.name, dominfo.domid, "fail"])
|
||||
return dominfo
|
||||
|
||||
def domain_configure(self, vmconfig):
|
||||
@@ -355,12 +362,12 @@ class XendDomain:
|
||||
log.info(
|
||||
"Creating entry for unknown domain: id=%d uuid=%s",
|
||||
id, uuid)
|
||||
db = self.dbmap.addChild(uuid)
|
||||
dominfo = XendDomainInfo.recreate(db, info)
|
||||
dominfo.setdom(id)
|
||||
db = self.dbmap.addChild("%s/xend" % uuid)
|
||||
dominfo = XendDomainInfo.recreate(uuid, id, db, info)
|
||||
self._add_domain(dominfo)
|
||||
return dominfo
|
||||
except Exception, ex:
|
||||
raise
|
||||
log.exception("Error creating domain info: id=%d", id)
|
||||
return None
|
||||
|
||||
@@ -383,9 +390,9 @@ class XendDomain:
|
||||
@param id: domain id
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
eserver.inject('xend.domain.unpause', [dominfo.name, dominfo.id])
|
||||
eserver.inject('xend.domain.unpause', [dominfo.name, dominfo.domid])
|
||||
try:
|
||||
return xc.domain_unpause(dom=dominfo.id)
|
||||
return xc.domain_unpause(dom=dominfo.domid)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
@@ -395,9 +402,9 @@ class XendDomain:
|
||||
@param id: domain id
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
eserver.inject('xend.domain.pause', [dominfo.name, dominfo.id])
|
||||
eserver.inject('xend.domain.pause', [dominfo.name, dominfo.domid])
|
||||
try:
|
||||
return xc.domain_pause(dom=dominfo.id)
|
||||
return xc.domain_pause(dom=dominfo.domid)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
@@ -413,8 +420,8 @@ class XendDomain:
|
||||
@param reason: shutdown type: poweroff, reboot, suspend, halt
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
self.domain_restart_schedule(dominfo.id, reason, force=True)
|
||||
eserver.inject('xend.domain.shutdown', [dominfo.name, dominfo.id, reason])
|
||||
self.domain_restart_schedule(dominfo.domid, reason, force=True)
|
||||
eserver.inject('xend.domain.shutdown', [dominfo.name, dominfo.domid, reason])
|
||||
if reason == 'halt':
|
||||
reason = 'poweroff'
|
||||
val = dominfo.shutdown(reason)
|
||||
@@ -438,7 +445,7 @@ class XendDomain:
|
||||
if not dominfo.shutdown_pending:
|
||||
# domain doesn't need shutdown
|
||||
continue
|
||||
id = dominfo.id
|
||||
id = dominfo.domid
|
||||
left = dominfo.shutdown_time_left(SHUTDOWN_TIMEOUT)
|
||||
if left <= 0:
|
||||
# Shutdown expired - destroy domain.
|
||||
@@ -469,15 +476,15 @@ class XendDomain:
|
||||
restart = (force and reason == 'reboot') or dominfo.restart_needed(reason)
|
||||
if restart:
|
||||
log.info('Scheduling restart for domain: name=%s id=%s',
|
||||
dominfo.name, dominfo.id)
|
||||
dominfo.name, dominfo.domid)
|
||||
eserver.inject("xend.domain.restart",
|
||||
[dominfo.name, dominfo.id, "schedule"])
|
||||
[dominfo.name, dominfo.domid, "schedule"])
|
||||
dominfo.restarting()
|
||||
else:
|
||||
log.info('Cancelling restart for domain: name=%s id=%s',
|
||||
dominfo.name, dominfo.id)
|
||||
dominfo.name, dominfo.domid)
|
||||
eserver.inject("xend.domain.restart",
|
||||
[dominfo.name, dominfo.id, "cancel"])
|
||||
[dominfo.name, dominfo.domid, "cancel"])
|
||||
dominfo.restart_cancel()
|
||||
|
||||
def domain_restarts(self):
|
||||
@@ -487,8 +494,8 @@ class XendDomain:
|
||||
for dominfo in self.domains.values():
|
||||
if not dominfo.restart_pending():
|
||||
continue
|
||||
print 'domain_restarts>', dominfo.name, dominfo.id
|
||||
info = doms.get(dominfo.id)
|
||||
print 'domain_restarts>', dominfo.name, dominfo.domid
|
||||
info = doms.get(dominfo.domid)
|
||||
if info:
|
||||
# Don't execute restart for domains still running.
|
||||
print 'domain_restarts> still runnning: ', dominfo.name
|
||||
@@ -505,7 +512,7 @@ class XendDomain:
|
||||
try:
|
||||
dominfo = self.domain_lookup(id)
|
||||
log.info('Destroying domain: name=%s', dominfo.name)
|
||||
eserver.inject('xend.domain.destroy', [dominfo.name, dominfo.id])
|
||||
eserver.inject('xend.domain.destroy', [dominfo.name, dominfo.domid])
|
||||
val = dominfo.destroy()
|
||||
except:
|
||||
#todo
|
||||
@@ -580,7 +587,7 @@ class XendDomain:
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
try:
|
||||
return xc.domain_pincpu(dominfo.id, vcpu, cpumap)
|
||||
return xc.domain_pincpu(dominfo.domid, vcpu, cpumap)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
@@ -589,7 +596,7 @@ class XendDomain:
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
try:
|
||||
return xc.bvtsched_domain_set(dom=dominfo.id, mcuadv=mcuadv,
|
||||
return xc.bvtsched_domain_set(dom=dominfo.domid, mcuadv=mcuadv,
|
||||
warpback=warpback, warpvalue=warpvalue,
|
||||
warpl=warpl, warpu=warpu)
|
||||
except Exception, ex:
|
||||
@@ -600,7 +607,7 @@ class XendDomain:
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
try:
|
||||
return xc.bvtsched_domain_get(dominfo.id)
|
||||
return xc.bvtsched_domain_get(dominfo.domid)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
@@ -610,7 +617,7 @@ class XendDomain:
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
try:
|
||||
return xc.sedf_domain_set(dominfo.id, period, slice, latency, extratime, weight)
|
||||
return xc.sedf_domain_set(dominfo.domid, period, slice, latency, extratime, weight)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
@@ -619,7 +626,7 @@ class XendDomain:
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
try:
|
||||
return xc.sedf_domain_get(dominfo.id)
|
||||
return xc.sedf_domain_get(dominfo.domid)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
@@ -667,7 +674,7 @@ class XendDomain:
|
||||
@param type: device type
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
val = dominfo.device_destroy(type, devid)
|
||||
val = dominfo.device_delete(type, devid)
|
||||
dominfo.exportToDB()
|
||||
return val
|
||||
|
||||
@@ -709,7 +716,7 @@ class XendDomain:
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
try:
|
||||
return xc.shadow_control(dominfo.id, op)
|
||||
return xc.shadow_control(dominfo.domid, op)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
@@ -723,7 +730,7 @@ class XendDomain:
|
||||
dominfo = self.domain_lookup(id)
|
||||
maxmem = int(mem) * 1024
|
||||
try:
|
||||
return xc.domain_setmaxmem(dominfo.id, maxmem_kb = maxmem)
|
||||
return xc.domain_setmaxmem(dominfo.domid, maxmem_kb = maxmem)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
@@ -735,7 +742,7 @@ class XendDomain:
|
||||
@return: 0 on success, -1 on error
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
return dominfo.mem_target_set(mem)
|
||||
return dominfo.setMemoryTarget(mem * (1 << 20))
|
||||
|
||||
def domain_vcpu_hotplug(self, id, vcpu, state):
|
||||
"""Enable or disable VCPU vcpu in DOM id
|
||||
@@ -755,12 +762,12 @@ class XendDomain:
|
||||
@param id: domain
|
||||
"""
|
||||
dominfo = self.domain_lookup(id)
|
||||
corefile = "/var/xen/dump/%s.%s.core"% (dominfo.name, dominfo.id)
|
||||
corefile = "/var/xen/dump/%s.%s.core"% (dominfo.name, dominfo.domid)
|
||||
try:
|
||||
xc.domain_dumpcore(dom=dominfo.id, corefile=corefile)
|
||||
xc.domain_dumpcore(dom=dominfo.domid, corefile=corefile)
|
||||
except Exception, ex:
|
||||
log.warning("Dumpcore failed, id=%s name=%s: %s",
|
||||
dominfo.id, dominfo.name, ex)
|
||||
dominfo.domid, dominfo.name, ex)
|
||||
|
||||
def instance():
|
||||
"""Singleton constructor. Use this instead of the class constructor.
|
||||
|
||||
@@ -27,6 +27,7 @@ import string, re
|
||||
import os
|
||||
import time
|
||||
import threading
|
||||
import errno
|
||||
|
||||
import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
|
||||
from xen.util.ip import check_subnet, get_current_ipgw
|
||||
@@ -48,6 +49,7 @@ from xen.xend.XendRoot import get_component
|
||||
from xen.xend.uuid import getUuid
|
||||
from xen.xend.xenstore import DBVar, XenNode, DBMap
|
||||
from xen.xend.xenstore.xstransact import xstransact
|
||||
from xen.xend.xenstore.xsutil import IntroduceDomain
|
||||
|
||||
"""Shutdown code for poweroff."""
|
||||
DOMAIN_POWEROFF = 0
|
||||
@@ -128,7 +130,7 @@ class XendDomainInfo:
|
||||
@raise: VmError for invalid configuration
|
||||
"""
|
||||
uuid = getUuid()
|
||||
db = parentdb.addChild(uuid)
|
||||
db = parentdb.addChild("%s/xend" % uuid)
|
||||
path = parentdb.getPath()
|
||||
vm = cls(uuid, path, db)
|
||||
vm.construct(config)
|
||||
@@ -138,23 +140,26 @@ class XendDomainInfo:
|
||||
|
||||
create = classmethod(create)
|
||||
|
||||
def recreate(cls, db, info):
|
||||
def recreate(cls, uuid, domid, db, info):
|
||||
"""Create the VM object for an existing domain.
|
||||
|
||||
@param db: domain db
|
||||
@param info: domain info from xc
|
||||
"""
|
||||
dom = info['dom']
|
||||
path = "/".join(db.getPath().split("/")[0:-1])
|
||||
vm = cls(db.getName(), path, db)
|
||||
vm.setdom(dom)
|
||||
db.readDB()
|
||||
path = "/".join(db.getPath().split("/")[0:-2])
|
||||
vm = cls(uuid, path, db)
|
||||
vm.setDomid(domid)
|
||||
vm.name, vm.start_time = vm.gatherVm(("name", str),
|
||||
("start-time", float))
|
||||
try:
|
||||
db.readDB()
|
||||
except: pass
|
||||
vm.importFromDB()
|
||||
config = vm.config
|
||||
log.debug('info=' + str(info))
|
||||
log.debug('config=' + prettyprintstring(config))
|
||||
|
||||
vm.memory = info['mem_kb']/1024
|
||||
vm.memory = info['mem_kb'] / 1024
|
||||
vm.target = info['mem_kb'] * 1024
|
||||
|
||||
if config:
|
||||
@@ -164,7 +169,7 @@ class XendDomainInfo:
|
||||
finally:
|
||||
vm.recreate = False
|
||||
else:
|
||||
vm.setName("Domain-%d" % dom)
|
||||
vm.setName("Domain-%d" % domid)
|
||||
|
||||
vm.exportToDB(save=True)
|
||||
return vm
|
||||
@@ -180,13 +185,13 @@ class XendDomainInfo:
|
||||
"""
|
||||
if not uuid:
|
||||
uuid = getUuid()
|
||||
db = parentdb.addChild(uuid)
|
||||
db = parentdb.addChild("%s/xend" % uuid)
|
||||
path = parentdb.getPath()
|
||||
vm = cls(uuid, path, db)
|
||||
ssidref = int(sxp.child_value(config, 'ssidref'))
|
||||
log.debug('restoring with ssidref='+str(ssidref))
|
||||
id = xc.domain_create(ssidref = ssidref)
|
||||
vm.setdom(id)
|
||||
vm.setDomid(id)
|
||||
vm.clear_shutdown()
|
||||
try:
|
||||
vm.restore = True
|
||||
@@ -199,32 +204,26 @@ class XendDomainInfo:
|
||||
restore = classmethod(restore)
|
||||
|
||||
__exports__ = [
|
||||
DBVar('id', ty='int'),
|
||||
DBVar('name', ty='str'),
|
||||
DBVar('uuid', ty='str'),
|
||||
DBVar('config', ty='sxpr'),
|
||||
DBVar('start_time', ty='float'),
|
||||
DBVar('state', ty='str'),
|
||||
DBVar('store_mfn', ty='long'),
|
||||
DBVar('console_mfn', ty='long', path="console/ring-ref"),
|
||||
DBVar('restart_mode', ty='str'),
|
||||
DBVar('restart_state', ty='str'),
|
||||
DBVar('restart_time', ty='float'),
|
||||
DBVar('restart_count', ty='int'),
|
||||
DBVar('target', ty='long', path="memory/target"),
|
||||
DBVar('device_model_pid', ty='int'),
|
||||
]
|
||||
|
||||
def __init__(self, uuid, path, db):
|
||||
self.uuid = uuid
|
||||
self.path = path + "/" + uuid
|
||||
|
||||
self.db = db
|
||||
|
||||
self.recreate = 0
|
||||
self.restore = 0
|
||||
|
||||
self.config = None
|
||||
self.id = None
|
||||
self.domid = None
|
||||
self.cpu_weight = 1
|
||||
self.start_time = None
|
||||
self.name = None
|
||||
@@ -260,10 +259,42 @@ class XendDomainInfo:
|
||||
self.restart_count = 0
|
||||
|
||||
self.vcpus = 1
|
||||
self.vcpusdb = {}
|
||||
self.bootloader = None
|
||||
self.device_model_pid = 0
|
||||
|
||||
self.writeVm("uuid", self.uuid)
|
||||
self.storeDom("vm", self.path)
|
||||
|
||||
def readVm(self, *args):
|
||||
return xstransact.Read(self.path, *args)
|
||||
|
||||
def writeVm(self, *args):
|
||||
return xstransact.Write(self.path, *args)
|
||||
|
||||
def removeVm(self, *args):
|
||||
return xstransact.Remove(self.path, *args)
|
||||
|
||||
def gatherVm(self, *args):
|
||||
return xstransact.Gather(self.path, *args)
|
||||
|
||||
def storeVm(self, *args):
|
||||
return xstransact.Store(self.path, *args)
|
||||
|
||||
def readDom(self, *args):
|
||||
return xstransact.Read(self.path, *args)
|
||||
|
||||
def writeDom(self, *args):
|
||||
return xstransact.Write(self.path, *args)
|
||||
|
||||
def removeDom(self, *args):
|
||||
return xstransact.Remove(self.path, *args)
|
||||
|
||||
def gatherDom(self, *args):
|
||||
return xstransact.Gather(self.path, *args)
|
||||
|
||||
def storeDom(self, *args):
|
||||
return xstransact.Store(self.path, *args)
|
||||
|
||||
def setDB(self, db):
|
||||
self.db = db
|
||||
|
||||
@@ -271,50 +302,56 @@ class XendDomainInfo:
|
||||
self.db.saveDB(save=save, sync=sync)
|
||||
|
||||
def exportToDB(self, save=False, sync=False):
|
||||
if self.store_channel:
|
||||
self.store_channel.saveToDB(self.db.addChild("store_channel"),
|
||||
save=save)
|
||||
if self.console_channel:
|
||||
self.db['console/port'] = "%i" % self.console_channel.port1
|
||||
if self.image:
|
||||
self.image.exportToDB(save=save, sync=sync)
|
||||
self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync)
|
||||
|
||||
def importFromDB(self):
|
||||
self.db.importFromDB(self, fields=self.__exports__)
|
||||
self.store_channel = self.eventChannelOld("store_channel")
|
||||
self.store_channel = self.eventChannel("store/port")
|
||||
|
||||
def setdom(self, dom):
|
||||
def setDomid(self, domid):
|
||||
"""Set the domain id.
|
||||
|
||||
@param dom: domain id
|
||||
"""
|
||||
self.id = int(dom)
|
||||
#self.db.id = self.id
|
||||
self.domid = domid
|
||||
self.storeDom("domid", self.domid)
|
||||
|
||||
def getDomain(self):
|
||||
return self.id
|
||||
return self.domid
|
||||
|
||||
def setName(self, name):
|
||||
self.name = name
|
||||
self.db.name = self.name
|
||||
self.storeVm("name", name)
|
||||
|
||||
def getName(self):
|
||||
return self.name
|
||||
|
||||
def getStoreChannel(self):
|
||||
return self.store_channel
|
||||
def setStoreRef(self, ref):
|
||||
self.store_mfn = ref
|
||||
self.storeDom("store/ring-ref", ref)
|
||||
|
||||
def getConsoleChannel(self):
|
||||
return self.console_channel
|
||||
def setStoreChannel(self, channel):
|
||||
if self.store_channel and self.store_channel != channel:
|
||||
self.store_channel.close()
|
||||
self.store_channel = channel
|
||||
self.storeDom("store/port", channel.port1)
|
||||
|
||||
def setConsoleRef(self, ref):
|
||||
self.console_mfn = ref
|
||||
self.storeDom("console/ring-ref", ref)
|
||||
|
||||
def setMemoryTarget(self, target):
|
||||
self.memory_target = target
|
||||
self.storeDom("memory/target", target)
|
||||
|
||||
def update(self, info=None):
|
||||
"""Update with info from xc.domain_getinfo().
|
||||
"""
|
||||
self.info = info or dom_get(self.id)
|
||||
self.info = info or dom_get(self.domid)
|
||||
self.memory = self.info['mem_kb'] / 1024
|
||||
self.ssidref = self.info['ssidref']
|
||||
self.target = self.info['mem_kb'] * 1024
|
||||
|
||||
def state_set(self, state):
|
||||
self.state_updated.acquire()
|
||||
@@ -332,7 +369,7 @@ class XendDomainInfo:
|
||||
|
||||
def __str__(self):
|
||||
s = "<domain"
|
||||
s += " id=" + str(self.id)
|
||||
s += " id=" + str(self.domid)
|
||||
s += " name=" + self.name
|
||||
s += " memory=" + str(self.memory)
|
||||
s += " ssidref=" + str(self.ssidref)
|
||||
@@ -373,7 +410,7 @@ class XendDomainInfo:
|
||||
frontpath = "%s/device/%s/%d" % (self.path, type, devnum)
|
||||
|
||||
front = { 'backend' : backpath,
|
||||
'backend-id' : "%i" % backdom.id,
|
||||
'backend-id' : "%i" % backdom.domid,
|
||||
'virtual-device' : "%i" % devnum }
|
||||
xstransact.Write(frontpath, front)
|
||||
|
||||
@@ -382,7 +419,7 @@ class XendDomainInfo:
|
||||
back = { 'type' : type,
|
||||
'params' : params,
|
||||
'frontend' : frontpath,
|
||||
'frontend-id' : "%i" % self.id }
|
||||
'frontend-id' : "%i" % self.domid }
|
||||
xstransact.Write(backpath, back)
|
||||
|
||||
return
|
||||
@@ -415,7 +452,7 @@ class XendDomainInfo:
|
||||
frontpath = "%s/device/%s/%d" % (self.path, type, devnum)
|
||||
|
||||
front = { 'backend' : backpath,
|
||||
'backend-id' : "%i" % backdom.id,
|
||||
'backend-id' : "%i" % backdom.domid,
|
||||
'handle' : "%i" % devnum,
|
||||
'mac' : mac }
|
||||
xstransact.Write(frontpath, front)
|
||||
@@ -425,7 +462,7 @@ class XendDomainInfo:
|
||||
'mac' : mac,
|
||||
'bridge' : bridge,
|
||||
'frontend' : frontpath,
|
||||
'frontend-id' : "%i" % self.id,
|
||||
'frontend-id' : "%i" % self.domid,
|
||||
'handle' : "%i" % devnum }
|
||||
if ipaddr:
|
||||
back['ip'] = ' '.join(ipaddr)
|
||||
@@ -444,13 +481,13 @@ class XendDomainInfo:
|
||||
frontpath = "%s/device/%s/%d" % (self.path, type, devnum)
|
||||
|
||||
front = { 'backend' : backpath,
|
||||
'backend-id' : "%i" % backdom.id,
|
||||
'backend-id' : "%i" % backdom.domid,
|
||||
'handle' : "%i" % devnum }
|
||||
xstransact.Write(frontpath, front)
|
||||
|
||||
back = { 'instance' : "%i" % devnum,
|
||||
'frontend' : frontpath,
|
||||
'frontend-id' : "%i" % self.id }
|
||||
'frontend-id' : "%i" % self.domid }
|
||||
xstransact.Write(backpath, back)
|
||||
|
||||
return
|
||||
@@ -485,7 +522,7 @@ class XendDomainInfo:
|
||||
|
||||
def sxpr(self):
|
||||
sxpr = ['domain',
|
||||
['id', self.id],
|
||||
['domid', self.domid],
|
||||
['name', self.name],
|
||||
['memory', self.memory],
|
||||
['ssidref', self.ssidref],
|
||||
@@ -582,7 +619,7 @@ class XendDomainInfo:
|
||||
return
|
||||
if dominfo.is_terminated():
|
||||
return
|
||||
if not self.id or (dominfo.id != self.id):
|
||||
if not self.domid or (dominfo.domid != self.domid):
|
||||
raise VmError('vm name clash: ' + name)
|
||||
|
||||
def construct(self, config):
|
||||
@@ -630,11 +667,11 @@ class XendDomainInfo:
|
||||
self.memory = int(sxp.child_value(config, 'memory'))
|
||||
if self.memory is None:
|
||||
raise VmError('missing memory size')
|
||||
self.target = self.memory * (1 << 20)
|
||||
self.setMemoryTarget(self.memory * (1 << 20))
|
||||
self.ssidref = int(sxp.child_value(config, 'ssidref'))
|
||||
cpu = sxp.child_value(config, 'cpu')
|
||||
if self.recreate and self.id and cpu is not None and int(cpu) >= 0:
|
||||
xc.domain_pincpu(self.id, 0, 1<<int(cpu))
|
||||
if self.recreate and self.domid and cpu is not None and int(cpu) >= 0:
|
||||
xc.domain_pincpu(self.domid, 0, 1<<int(cpu))
|
||||
try:
|
||||
image = sxp.child_value(self.config, 'image')
|
||||
vcpus = sxp.child_value(image, 'vcpus')
|
||||
@@ -643,15 +680,11 @@ class XendDomainInfo:
|
||||
except:
|
||||
raise VmError('invalid vcpus value')
|
||||
|
||||
def exportVCPUSToDB(self, vcpus):
|
||||
for v in range(0,vcpus):
|
||||
path = "/cpu/%d"%(v)
|
||||
if not self.vcpusdb.has_key(path):
|
||||
self.vcpusdb[path] = self.db.addChild(path)
|
||||
db = self.vcpusdb[path]
|
||||
log.debug("writing key availability=online to path %s in store"%(path))
|
||||
db['availability'] = "online"
|
||||
db.saveDB(save=True)
|
||||
def configure_vcpus(self, vcpus):
|
||||
d = {}
|
||||
for v in range(0, vcpus):
|
||||
d["cpu/%d/availability" % v] = "online"
|
||||
self.writeVm(d)
|
||||
|
||||
def init_image(self):
|
||||
"""Create boot image handler for the domain.
|
||||
@@ -668,18 +701,17 @@ class XendDomainInfo:
|
||||
self.image.createImage()
|
||||
self.exportToDB()
|
||||
if self.store_channel and self.store_mfn >= 0:
|
||||
self.db.introduceDomain(self.id,
|
||||
self.store_mfn,
|
||||
self.store_channel)
|
||||
IntroduceDomain(self.domid, self.store_mfn,
|
||||
self.store_channel.port1, self.path)
|
||||
# get the configured value of vcpus and update store
|
||||
self.exportVCPUSToDB(self.vcpus)
|
||||
self.configure_vcpus(self.vcpus)
|
||||
|
||||
def delete(self):
|
||||
"""Delete the vm's db.
|
||||
"""
|
||||
if dom_get(self.id):
|
||||
if dom_get(self.domid):
|
||||
return
|
||||
self.id = None
|
||||
self.domid = None
|
||||
self.saveToDB(sync=True)
|
||||
try:
|
||||
# Todo: eventually will have to wait for devices to signal
|
||||
@@ -695,10 +727,10 @@ class XendDomainInfo:
|
||||
The domain will not finally go away unless all vm
|
||||
devices have been released.
|
||||
"""
|
||||
if self.id is None:
|
||||
if self.domid is None:
|
||||
return
|
||||
try:
|
||||
xc.domain_destroy(dom=self.id)
|
||||
xc.domain_destroy(dom=self.domid)
|
||||
except Exception, err:
|
||||
log.exception("Domain destroy failed: %s", self.name)
|
||||
|
||||
@@ -708,16 +740,7 @@ class XendDomainInfo:
|
||||
self.state = STATE_VM_TERMINATED
|
||||
self.release_devices()
|
||||
if self.store_channel:
|
||||
try:
|
||||
self.store_channel.close()
|
||||
self.store_channel = None
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.db.releaseDomain(self.id)
|
||||
except Exception, ex:
|
||||
log.warning("error in domain release on xenstore: %s", ex)
|
||||
pass
|
||||
self.setStoreChannel(None)
|
||||
if self.console_channel:
|
||||
# notify processes using this cosole?
|
||||
try:
|
||||
@@ -765,7 +788,7 @@ class XendDomainInfo:
|
||||
def show(self):
|
||||
"""Print virtual machine info.
|
||||
"""
|
||||
print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.id, self.name, self.memory, self.ssidref)
|
||||
print "[VM dom=%d name=%s memory=%d ssidref=%d" % (self.domid, self.name, self.memory, self.ssidref)
|
||||
print "image:"
|
||||
sxp.show(self.image)
|
||||
print "]"
|
||||
@@ -777,46 +800,37 @@ class XendDomainInfo:
|
||||
return
|
||||
if self.start_time is None:
|
||||
self.start_time = time.time()
|
||||
self.storeVm(("start-time", self.start_time))
|
||||
try:
|
||||
cpu = int(sxp.child_value(self.config, 'cpu', '-1'))
|
||||
except:
|
||||
raise VmError('invalid cpu')
|
||||
id = self.image.initDomain(self.id, self.memory, self.ssidref, cpu, self.cpu_weight)
|
||||
id = self.image.initDomain(self.domid, self.memory, self.ssidref, cpu, self.cpu_weight)
|
||||
log.debug('init_domain> Created domain=%d name=%s memory=%d',
|
||||
id, self.name, self.memory)
|
||||
self.setdom(id)
|
||||
self.setDomid(id)
|
||||
|
||||
def eventChannelOld(self, key):
|
||||
"""Create an event channel to the domain.
|
||||
If saved info is available recreate the channel.
|
||||
|
||||
@param key db key for the saved data (if any)
|
||||
"""
|
||||
db = self.db.addChild(key)
|
||||
return EventChannel.restoreFromDB(db, 0, self.id)
|
||||
|
||||
def eventChannel(self, path=None, key=None):
|
||||
def eventChannel(self, path=None):
|
||||
"""Create an event channel to the domain.
|
||||
|
||||
@param path under which port is stored in db
|
||||
"""
|
||||
port = 0
|
||||
try:
|
||||
if path and key:
|
||||
if path:
|
||||
db = self.db.addChild(path)
|
||||
else:
|
||||
db = self.db
|
||||
port = int(db[key].getData())
|
||||
except: pass
|
||||
return EventChannel.interdomain(0, self.id, port1=port, port2=0)
|
||||
if path:
|
||||
try:
|
||||
port = int(self.readDom(path))
|
||||
except:
|
||||
# if anything goes wrong, assume the port was not yet set
|
||||
pass
|
||||
ret = EventChannel.interdomain(0, self.domid, port1=port, port2=0)
|
||||
self.storeDom(path, ret.port1)
|
||||
return ret
|
||||
|
||||
def create_channel(self):
|
||||
"""Create the channels to the domain.
|
||||
"""
|
||||
self.store_channel = self.eventChannelOld("store_channel")
|
||||
self.console_channel = self.eventChannel("console", "port")
|
||||
|
||||
self.store_channel = self.eventChannel("store/port")
|
||||
self.console_channel = self.eventChannel("console/port")
|
||||
|
||||
def create_configured_devices(self):
|
||||
devices = sxp.children(self.config, 'device')
|
||||
@@ -1046,50 +1060,30 @@ class XendDomainInfo:
|
||||
log.warning("Unknown config field %s", field_name)
|
||||
index[field_name] = field_index + 1
|
||||
|
||||
def mem_target_set(self, target):
|
||||
"""Set domain memory target in bytes.
|
||||
"""
|
||||
if target:
|
||||
self.target = target * (1 << 20)
|
||||
# Commit to XenStore immediately
|
||||
self.exportToDB()
|
||||
|
||||
def vcpu_hotplug(self, vcpu, state):
|
||||
"""Disable or enable VCPU in domain.
|
||||
"""
|
||||
db = ""
|
||||
try:
|
||||
db = self.vcpusdb['/cpu/%d'%(vcpu)]
|
||||
except:
|
||||
log.error("Invalid VCPU")
|
||||
if vcpu > self.vcpus:
|
||||
log.error("Invalid VCPU %d" % vcpu)
|
||||
return
|
||||
|
||||
if self.store_channel:
|
||||
if int(state) == 0:
|
||||
db['availability'] = "offline"
|
||||
else:
|
||||
db['availability'] = "online"
|
||||
|
||||
db.saveDB(save=True)
|
||||
if int(state) == 0:
|
||||
availability = "offline"
|
||||
else:
|
||||
availability = "online"
|
||||
self.storeVm("cpu/%d/availability" % vcpu, availability)
|
||||
|
||||
def shutdown(self, reason):
|
||||
if not reason in shutdown_reasons.values():
|
||||
raise XendError('invalid reason:' + reason)
|
||||
db = self.db.addChild("/control");
|
||||
db['shutdown'] = reason;
|
||||
db.saveDB(save=True);
|
||||
self.storeVm("control/shutdown", reason)
|
||||
if not reason in ['suspend']:
|
||||
self.shutdown_pending = {'start':time.time(), 'reason':reason}
|
||||
|
||||
def clear_shutdown(self):
|
||||
db = self.db.addChild("/control")
|
||||
db['shutdown'] = ""
|
||||
db.saveDB(save=True)
|
||||
self.removeVm("control/shutdown")
|
||||
|
||||
def send_sysrq(self, key=0):
|
||||
db = self.db.addChild("/control");
|
||||
db['sysrq'] = '%c' % key;
|
||||
db.saveDB(save=True);
|
||||
self.storeVm("control/sysrq", '%c' % key)
|
||||
|
||||
def shutdown_time_left(self, timeout):
|
||||
if not self.shutdown_pending:
|
||||
@@ -1098,14 +1092,22 @@ class XendDomainInfo:
|
||||
|
||||
def dom0_init_store(self):
|
||||
if not self.store_channel:
|
||||
self.store_channel = self.eventChannelOld("store_channel")
|
||||
self.store_mfn = xc.init_store(self.store_channel.port2)
|
||||
if self.store_mfn >= 0:
|
||||
self.db.introduceDomain(self.id, self.store_mfn,
|
||||
self.store_channel)
|
||||
self.exportToDB(save=True, sync=True)
|
||||
# get run-time value of vcpus and update store
|
||||
self.exportVCPUSToDB(dom_get(self.id)['vcpus'])
|
||||
self.store_channel = self.eventChannel("store/port")
|
||||
if not self.store_channel:
|
||||
return
|
||||
ref = xc.init_store(self.store_channel.port2)
|
||||
if ref and ref >= 0:
|
||||
self.setStoreRef(ref)
|
||||
try:
|
||||
IntroduceDomain(self.domid, ref, self.store_channel.port1,
|
||||
self.path)
|
||||
except RuntimeError, ex:
|
||||
if ex.args[0] == errno.EISCONN:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
# get run-time value of vcpus and update store
|
||||
self.configure_vcpus(dom_get(self.domid)['vcpus'])
|
||||
|
||||
|
||||
def vm_field_ignore(_, _1, _2, _3):
|
||||
@@ -1126,7 +1128,7 @@ def vm_field_maxmem(vm, _1, val, _2):
|
||||
maxmem = int(maxmem)
|
||||
except:
|
||||
raise VmError("invalid maxmem: " + str(maxmem))
|
||||
xc.domain_setmaxmem(vm.id, maxmem_kb = maxmem * 1024)
|
||||
xc.domain_setmaxmem(vm.domid, maxmem_kb = maxmem * 1024)
|
||||
|
||||
|
||||
#============================================================================
|
||||
|
||||
@@ -23,6 +23,7 @@ from xen.xend import sxp
|
||||
from xen.xend.XendError import VmError
|
||||
from xen.xend.XendLogging import log
|
||||
from xen.xend.xenstore import DBVar
|
||||
from xen.xend.xenstore.xstransact import xstransact
|
||||
|
||||
from xen.xend.server import channel
|
||||
|
||||
@@ -154,7 +155,6 @@ class ImageHandler:
|
||||
if dom <= 0:
|
||||
raise VmError('Creating domain failed: name=%s' % self.vm.name)
|
||||
log.debug("initDomain: cpu=%d mem_kb=%d ssidref=%d dom=%d", cpu, mem_kb, ssidref, dom)
|
||||
# xc.domain_setuuid(dom, uuid)
|
||||
xc.domain_setcpuweight(dom, cpu_weight)
|
||||
xc.domain_setmaxmem(dom, mem_kb)
|
||||
|
||||
@@ -240,6 +240,12 @@ class ImageHandler:
|
||||
"""Extra cleanup on domain destroy (define in subclass if needed)."""
|
||||
pass
|
||||
|
||||
def set_vminfo(self, d):
|
||||
if d.has_key('store_mfn'):
|
||||
self.vm.setStoreRef(d.get('store_mfn'))
|
||||
if d.has_key('console_mfn'):
|
||||
self.vm.setConsoleRef(d.get('console_mfn'))
|
||||
|
||||
addImageHandlerClass = ImageHandler.addImageHandlerClass
|
||||
|
||||
class LinuxImageHandler(ImageHandler):
|
||||
@@ -274,8 +280,7 @@ class LinuxImageHandler(ImageHandler):
|
||||
flags = self.flags,
|
||||
vcpus = self.vm.vcpus)
|
||||
if isinstance(ret, dict):
|
||||
self.vm.store_mfn = ret.get('store_mfn')
|
||||
self.vm.console_mfn = ret.get('console_mfn')
|
||||
self.set_vminfo(ret)
|
||||
return 0
|
||||
return ret
|
||||
|
||||
@@ -318,7 +323,7 @@ class VmxImageHandler(ImageHandler):
|
||||
flags = self.flags,
|
||||
vcpus = self.vm.vcpus)
|
||||
if isinstance(ret, dict):
|
||||
self.vm.store_mfn = ret.get('store_mfn')
|
||||
self.set_vminfo(ret)
|
||||
return 0
|
||||
return ret
|
||||
|
||||
|
||||
@@ -41,21 +41,21 @@ class SrvDomain(SrvDir):
|
||||
fn = FormFn(self.xd.domain_configure,
|
||||
[['dom', 'int'],
|
||||
['config', 'sxpr']])
|
||||
return fn(req.args, {'dom': self.dom.id})
|
||||
return fn(req.args, {'dom': self.dom.domid})
|
||||
|
||||
def op_unpause(self, op, req):
|
||||
val = self.xd.domain_unpause(self.dom.id)
|
||||
val = self.xd.domain_unpause(self.dom.domid)
|
||||
return val
|
||||
|
||||
def op_pause(self, op, req):
|
||||
val = self.xd.domain_pause(self.dom.id)
|
||||
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.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
req.setResponseCode(http.ACCEPTED)
|
||||
req.setHeader("Location", "%s/.." % req.prePathURL())
|
||||
return val
|
||||
@@ -64,7 +64,7 @@ class SrvDomain(SrvDir):
|
||||
fn = FormFn(self.xd.domain_sysrq,
|
||||
[['dom', 'int'],
|
||||
['key', 'int']])
|
||||
val = fn(req.args, {'dom' : self.dom.id})
|
||||
val = fn(req.args, {'dom' : self.dom.domid})
|
||||
req.setResponseCode(http.ACCEPTED)
|
||||
req.setHeader("Location", "%s/.." % req.prePathURL())
|
||||
return val
|
||||
@@ -73,7 +73,7 @@ class SrvDomain(SrvDir):
|
||||
fn = FormFn(self.xd.domain_destroy,
|
||||
[['dom', 'int'],
|
||||
['reason', 'str']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
req.setHeader("Location", "%s/.." % req.prePathURL())
|
||||
return val
|
||||
|
||||
@@ -84,7 +84,7 @@ class SrvDomain(SrvDir):
|
||||
fn = FormFn(self.xd.domain_save,
|
||||
[['dom', 'int'],
|
||||
['file', 'str']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return 0
|
||||
|
||||
def op_migrate(self, op, req):
|
||||
@@ -96,14 +96,14 @@ class SrvDomain(SrvDir):
|
||||
['destination', 'str'],
|
||||
['live', 'int'],
|
||||
['resource', 'int']])
|
||||
return fn(req.args, {'dom': self.dom.id})
|
||||
return fn(req.args, {'dom': self.dom.domid})
|
||||
|
||||
def op_pincpu(self, op, req):
|
||||
fn = FormFn(self.xd.domain_pincpu,
|
||||
[['dom', 'int'],
|
||||
['vcpu', 'int'],
|
||||
['cpumap', 'int']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def op_cpu_bvt_set(self, op, req):
|
||||
@@ -114,7 +114,7 @@ class SrvDomain(SrvDir):
|
||||
['warpvalue', 'int'],
|
||||
['warpl', 'long'],
|
||||
['warpu', 'long']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
|
||||
@@ -126,28 +126,28 @@ class SrvDomain(SrvDir):
|
||||
['latency', 'int'],
|
||||
['extratime', 'int'],
|
||||
['weight', 'int']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def op_maxmem_set(self, op, req):
|
||||
fn = FormFn(self.xd.domain_maxmem_set,
|
||||
[['dom', 'int'],
|
||||
['memory', 'int']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
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.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def op_devices(self, op, req):
|
||||
fn = FormFn(self.xd.domain_devtype_ls,
|
||||
[['dom', 'int'],
|
||||
['type', 'str']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def op_device(self, op, req):
|
||||
@@ -155,7 +155,7 @@ class SrvDomain(SrvDir):
|
||||
[['dom', 'int'],
|
||||
['type', 'str'],
|
||||
['idx', 'int']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
if val:
|
||||
return val.sxpr()
|
||||
else:
|
||||
@@ -165,7 +165,7 @@ class SrvDomain(SrvDir):
|
||||
fn = FormFn(self.xd.domain_device_create,
|
||||
[['dom', 'int'],
|
||||
['config', 'sxpr']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def op_device_refresh(self, op, req):
|
||||
@@ -173,7 +173,7 @@ class SrvDomain(SrvDir):
|
||||
[['dom', 'int'],
|
||||
['type', 'str'],
|
||||
['idx', 'str']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def op_device_destroy(self, op, req):
|
||||
@@ -181,7 +181,7 @@ class SrvDomain(SrvDir):
|
||||
[['dom', 'int'],
|
||||
['type', 'str'],
|
||||
['idx', 'str']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def op_device_configure(self, op, req):
|
||||
@@ -189,7 +189,7 @@ class SrvDomain(SrvDir):
|
||||
[['dom', 'int'],
|
||||
['config', 'sxpr'],
|
||||
['idx', 'str']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def op_vif_limit_set(self, op, req):
|
||||
@@ -198,7 +198,7 @@ class SrvDomain(SrvDir):
|
||||
['vif', 'int'],
|
||||
['credit', 'int'],
|
||||
['period', 'int']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def op_vcpu_hotplug(self, op, req):
|
||||
@@ -206,7 +206,7 @@ class SrvDomain(SrvDir):
|
||||
[['dom', 'int'],
|
||||
['vcpu', 'int'],
|
||||
['state', 'int']])
|
||||
val = fn(req.args, {'dom': self.dom.id})
|
||||
val = fn(req.args, {'dom': self.dom.domid})
|
||||
return val
|
||||
|
||||
def render_POST(self, req):
|
||||
|
||||
@@ -154,7 +154,7 @@ class SrvDomainDir(SrvDir):
|
||||
for d in domains:
|
||||
req.write('<li><a href="%s%s"> Domain %s</a>'
|
||||
% (url, d.name, d.name))
|
||||
req.write('id=%s' % d.id)
|
||||
req.write('id=%s' % d.domid)
|
||||
req.write('memory=%d'% d.memory)
|
||||
req.write('ssidref=%d'% d.ssidref)
|
||||
req.write('</li>')
|
||||
|
||||
@@ -123,7 +123,7 @@ class BlkDev(Dev):
|
||||
def init(self, recreate=False, reboot=False):
|
||||
self.frontendDomain = self.getDomain()
|
||||
backend = self.getBackend()
|
||||
self.backendId = backend.id
|
||||
self.backendId = backend.domid
|
||||
|
||||
def configure(self, config, change=False, recreate=False):
|
||||
if change:
|
||||
@@ -146,7 +146,7 @@ class BlkDev(Dev):
|
||||
|
||||
try:
|
||||
xd = get_component('xen.xend.XendDomain')
|
||||
self.backendDomain = xd.domain_lookup_by_name(sxp.child_value(config, 'backend', '0')).id
|
||||
self.backendDomain = xd.domain_lookup_by_name(sxp.child_value(config, 'backend', '0')).domid
|
||||
except:
|
||||
raise XendError('invalid backend domain')
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ class NetDev(Dev):
|
||||
else:
|
||||
#todo: Code below will fail on xend restart when backend is not domain 0.
|
||||
xd = get_component('xen.xend.XendDomain')
|
||||
self.backendDomain = xd.domain_lookup_by_name(sxp.child_value(config, 'backend', '0')).id
|
||||
self.backendDomain = xd.domain_lookup_by_name(sxp.child_value(config, 'backend', '0')).domid
|
||||
except:
|
||||
raise XendError('invalid backend domain')
|
||||
return self.config
|
||||
@@ -206,7 +206,7 @@ class NetDev(Dev):
|
||||
mtu = self._get_config_mtu(config)
|
||||
|
||||
xd = get_component('xen.xend.XendDomain')
|
||||
backendDomain = xd.domain_lookup_by_name(sxp.child_value(config, 'backend', '0')).id
|
||||
backendDomain = xd.domain_lookup_by_name(sxp.child_value(config, 'backend', '0')).domid
|
||||
|
||||
if (mac is not None) and (mac != self.mac):
|
||||
raise XendError("cannot change mac")
|
||||
|
||||
@@ -365,18 +365,6 @@ class XenStore:
|
||||
finally:
|
||||
self.watchThread = None
|
||||
|
||||
def introduceDomain(self, dom, page, evtchn, path):
|
||||
try:
|
||||
self.getxs().introduce_domain(dom, page, evtchn.port1, path)
|
||||
except RuntimeError, ex:
|
||||
if ex.args[0] == errno.EISCONN:
|
||||
return None
|
||||
else:
|
||||
raise
|
||||
|
||||
def releaseDomain(self, dom):
|
||||
self.getxs().release_domain(dom)
|
||||
|
||||
def getXenStore():
|
||||
global xenstore
|
||||
try:
|
||||
@@ -461,12 +449,6 @@ class XenNode:
|
||||
def ls(self):
|
||||
return self.store.ls(self.path)
|
||||
|
||||
def introduceDomain(self, dom, page, evtchn, path):
|
||||
self.store.introduceDomain(dom, page, evtchn, path)
|
||||
|
||||
def releaseDomain(self, dom):
|
||||
self.store.releaseDomain(dom)
|
||||
|
||||
def watch(self, fn, path=""):
|
||||
"""Watch a path for changes. The path is relative
|
||||
to the node and defaults to the node itself.
|
||||
|
||||
@@ -319,30 +319,6 @@ class DBMap(dict):
|
||||
def getPath(self):
|
||||
return self.__db__ and self.__db__.relPath()
|
||||
|
||||
def introduceDomain(self, dom, page, evtchn, path=None):
|
||||
db = self.__db__
|
||||
if path is None:
|
||||
path = db.relPath()
|
||||
log.info("DBMap>introduceDomain> %d %d %s %s" %(dom, page, evtchn, path))
|
||||
try:
|
||||
db.introduceDomain(dom, page, evtchn, path)
|
||||
except Exception, ex:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
log.info("DBMap>introduceDomain> %s" %ex)
|
||||
pass # todo: don't ignore
|
||||
|
||||
def releaseDomain(self, dom):
|
||||
db = self.__db__
|
||||
log.info("DBMap>releaseDomain> %d" %dom)
|
||||
try:
|
||||
db.releaseDomain(dom)
|
||||
except Exception, ex:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
log.info("DBMap>releaseDomain> %s" %ex)
|
||||
pass # todo: don't ignore
|
||||
|
||||
def watch(self, fn, path=""):
|
||||
return self.__db__.watch(fn, path=path)
|
||||
|
||||
@@ -509,9 +485,11 @@ class DBMap(dict):
|
||||
if self.__db__ is None:
|
||||
return
|
||||
self.__data__ = self.__db__.getData()
|
||||
for k in self.__db__.ls():
|
||||
n = self.addChild(k)
|
||||
n.readDB()
|
||||
l = self.__db__.ls()
|
||||
if l:
|
||||
for k in l:
|
||||
n = self.addChild(k)
|
||||
n.readDB()
|
||||
self.__dirty__ = False
|
||||
|
||||
def readChildDB(self, k):
|
||||
|
||||
@@ -7,14 +7,7 @@
|
||||
import errno
|
||||
import threading
|
||||
from xen.lowlevel import xs
|
||||
|
||||
handles = {}
|
||||
|
||||
# XXX need to g/c handles from dead threads
|
||||
def xshandle():
|
||||
if not handles.has_key(threading.currentThread()):
|
||||
handles[threading.currentThread()] = xs.open()
|
||||
return handles[threading.currentThread()]
|
||||
from xen.xend.xenstore.xsutil import xshandle
|
||||
|
||||
class xstransact:
|
||||
|
||||
@@ -43,8 +36,6 @@ class xstransact:
|
||||
return xshandle().transaction_end(False)
|
||||
|
||||
def abort(self):
|
||||
if not self.in_transaction:
|
||||
raise RuntimeError
|
||||
self.in_transaction = False
|
||||
return xshandle().transaction_end(True)
|
||||
|
||||
@@ -100,7 +91,10 @@ class xstransact:
|
||||
|
||||
def _list(self, key):
|
||||
path = "%s/%s" % (self.path, key)
|
||||
return map(lambda x: key + "/" + x, xshandle().ls(path))
|
||||
l = xshandle().ls(path)
|
||||
if l:
|
||||
return map(lambda x: key + "/" + x, l)
|
||||
return []
|
||||
|
||||
def list(self, *args):
|
||||
if len(args) == 0:
|
||||
@@ -110,6 +104,45 @@ class xstransact:
|
||||
ret.extend(self._list(key))
|
||||
return ret
|
||||
|
||||
def gather(self, *args):
|
||||
if len(args) and type(args[0]) != tuple:
|
||||
args = args,
|
||||
ret = []
|
||||
for tup in args:
|
||||
if len(tup) == 2:
|
||||
(key, fn) = tup
|
||||
defval = None
|
||||
else:
|
||||
(key, fn, defval) = tup
|
||||
try:
|
||||
val = fn(self._read(key))
|
||||
except TypeError:
|
||||
val = defval
|
||||
ret.append(val)
|
||||
if len(ret) == 1:
|
||||
return ret[0]
|
||||
return ret
|
||||
|
||||
def store(self, *args):
|
||||
if len(args) and type(args[0]) != tuple:
|
||||
args = args,
|
||||
for tup in args:
|
||||
if len(tup) == 2:
|
||||
(key, val) = tup
|
||||
try:
|
||||
fmt = { str : "%s",
|
||||
int : "%i",
|
||||
float : "%f",
|
||||
type(None) : None }[type(val)]
|
||||
except KeyError:
|
||||
raise TypeError
|
||||
else:
|
||||
(key, val, fmt) = tup
|
||||
if val is None:
|
||||
self._remove(key)
|
||||
else:
|
||||
self._write(key, fmt % val)
|
||||
|
||||
|
||||
def Read(cls, path, *args):
|
||||
while True:
|
||||
@@ -119,8 +152,13 @@ class xstransact:
|
||||
t.commit()
|
||||
return v
|
||||
except RuntimeError, ex:
|
||||
t.abort()
|
||||
if ex.args[0] == errno.ETIMEDOUT:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
except:
|
||||
t.abort()
|
||||
raise
|
||||
|
||||
Read = classmethod(Read)
|
||||
@@ -133,13 +171,18 @@ class xstransact:
|
||||
t.commit()
|
||||
return
|
||||
except RuntimeError, ex:
|
||||
t.abort()
|
||||
if ex.args[0] == errno.ETIMEDOUT:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
except:
|
||||
t.abort()
|
||||
raise
|
||||
|
||||
Write = classmethod(Write)
|
||||
|
||||
def Remove(cls, *args):
|
||||
def Remove(cls, path, *args):
|
||||
while True:
|
||||
try:
|
||||
t = cls(path)
|
||||
@@ -147,8 +190,13 @@ class xstransact:
|
||||
t.commit()
|
||||
return
|
||||
except RuntimeError, ex:
|
||||
t.abort()
|
||||
if ex.args[0] == errno.ETIMEDOUT:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
except:
|
||||
t.abort()
|
||||
raise
|
||||
|
||||
Remove = classmethod(Remove)
|
||||
@@ -161,8 +209,51 @@ class xstransact:
|
||||
t.commit()
|
||||
return v
|
||||
except RuntimeError, ex:
|
||||
t.abort()
|
||||
if ex.args[0] == errno.ETIMEDOUT:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
except:
|
||||
t.abort()
|
||||
raise
|
||||
|
||||
List = classmethod(List)
|
||||
|
||||
def Gather(cls, path, *args):
|
||||
while True:
|
||||
try:
|
||||
t = cls(path)
|
||||
v = t.gather(*args)
|
||||
t.commit()
|
||||
return v
|
||||
except RuntimeError, ex:
|
||||
t.abort()
|
||||
if ex.args[0] == errno.ETIMEDOUT:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
except:
|
||||
t.abort()
|
||||
raise
|
||||
|
||||
Gather = classmethod(Gather)
|
||||
|
||||
def Store(cls, path, *args):
|
||||
while True:
|
||||
try:
|
||||
t = cls(path)
|
||||
v = t.store(*args)
|
||||
t.commit()
|
||||
return v
|
||||
except RuntimeError, ex:
|
||||
t.abort()
|
||||
if ex.args[0] == errno.ETIMEDOUT:
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
except:
|
||||
t.abort()
|
||||
raise
|
||||
|
||||
Store = classmethod(Store)
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
|
||||
|
||||
# This file is subject to the terms and conditions of the GNU General
|
||||
# Public License. See the file "COPYING" in the main directory of
|
||||
# this archive for more details.
|
||||
|
||||
import threading
|
||||
from xen.lowlevel import xs
|
||||
|
||||
handles = {}
|
||||
|
||||
# XXX need to g/c handles from dead threads
|
||||
def xshandle():
|
||||
if not handles.has_key(threading.currentThread()):
|
||||
handles[threading.currentThread()] = xs.open()
|
||||
return handles[threading.currentThread()]
|
||||
|
||||
|
||||
def IntroduceDomain(domid, page, port, path):
|
||||
return xshandle().introduce_domain(domid, page, port, path)
|
||||
@@ -750,7 +750,7 @@ def make_domain(opts, config):
|
||||
server.xend_domain_destroy(dom)
|
||||
opts.err("Failed to unpause domain %s" % dom)
|
||||
opts.info("Started domain %s" % (dom))
|
||||
return int(sxp.child_value(dominfo, 'id'))
|
||||
return int(sxp.child_value(dominfo, 'domid'))
|
||||
|
||||
def get_dom0_alloc():
|
||||
"""Return current allocation memory of dom0 (in MB). Return 0 on error"""
|
||||
|
||||
+60
-55
@@ -64,7 +64,6 @@ xm full list of subcommands:
|
||||
Domain Commands:
|
||||
console <DomId> attach to console of DomId
|
||||
cpus-list <DomId> <VCpu> get the list of cpus for a VCPU
|
||||
cpus-set <DomId> <VCpu> <CPUS> set which cpus a VCPU can use.
|
||||
create <ConfigFile> create a domain
|
||||
destroy <DomId> terminate a domain immediately
|
||||
domid <DomName> convert a domain name to a domain id
|
||||
@@ -83,6 +82,7 @@ xm full list of subcommands:
|
||||
vcpu-enable <DomId> <VCPU> disable VCPU in a domain
|
||||
vcpu-disable <DomId> <VCPU> enable VCPU in a domain
|
||||
vcpu-list <DomId> get the list of VCPUs for a domain
|
||||
vcpu-pin <DomId> <VCpu> <CPUS> set which cpus a VCPU can use.
|
||||
|
||||
Xen Host Commands:
|
||||
dmesg [--clear] read or clear Xen's message buffer
|
||||
@@ -91,14 +91,15 @@ xm full list of subcommands:
|
||||
top monitor system and domains in real-time
|
||||
|
||||
Scheduler Commands:
|
||||
bvt <options> set BVT scheduler parameters
|
||||
bvt_ctxallow <Allow> set the BVT scheduler context switch allowance
|
||||
sedf <options> set simple EDF parameters
|
||||
sched-bvt <options> set BVT scheduler parameters
|
||||
sched-bvt-ctxallow <Allow>
|
||||
Set the BVT scheduler context switch allowance
|
||||
sched-sedf <options> set simple EDF parameters
|
||||
|
||||
Virtual Device Commands:
|
||||
block-create <DomId> <BackDev> <FrontDev> <Mode> [BackDomId]
|
||||
block-attach <DomId> <BackDev> <FrontDev> <Mode> [BackDomId]
|
||||
Create a new virtual block device
|
||||
block-destroy <DomId> <DevId> Destroy a domain's virtual block device
|
||||
block-detach <DomId> <DevId> Destroy a domain's virtual block device
|
||||
block-list <DomId> List virtual block devices for a domain
|
||||
block-refresh <DomId> <DevId> Refresh a virtual block device for a domain
|
||||
network-limit <DomId> <Vif> <Credit> <Period>
|
||||
@@ -172,8 +173,7 @@ def xm_create(args):
|
||||
from xen.xm import create
|
||||
# ugly hack because the opt parser apparently wants
|
||||
# the subcommand name just to throw it away!
|
||||
args.insert(0,"bogus")
|
||||
create.main(args)
|
||||
create.main(["bogus"] + args)
|
||||
|
||||
def xm_save(args):
|
||||
arg_check(args,2,"save")
|
||||
@@ -192,17 +192,16 @@ def xm_restore(args):
|
||||
from xen.xend.XendClient import server
|
||||
info = server.xend_domain_restore(savefile)
|
||||
PrettyPrint.prettyprint(info)
|
||||
id = sxp.child_value(info, 'id')
|
||||
id = sxp.child_value(info, 'domid')
|
||||
if id is not None:
|
||||
server.xend_domain_unpause(id)
|
||||
server.xend_domain_unpause(domid)
|
||||
|
||||
def xm_migrate(args):
|
||||
# TODO: arg_check
|
||||
from xen.xm import migrate
|
||||
# ugly hack because the opt parser apparently wants
|
||||
# the subcommand name just to throw it away!
|
||||
args.insert(0,"bogus")
|
||||
migrate.main(args)
|
||||
migrate.main(["bogus"] + args)
|
||||
|
||||
def xm_list(args):
|
||||
use_long = 0
|
||||
@@ -242,7 +241,7 @@ def xm_list(args):
|
||||
|
||||
def parse_doms_info(info):
|
||||
dominfo = {}
|
||||
dominfo['dom'] = int(sxp.child_value(info, 'id', '-1'))
|
||||
dominfo['dom'] = int(sxp.child_value(info, 'domid', '-1'))
|
||||
dominfo['name'] = sxp.child_value(info, 'name', '??')
|
||||
dominfo['mem'] = int(sxp.child_value(info, 'memory', '0'))
|
||||
dominfo['cpu'] = str(sxp.child_value(info, 'cpu', '0'))
|
||||
@@ -265,7 +264,7 @@ def parse_doms_info(info):
|
||||
for cpu in vcpu_to_cpu:
|
||||
vcpuinfo = {}
|
||||
vcpuinfo['name'] = sxp.child_value(info, 'name', '??')
|
||||
vcpuinfo['dom'] = int(sxp.child_value(info, 'id', '-1'))
|
||||
vcpuinfo['dom'] = int(sxp.child_value(info, 'domid', '-1'))
|
||||
vcpuinfo['vcpu'] = int(count)
|
||||
vcpuinfo['cpu'] = int(cpu)
|
||||
vcpuinfo['cpumap'] = int(cpumap[count])&mask
|
||||
@@ -289,8 +288,7 @@ def xm_show_vcpus(domsinfo):
|
||||
vcpuinfo)
|
||||
|
||||
def xm_vcpu_list(args):
|
||||
args.insert(0,"-v")
|
||||
xm_list(args)
|
||||
xm_list(["-v"] + args)
|
||||
|
||||
def xm_destroy(args):
|
||||
arg_check(args,1,"destroy")
|
||||
@@ -298,33 +296,28 @@ def xm_destroy(args):
|
||||
from xen.xm import destroy
|
||||
# ugly hack because the opt parser apparently wants
|
||||
# the subcommand name just to throw it away!
|
||||
args.insert(0,"bogus")
|
||||
destroy.main(args)
|
||||
destroy.main(["bogus"] + args)
|
||||
|
||||
def xm_reboot(args):
|
||||
arg_check(args,1,"reboot")
|
||||
from xen.xm import shutdown
|
||||
# ugly hack because the opt parser apparently wants
|
||||
# the subcommand name just to throw it away!
|
||||
args.insert(0,"bogus")
|
||||
args.insert(2,"-R")
|
||||
from xen.xm import shutdown
|
||||
shutdown.main(args)
|
||||
shutdown.main(["bogus", "-R"] + args)
|
||||
|
||||
def xm_shutdown(args):
|
||||
arg_check(args,1,"shutdown")
|
||||
|
||||
from xen.xm import shutdown
|
||||
# ugly hack because the opt parser apparently wants
|
||||
# the subcommand name just to throw it away!
|
||||
args.insert(0,"bogus")
|
||||
from xen.xm import shutdown
|
||||
shutdown.main(args)
|
||||
shutdown.main(["bogus"] + args)
|
||||
|
||||
def xm_sysrq(args):
|
||||
from xen.xm import sysrq
|
||||
# ugly hack because the opt parser apparently wants
|
||||
# the subcommand name just to throw it away!
|
||||
args.insert(0,"bogus")
|
||||
sysrq.main(args)
|
||||
sysrq.main(["bogus"] + args)
|
||||
|
||||
def xm_pause(args):
|
||||
arg_check(args, 1, "pause")
|
||||
@@ -358,8 +351,8 @@ def cpu_make_map(cpulist):
|
||||
|
||||
return cpumap
|
||||
|
||||
def xm_cpus_set(args):
|
||||
arg_check(args, 3, "cpus-set")
|
||||
def xm_vcpu_pin(args):
|
||||
arg_check(args, 3, "vcpu-pin")
|
||||
|
||||
dom = args[0]
|
||||
vcpu = int(args[1])
|
||||
@@ -395,7 +388,7 @@ def xm_vcpu_enable(args):
|
||||
|
||||
from xen.xend.XendClient import server
|
||||
dom = server.xend_domain(name)
|
||||
id = sxp.child_value(dom, 'id')
|
||||
id = sxp.child_value(dom, 'domid')
|
||||
server.xend_domain_vcpu_hotplug(id, vcpu, 1)
|
||||
|
||||
def xm_vcpu_disable(args):
|
||||
@@ -406,7 +399,7 @@ def xm_vcpu_disable(args):
|
||||
|
||||
from xen.xend.XendClient import server
|
||||
dom = server.xend_domain(name)
|
||||
id = sxp.child_value(dom, 'id')
|
||||
id = sxp.child_value(dom, 'domid')
|
||||
server.xend_domain_vcpu_hotplug(id, vcpu, 0)
|
||||
|
||||
def xm_domid(args):
|
||||
@@ -414,7 +407,7 @@ def xm_domid(args):
|
||||
|
||||
from xen.xend.XendClient import server
|
||||
dom = server.xend_domain(name)
|
||||
print sxp.child_value(dom, 'id')
|
||||
print sxp.child_value(dom, 'domid')
|
||||
|
||||
def xm_domname(args):
|
||||
name = args[0]
|
||||
@@ -423,22 +416,22 @@ def xm_domname(args):
|
||||
dom = server.xend_domain(name)
|
||||
print sxp.child_value(dom, 'name')
|
||||
|
||||
def xm_bvt(args):
|
||||
arg_check(args, 6, "bvt")
|
||||
def xm_sched_bvt(args):
|
||||
arg_check(args, 6, "sched-bvt")
|
||||
dom = args[0]
|
||||
v = map(long, args[1:6])
|
||||
from xen.xend.XendClient import server
|
||||
server.xend_domain_cpu_bvt_set(dom, *v)
|
||||
|
||||
def xm_bvt_ctxallow(args):
|
||||
arg_check(args, 1, "bvt_ctxallow")
|
||||
def xm_sched_bvt_ctxallow(args):
|
||||
arg_check(args, 1, "sched-bvt-ctxallow")
|
||||
|
||||
slice = int(args[0])
|
||||
from xen.xend.XendClient import server
|
||||
server.xend_node_cpu_bvt_slice_set(slice)
|
||||
|
||||
def xm_sedf(args):
|
||||
arg_check(args, 6, "sedf")
|
||||
def xm_sched_sedf(args):
|
||||
arg_check(args, 6, "sched-sedf")
|
||||
|
||||
dom = args[0]
|
||||
v = map(int, args[1:6])
|
||||
@@ -462,7 +455,7 @@ def xm_console(args):
|
||||
dom = args[0]
|
||||
from xen.xend.XendClient import server
|
||||
info = server.xend_domain(dom)
|
||||
domid = int(sxp.child_value(info, 'id', '-1'))
|
||||
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")
|
||||
@@ -482,10 +475,11 @@ its contents if the [-c|--clear] flag is specified.
|
||||
fn=set_true, default=0,
|
||||
use="Clear the contents of the Xen message buffer.")
|
||||
# Work around for gopts
|
||||
args.insert(0,"bogus")
|
||||
gopts.parse(args)
|
||||
if not (1 <= len(args) <= 2):
|
||||
err('Invalid arguments: ' + str(args))
|
||||
myargs = args
|
||||
myargs.insert(0, "bogus")
|
||||
gopts.parse(myargs)
|
||||
if not (1 <= len(myargs) <= 2):
|
||||
err('Invalid arguments: ' + str(myargs))
|
||||
|
||||
from xen.xend.XendClient import server
|
||||
if not gopts.vals.clear:
|
||||
@@ -512,6 +506,14 @@ def xm_network_list(args):
|
||||
sxp.show(x)
|
||||
print
|
||||
|
||||
def xm_network_attach(args):
|
||||
|
||||
print "Not implemented"
|
||||
|
||||
def xm_network_detach(args):
|
||||
|
||||
print "Not implemented"
|
||||
|
||||
def xm_block_list(args):
|
||||
arg_check(args,1,"block-list")
|
||||
dom = args[0]
|
||||
@@ -520,11 +522,14 @@ def xm_block_list(args):
|
||||
sxp.show(x)
|
||||
print
|
||||
|
||||
def xm_block_create(args):
|
||||
def xm_block_attach(args):
|
||||
n = len(args)
|
||||
if n == 0:
|
||||
usage("block-attach")
|
||||
|
||||
if n < 4 or n > 5:
|
||||
err("%s: Invalid argument(s)" % args[0])
|
||||
usage("block-create")
|
||||
usage("block-attach")
|
||||
|
||||
dom = args[0]
|
||||
vbd = ['vbd',
|
||||
@@ -546,8 +551,8 @@ def xm_block_refresh(args):
|
||||
from xen.xend.XendClient import server
|
||||
server.xend_domain_device_refresh(dom, 'vbd', dev)
|
||||
|
||||
def xm_block_destroy(args):
|
||||
arg_check(args,2,"block-destroy")
|
||||
def xm_block_detach(args):
|
||||
arg_check(args,2,"block-detach")
|
||||
|
||||
dom = args[0]
|
||||
dev = args[1]
|
||||
@@ -615,7 +620,7 @@ commands = {
|
||||
"mem-max": xm_mem_max,
|
||||
"mem-set": xm_mem_set,
|
||||
# cpu commands
|
||||
"cpus-set": xm_cpus_set,
|
||||
"vcpu-pin": xm_vcpu_pin,
|
||||
# "cpus-list": xm_cpus_list,
|
||||
"vcpu-enable": xm_vcpu_enable,
|
||||
"vcpu-disable": xm_vcpu_disable,
|
||||
@@ -631,17 +636,19 @@ commands = {
|
||||
"info": xm_info,
|
||||
"log": xm_log,
|
||||
# scheduler
|
||||
"bvt": xm_bvt,
|
||||
"bvt_ctxallow": xm_bvt_ctxallow,
|
||||
"sedf": xm_sedf,
|
||||
"sched-bvt": xm_sched_bvt,
|
||||
"sched-bvt-ctxallow": xm_sched_bvt_ctxallow,
|
||||
"sched-sedf": xm_sched_sedf,
|
||||
# block
|
||||
"block-create": xm_block_create,
|
||||
"block-destroy": xm_block_destroy,
|
||||
"block-attach": xm_block_attach,
|
||||
"block-detach": xm_block_detach,
|
||||
"block-list": xm_block_list,
|
||||
"block-refresh": xm_block_refresh,
|
||||
# network
|
||||
"network-limit": xm_network_limit,
|
||||
"network-list": xm_network_list,
|
||||
"network-attach": xm_network_attach,
|
||||
"network-detach": xm_network_detach,
|
||||
# vnet
|
||||
"vnet-list": xm_vnet_list,
|
||||
"vnet-create": xm_vnet_create,
|
||||
@@ -719,8 +726,6 @@ def main(argv=sys.argv):
|
||||
sys.exit(1)
|
||||
except XendError, ex:
|
||||
if len(args) > 0:
|
||||
if args[0] == "bogus":
|
||||
args.remove("bogus")
|
||||
handle_xend_error(argv[1], args[0], ex)
|
||||
else:
|
||||
print "Unexpected error:", sys.exc_info()[0]
|
||||
|
||||