aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-10-16 09:04:53 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-10-16 09:04:53 +0100
commit27759c390cd331a1882c8cf3047a52751a95373c (patch)
treeeb9c91345f4e72ad5436c977c651e3f8af6050a9
parent5a0730a43591dddd413d0f1b72ef5aa37997d60e (diff)
downloadxen-27759c390cd331a1882c8cf3047a52751a95373c.tar.gz
xen-27759c390cd331a1882c8cf3047a52751a95373c.tar.bz2
xen-27759c390cd331a1882c8cf3047a52751a95373c.zip
xend: Implement VBD.media_change
Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
-rw-r--r--tools/python/xen/xend/XendAPI.py40
-rw-r--r--tools/python/xen/xend/XendDomainInfo.py31
2 files changed, 69 insertions, 2 deletions
diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py
index a489db01b1..6c492d94b5 100644
--- a/tools/python/xen/xend/XendAPI.py
+++ b/tools/python/xen/xend/XendAPI.py
@@ -1960,8 +1960,44 @@ class XendAPI(object):
return xen_api_success(return_cfg)
- def VBD_media_change(self, session, vbd_ref, vdi_ref):
- return xen_api_error(XEND_ERROR_UNSUPPORTED)
+ def VBD_media_change(self, session, vbd_ref, new_vdi_ref):
+ xendom = XendDomain.instance()
+ xennode = XendNode.instance()
+
+ vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
+ if not vm:
+ return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
+ cur_vbd_struct = vm.get_dev_xenapi_config('vbd', vbd_ref)
+ if not cur_vbd_struct:
+ return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
+ if cur_vbd_struct['type'] != XEN_API_VBD_TYPE[0]: # Not CD
+ return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
+ if cur_vbd_struct['mode'] != 'RO': # Not read only
+ return xen_api_error(['HANDLE_INVALID', 'VBD', vbd_ref])
+
+ new_vdi = xennode.get_vdi_by_uuid(new_vdi_ref)
+ if not new_vdi:
+ return xen_api_error(['HANDLE_INVALID', 'VDI', new_vdi_ref])
+ new_vdi_image = new_vdi.get_location()
+
+ valid_vbd_keys = self.VBD_attr_ro + self.VBD_attr_rw + \
+ self.Base_attr_ro + self.Base_attr_rw
+
+ new_vbd_struct = {}
+ for k in cur_vbd_struct.keys():
+ if k in valid_vbd_keys:
+ new_vbd_struct[k] = cur_vbd_struct[k]
+ new_vbd_struct['VDI'] = new_vdi_ref
+
+ try:
+ XendTask.log_progress(0, 100,
+ vm.change_vdi_of_vbd,
+ new_vbd_struct, new_vdi_image)
+ except XendError, e:
+ log.exception("Error in VBD_media_change")
+ return xen_api_error(['INTERNAL_ERROR', str(e)])
+
+ return xen_api_success_void()
# class methods
def VBD_create(self, session, vbd_struct):
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py
index d4fd6bffb8..e0891b46f3 100644
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -3970,6 +3970,37 @@ class XendDomainInfo:
return dscsi_uuid
+ def change_vdi_of_vbd(self, xenapi_vbd, vdi_image_path):
+ """Change current VDI with the new VDI.
+
+ @param xenapi_vbd: vbd struct from the Xen API
+ @param vdi_image_path: path of VDI
+ """
+ dev_uuid = xenapi_vbd['uuid']
+ if dev_uuid not in self.info['devices']:
+ raise XendError('Device does not exist')
+
+ # Convert xenapi to sxp
+ if vdi_image_path.startswith('tap'):
+ dev_class = 'tap'
+ else:
+ dev_class = 'vbd'
+ dev_sxp = [
+ dev_class,
+ ['uuid', dev_uuid],
+ ['uname', vdi_image_path],
+ ['dev', '%s:cdrom' % xenapi_vbd['device']],
+ ['mode', 'r'],
+ ['VDI', xenapi_vbd['VDI']]
+ ]
+
+ if self._stateGet() in (XEN_API_VM_POWER_STATE_RUNNING,
+ XEN_API_VM_POWER_STATE_PAUSED):
+ self.device_configure(dev_sxp)
+ else:
+ self.info.device_update(dev_uuid, dev_sxp)
+
+
def destroy_device_by_uuid(self, dev_type, dev_uuid):
if dev_uuid not in self.info['devices']:
raise XendError('Device does not exist')