# HG changeset patch
# User Alastair Tse <atse@xxxxxxxxxxxxx>
# Node ID c88a78f8bed98c705aa2300d6d4ded13479e6986
# Parent c0d9f8b9c0e592c58b36762a5cae8a4a54fe8ad5
[XEND] Proper support for devices with UUID. Removing old workaround
with augmented VM UUIDs with devids.
Signed-off-by: Alastair Tse <atse@xxxxxxxxxxxxx>
---
tools/python/xen/xend/XendAPI.py | 36 ++++++-
tools/python/xen/xend/XendConfig.py | 6 +
tools/python/xen/xend/XendDomain.py | 48 ++++------
tools/python/xen/xend/XendDomainInfo.py | 119 +++++++++++++++-----------
tools/python/xen/xend/server/DevController.py | 7 +
5 files changed, 132 insertions(+), 84 deletions(-)
diff -r c0d9f8b9c0e5 -r c88a78f8bed9 tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py Fri Oct 06 12:46:46 2006 +0100
+++ b/tools/python/xen/xend/XendAPI.py Fri Oct 06 16:27:06 2006 +0100
@@ -948,9 +948,14 @@ class XendAPI:
# object methods
def vbd_get_record(self, session, vbd_ref):
xendom = XendDomain.instance()
- return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref,
- 'driver'))
-
+ vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
+ if not vm:
+ return xen_api_error(XEND_ERROR_VIF_INVALID)
+ cfg = vm.get_dev_xenapi_config('vbd', vbd_ref)
+ if not cfg:
+ return xen_api_error(XEND_ERROR_UNKNOWN)
+ return xen_api_success(cfg)
+
# class methods
def vbd_create(self, session, vbd_struct):
xendom = XendDomain.instance()
@@ -968,20 +973,20 @@ class XendAPI:
# attributes (rw)
def vbd_get_vm(self, session, vbd_ref):
xendom = XendDomain.instance()
- return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref, 'VM'))
+ return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM'))
def vbd_get_vdi(self, session, vbd_ref):
return xen_api_error(XEND_ERROR_UNSUPPORTED)
def vbd_get_device(self, session, vbd_ref):
xendom = XendDomain.instance()
- return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref,
+ return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
'device'))
def vbd_get_mode(self, session, vbd_ref):
xendom = XendDomain.instance()
- return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref,
+ return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
'mode'))
def vbd_get_driver(self, session, vbd_ref):
xendom = XendDomain.instance()
- return xen_api_success(xendom.get_dev_by_uuid('vbd', vbd_ref,
+ return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
'driver'))
# Xen API: Class VIF
@@ -1001,6 +1006,23 @@ class XendAPI:
VIF_attr_inst = VIF_attr_rw
+ # object methods
+ def vif_get_record(self, session, vif_ref):
+ xendom = XendDomain.instance()
+ vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
+ if not vm:
+ return xen_api_error(XEND_ERROR_VIF_INVALID)
+ cfg = vm.get_dev_xenapi_config('vif', vif_ref)
+ if not cfg:
+ return xen_api_error(XEND_ERROR_UNKNOWN)
+ valid_vif_keys = self.VIF_attr_ro + self.VIF_attr_rw + \
+ self.Base_attr_ro + self.Base_attr_rw
+ for k in cfg.keys():
+ if k not in valid_vif_keys:
+ del cfg[k]
+
+ return xen_api_success(cfg)
+
# class methods
def vif_create(self, session, vif_struct):
xendom = XendDomain.instance()
diff -r c0d9f8b9c0e5 -r c88a78f8bed9 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Fri Oct 06 12:46:46 2006 +0100
+++ b/tools/python/xen/xend/XendConfig.py Fri Oct 06 16:27:06 2006 +0100
@@ -717,6 +717,12 @@ class XendConfig(dict):
raise XendConfigError('Invalid restart event: %s = %s' % \
(event, str(self[event])))
+ # Verify that {vif,vbd}_refs are here too
+ if 'vif_refs' not in self:
+ self['vif_refs'] = []
+ if 'vbd_refs' not in self:
+ self['vbd_refs'] = []
+
def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
if dev_type not in XendDevices.valid_devices():
raise XendConfigError("XendConfig: %s not a valid device type" %
diff -r c0d9f8b9c0e5 -r c88a78f8bed9 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Fri Oct 06 12:46:46 2006 +0100
+++ b/tools/python/xen/xend/XendDomain.py Fri Oct 06 16:27:06 2006 +0100
@@ -563,22 +563,25 @@ class XendDomain:
finally:
self.domains_lock.release()
- def get_dev_by_uuid(self, klass, dev_uuid, field):
- parts = dev_uuid.split('-%s-' % klass, 1)
- try:
- if len(parts) > 1:
- dom = self.get_vm_by_uuid(parts[0])
- if not dom:
- return None
-
- if field == 'VM':
- return dom.get_uuid()
- if field == 'uuid':
- return dev_uuid
-
- devid = int(parts[1])
- value = dom.get_device_property(klass, devid, field)
- return value
+ def get_vm_with_dev_uuid(self, klass, dev_uuid):
+ self.domains_lock.acquire()
+ try:
+ for dom in self.domains.values():
+ if dom.has_device(klass, dev_uuid):
+ return dom
+ return None
+ finally:
+ self.domains_lock.release()
+
+ def get_dev_property_by_uuid(self, klass, dev_uuid, field):
+ self.domains_lock.acquire()
+ try:
+ dom = self.get_vm_with_dev_uuid(klass, dev_uuid)
+ if not dom:
+ return None
+
+ value = dom.get_device_property(klass, devid, field)
+ return value
except ValueError, e:
pass
@@ -588,18 +591,7 @@ class XendDomain:
return (self.get_vm_by_uuid(vm_ref) != None)
def is_valid_dev(self, klass, dev_uuid):
- parts = dev_uuid.split('-%s-' % klass, 1)
- try:
- if len(parts) > 1:
- dom = self.get_vm_by_uuid(parts[0])
- if not dom:
- return False
- devid = int(parts[1])
- return dom.isDeviceValid(klass, devid)
- except ValueError, e:
- pass
-
- return False
+ return (self.get_vm_with_dev_uuid(klass, dev_uuid) != None)
def do_legacy_api_with_uuid(self, fn, vm_uuid, *args):
self.domains_lock.acquire()
diff -r c0d9f8b9c0e5 -r c88a78f8bed9 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Fri Oct 06 12:46:46 2006 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py Fri Oct 06 16:27:06 2006 +0100
@@ -1709,54 +1709,73 @@ class XendDomainInfo:
return XEN_API_ON_CRASH_BEHAVIOUR.index(self.info['on_crash'])
except ValueError, e:
return XEN_API_ON_CRASH_BEHAVIOUR.index('destroy')
-
-
- def get_device_property(self, devclass, devid, field):
- controller = self.getDeviceController(devclass)
-
- if devclass == 'vif':
- if field in ('name', 'MAC', 'type'):
- config = controller.getDeviceConfiguration(devid)
- if field == 'name':
- return config['vifname']
- if field == 'mac':
- return config['mac']
- if field == 'type':
- return config['type']
- if field == 'device':
- return 'eth%s' % devid
- if field == 'network':
- return None # TODO
- if field == 'VM':
- return self.get_uuid()
- if field == 'MTU':
- return 0 # TODO
- # TODO: network bandwidth values
- return 0.0
-
- if devclass == 'vbd':
- if field == 'VM':
- return self.get_uuid()
- if field == 'VDI':
- return '' # TODO
- if field in ('device', 'mode', 'driver'):
- config = controller.getDeviceConfiguration(devid)
- if field == 'device':
- return config['dev'] # TODO
- if field == 'mode':
- return config['mode']
- if field == 'driver':
- return config['uname'] # TODO
-
- # TODO network bandwidth values
- return 0.0
-
- raise XendError("Unrecognised dev class or property")
-
-
- def is_device_valid(self, devclass, devid):
- controller = self.getDeviceController(devclass)
- return (devid in controller.deviceIDs())
+
+ def get_dev_config_by_uuid(self, dev_class, dev_uuid):
+ """ Get's a device configuration either from XendConfig or
+ from the DevController."""
+ if self.get_power_state() not in ('Halted',):
+ dev = self.info['device'].get(dev_uuid)
+ if dev:
+ return dev[1].copy()
+ return None
+ else:
+ controller = self.getDeviceController(dev_class)
+ if not controller:
+ return None
+ all_configs = controller.getAllDeviceConfigurations()
+ if not all_configs:
+ return None
+ for _devid, _devcfg in all_configs.items():
+ if _devcfg.get('uuid') == dev_uuid:
+ devcfg = _devcfg.copy()
+ devcfg['id'] = _devid
+ return devcfg
+
+ return None
+
+ def get_dev_xenapi_config(self, dev_class, dev_uuid):
+ config = self.get_dev_config_by_uuid(dev_class, dev_uuid)
+ if not config:
+ return {}
+
+ config['VM'] = self.get_uuid()
+
+ if dev_class == 'vif':
+ if not config.has_key('name'):
+ config['name'] = config.get('vifname', '')
+ if not config.has_key('MAC'):
+ config['MAC'] = config.get('mac', '')
+ if not config.has_key('type'):
+ config['type'] = 'paravirtualised'
+ if not config.has_key('device'):
+ devid = config.get('id')
+ if devid != None:
+ config['device'] = 'eth%d' % devid
+ else:
+ config['device'] = ''
+
+ config['network'] = '' # Invalid for Xend
+ config['MTU'] = 1500 # TODO
+ config['network_read_kbs'] = 0.0
+ config['network_write_kbs'] = 0.0
+ config['IO_bandwidth_incoming_kbs'] = 0.0
+ config['IO_bandwidth_outgoing_kbs'] = 0.0
+
+ if dev_class == 'vbd':
+ config['VDI'] = '' # TODO
+ config['device'] = config.get('dev', '')
+ config['driver'] = config.get('uname', '')
+ config['IO_bandwidth_incoming_kbs'] = 0.0
+ config['IO_bandwidth_outgoing_kbs'] = 0.0
+
+ return config
+
+ def get_dev_property(self, dev_class, dev_uuid, field):
+ config = self.get_dev_xenapi_config(dev_class, dev_uuid)
+ try:
+ return config[field]
+ except KeyError:
+ raise XendError('Invalid property for device: %s' % field)
def get_vcpus_util(self):
# TODO: this returns the total accum cpu time, rather than util
@@ -1806,7 +1825,9 @@ class XendDomainInfo:
raise XendError("Device creation failed")
return dev_uuid
-
+
+ def has_device(self, dev_class, dev_uuid):
+ return (dev_uuid in self.info['%s_refs' % dev_class])
"""
def stateChar(name):
diff -r c0d9f8b9c0e5 -r c88a78f8bed9
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Fri Oct 06 12:46:46
2006 +0100
+++ b/tools/python/xen/xend/server/DevController.py Fri Oct 06 16:27:06
2006 +0100
@@ -255,6 +255,13 @@ class DevController:
raise VmError("Device %s not connected" % devid)
return {'backend': int(backdomid)}
+
+ def getAllDeviceConfigurations(self):
+ all_configs = {}
+ for devid in self.deviceIDs():
+ config_dict = self.getDeviceConfiguration(devid)
+ all_configs[devid] = config_dict
+ return all_configs
## protected:
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|