mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
[XEND] Proper support for devices with UUID. Removing old workaround
with augmented VM UUIDs with devids. Signed-off-by: Alastair Tse <atse@xensource.com>
This commit is contained in:
1 parent
e9fce87749
commit
943f4e6d26
5 files changed
+125
-77
No files matched your search
@@ -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()
|
||||
|
||||
@@ -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" %
|
||||
|
||||
@@ -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)
|
||||
def get_vm_with_dev_uuid(self, klass, dev_uuid):
|
||||
self.domains_lock.acquire()
|
||||
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
|
||||
for dom in self.domains.values():
|
||||
if dom.has_device(klass, dev_uuid):
|
||||
return dom
|
||||
return None
|
||||
finally:
|
||||
self.domains_lock.release()
|
||||
|
||||
devid = int(parts[1])
|
||||
value = dom.get_device_property(klass, devid, field)
|
||||
return value
|
||||
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()
|
||||
|
||||
@@ -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)
|
||||
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
|
||||
|
||||
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
|
||||
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 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
|
||||
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
|
||||
|
||||
# TODO network bandwidth values
|
||||
return 0.0
|
||||
return config
|
||||
|
||||
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_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):
|
||||
|
||||
@@ -256,6 +256,13 @@ class DevController:
|
||||
|
||||
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:
|
||||
|
||||
def getDeviceDetails(self, config):
|
||||
|
||||