Merge with xenppc-unstable.hg

This commit is contained in:
kfraser@localhost.localdomain committed 2007-02-14 19:01:35 +00:00
commit b3f09a8a4f
175 files changed
+5796 -3660

No files matched your search

+5 -2
View File
@@ -239,8 +239,11 @@ def restore(xd, fd, dominfo = None, paused = False):
forkHelper(cmd, fd, handler.handler, True)
if handler.store_mfn is None or handler.console_mfn is None:
raise XendError('Could not read store/console MFN')
if handler.store_mfn is None:
raise XendError('Could not read store MFN')
if not is_hvm and handler.console_mfn is None:
raise XendError('Could not read console MFN')
dominfo.waitForDevices() # Wait for backends to set up
if not paused:
+41
View File
@@ -1148,6 +1148,47 @@ class XendConfig(dict):
# no valid device to add
return ''
def phantom_device_add(self, dev_type, cfg_xenapi = None,
target = None):
"""Add a phantom tap device configuration in XenAPI struct format.
"""
if target == None:
target = self
if dev_type not in XendDevices.valid_devices() and \
dev_type not in XendDevices.pseudo_devices():
raise XendConfigError("XendConfig: %s not a valid device type" %
dev_type)
if cfg_xenapi == None:
raise XendConfigError("XendConfig: device_add requires some "
"config.")
if cfg_xenapi:
log.debug("XendConfig.phantom_device_add: %s" % str(cfg_xenapi))
if cfg_xenapi:
dev_info = {}
if dev_type in ('vbd', 'tap'):
if dev_type == 'vbd':
dev_info['uname'] = cfg_xenapi.get('image', '')
dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
elif dev_type == 'tap':
if cfg_xenapi.get('image').find('tap:') == -1:
dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
dev_info['dev'] = '/dev/%s' % cfg_xenapi.get('device')
dev_info['uname'] = cfg_xenapi.get('image')
dev_info['mode'] = cfg_xenapi.get('mode')
dev_info['backend'] = '0'
dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
dev_info['uuid'] = dev_uuid
self['devices'][dev_uuid] = (dev_type, dev_info)
self['vbd_refs'].append(dev_uuid)
return dev_uuid
return ''
def console_add(self, protocol, location, other_config = {}):
dev_uuid = uuid.createString()
if protocol == 'vt100':
+16 -4
View File
@@ -800,7 +800,10 @@ class XendDomain:
"support.")
path = self._managed_check_point_path(dom_uuid)
fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
oflags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
if hasattr(os, "O_LARGEFILE"):
oflags |= os.O_LARGEFILE
fd = os.open(path, oflags)
try:
# For now we don't support 'live checkpoint'
XendCheckpoint.save(fd, dominfo, False, False, path)
@@ -840,8 +843,11 @@ class XendDomain:
# Restore that replaces the existing XendDomainInfo
try:
log.debug('Current DomainInfo state: %d' % dominfo.state)
oflags = os.O_RDONLY
if hasattr(os, "O_LARGEFILE"):
oflags |= os.O_LARGEFILE
XendCheckpoint.restore(self,
os.open(chkpath, os.O_RDONLY),
os.open(chkpath, oflags),
dominfo,
paused = start_paused)
os.unlink(chkpath)
@@ -1009,7 +1015,10 @@ class XendDomain:
@raise XendError: Failure to restore domain
"""
try:
fd = os.open(src, os.O_RDONLY)
oflags = os.O_RDONLY
if hasattr(os, "O_LARGEFILE"):
oflags |= os.O_LARGEFILE
fd = os.open(src, oflags)
try:
return self.domain_restore_fd(fd, paused=paused)
finally:
@@ -1193,7 +1202,10 @@ class XendDomain:
if dominfo.getDomid() == DOM0_ID:
raise XendError("Cannot save privileged domain %i" % domid)
fd = os.open(dst, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
oflags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
if hasattr(os, "O_LARGEFILE"):
oflags |= os.O_LARGEFILE
fd = os.open(dst, oflags)
try:
# For now we don't support 'live checkpoint'
XendCheckpoint.save(fd, dominfo, False, False, dst)
+56 -2
View File
@@ -1416,7 +1416,7 @@ class XendDomainInfo:
self.info['image'],
self.info['devices'])
localtime = self.info.get('localtime', False)
localtime = self.info.get('platform_localtime', False)
if localtime:
xc.domain_set_time_offset(self.domid)
@@ -1565,19 +1565,54 @@ class XendDomainInfo:
# VM Destroy
#
def _prepare_phantom_paths(self):
# get associated devices to destroy
# build list of phantom devices to be removed after normal devices
plist = []
from xen.xend.xenstore.xstransact import xstransact
t = xstransact("%s/device/vbd" % GetDomainPath(self.domid))
for dev in t.list():
backend_phantom_vbd = xstransact.Read("%s/device/vbd/%s/phantom_vbd" \
% (self.dompath, dev))
if backend_phantom_vbd is not None:
frontend_phantom_vbd = xstransact.Read("%s/frontend" \
% backend_phantom_vbd)
plist.append(backend_phantom_vbd)
plist.append(frontend_phantom_vbd)
return plist
def _cleanup_phantom_devs(self, plist):
# remove phantom devices
if not plist == []:
time.sleep(2)
for paths in plist:
if paths.find('backend') != -1:
from xen.xend.server import DevController
# Modify online status /before/ updating state (latter is watched by
# drivers, so this ordering avoids a race).
xstransact.Write(paths, 'online', "0")
xstransact.Write(paths, 'state', str(DevController.xenbusState['Closing']))
# force
xstransact.Remove(paths)
def destroy(self):
"""Cleanup VM and destroy domain. Nothrow guarantee."""
log.debug("XendDomainInfo.destroy: domid=%s", str(self.domid))
paths = self._prepare_phantom_paths()
self._cleanupVm()
if self.dompath is not None:
self.destroyDomain()
self._cleanup_phantom_devs(paths)
def destroyDomain(self):
log.debug("XendDomainInfo.destroyDomain(%s)", str(self.domid))
paths = self._prepare_phantom_paths()
try:
if self.domid is not None:
xc.domain_destroy(self.domid)
@@ -1591,7 +1626,7 @@ class XendDomainInfo:
XendDomain.instance().remove_domain(self)
self.cleanupDomain()
self._cleanup_phantom_devs(paths)
def resumeDomain(self):
log.debug("XendDomainInfo.resumeDomain(%s)", str(self.domid))
@@ -2211,6 +2246,25 @@ class XendDomainInfo:
return dev_uuid
def create_phantom_vbd_with_vdi(self, xenapi_vbd, vdi_image_path):
"""Create a VBD using a VDI from XendStorageRepository.
@param xenapi_vbd: vbd struct from the Xen API
@param vdi_image_path: VDI UUID
@rtype: string
@return: uuid of the device
"""
xenapi_vbd['image'] = vdi_image_path
dev_uuid = self.info.phantom_device_add('tap', cfg_xenapi = xenapi_vbd)
if not dev_uuid:
raise XendError('Failed to create device')
if self.state == XEN_API_VM_POWER_STATE_RUNNING:
_, config = self.info['devices'][dev_uuid]
config['devid'] = self.getDeviceController('tap').createDevice(config)
return config['devid']
def create_vif(self, xenapi_vif):
"""Create VIF device from the passed struct in Xen API format.
@@ -2,7 +2,10 @@
from xen.xend.server.blkif import BlkifController
from xen.xend.XendLogging import log
phantomDev = 0;
phantomId = 0;
class BlktapController(BlkifController):
def __init__(self, vm):
@@ -12,3 +15,62 @@ class BlktapController(BlkifController):
"""@see DevController#frontendRoot"""
return "%s/device/vbd" % self.vm.getDomainPath()
def getDeviceDetails(self, config):
(devid, back, front) = BlkifController.getDeviceDetails(self, config)
phantomDevid = 0
wrapped = False
try:
imagetype = self.vm.info['image']['type']
except:
imagetype = ""
if imagetype == 'hvm':
tdevname = back['dev']
index = ['c', 'd', 'e', 'f', 'g', 'h', 'i', \
'j', 'l', 'm', 'n', 'o', 'p']
while True:
global phantomDev
global phantomId
import os, stat
phantomId = phantomId + 1
if phantomId == 16:
if index[phantomDev] == index[-1]:
if wrapped:
raise VmError(" No loopback block \
devices are available. ")
wrapped = True
phantomDev = 0
else:
phantomDev = phantomDev + 1
phantomId = 1
devname = 'xvd%s%d' % (index[phantomDev], phantomId)
try:
info = os.stat('/dev/%s' % devname)
except:
break
vbd = { 'mode': 'w', 'device': devname }
fn = 'tap:%s' % back['params']
# recurse ... by creating the vbd, then fallthrough
# and finish creating the original device
from xen.xend import XendDomain
dom0 = XendDomain.instance().privilegedDomain()
phantomDevid = dom0.create_phantom_vbd_with_vdi(vbd, fn)
# we need to wait for this device at a higher level
# the vbd that gets created will have a link to us
# and will let them do it there
# add a hook to point to the phantom device,
# root path is always the same (dom0 tap)
if phantomDevid != 0:
front['phantom_vbd'] = '/local/domain/0/backend/tap/0/%s' \
% str(phantomDevid)
return (devid, back, front)
+32 -18
View File
@@ -153,9 +153,9 @@ class DevController:
log.debug("Waiting for %s.", devid)
if not self.hotplug:
return
status = self.waitForBackend(devid)
return
(status, err) = self.waitForBackend(devid)
if status == Timeout:
self.destroyDevice(devid, False)
@@ -165,25 +165,22 @@ class DevController:
elif status == Error:
self.destroyDevice(devid, False)
raise VmError("Device %s (%s) could not be connected. "
"Backend device not found." %
(devid, self.deviceClass))
if err is None:
raise VmError("Device %s (%s) could not be connected. "
"Backend device not found." %
(devid, self.deviceClass))
else:
raise VmError("Device %s (%s) could not be connected. "
"%s" % (devid, self.deviceClass, err))
elif status == Missing:
# Don't try to destroy the device; it's already gone away.
raise VmError("Device %s (%s) could not be connected. "
"Device not found." % (devid, self.deviceClass))
elif status == Busy:
err = None
frontpath = self.frontendPath(devid)
backpath = xstransact.Read(frontpath, "backend")
if backpath:
err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
if not err:
err = "Busy."
self.destroyDevice(devid, False)
if err is None:
err = "Busy."
raise VmError("Device %s (%s) could not be connected.\n%s" %
(devid, self.deviceClass, err))
@@ -476,19 +473,36 @@ class DevController:
def waitForBackend(self, devid):
frontpath = self.frontendPath(devid)
# lookup a phantom
phantomPath = xstransact.Read(frontpath, 'phantom_vbd')
if phantomPath is not None:
log.debug("Waiting for %s's phantom %s.", devid, phantomPath)
statusPath = phantomPath + '/' + HOTPLUG_STATUS_NODE
ev = Event()
result = { 'status': Timeout }
xswatch(statusPath, hotplugStatusCallback, ev, result)
ev.wait(DEVICE_CREATE_TIMEOUT)
err = xstransact.Read(statusPath, HOTPLUG_ERROR_NODE)
if result['status'] != 'Connected':
return (result['status'], err)
backpath = xstransact.Read(frontpath, "backend")
if backpath:
statusPath = backpath + '/' + HOTPLUG_STATUS_NODE
ev = Event()
result = { 'status': Timeout }
xswatch(statusPath, hotplugStatusCallback, ev, result)
ev.wait(DEVICE_CREATE_TIMEOUT)
return result['status']
err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
return (result['status'], err)
else:
return Missing
return (Missing, None)
def backendPath(self, backdom, devid):
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.