virt: add get_instance_disk_info to virt driver API

The compute manager has been calling get_instance_disk_info on
virt driver implementations during block migration, despite
this method not being declared in the virt driver API. It was
implemented in libvirt and stubbed in xenapi, with different
API signatures in both.

Declare & document it as part of the virt driver API, and
split the libvirt impl into two parts to hide the libvirt
specific notion of XML config.

Partial-bug: #1333219
Change-Id: I38c811f91cce99772ff988a278c32483a219949d
This commit is contained in:
Daniel P. Berrange
2014-06-20 14:44:38 +01:00
parent e1e3518da1
commit 2bed16c893
5 changed files with 54 additions and 46 deletions

View File

@@ -5528,7 +5528,7 @@ class LibvirtConnTestCase(test.TestCase):
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
self.mox.StubOutWithMock(conn, '_destroy')
self.mox.StubOutWithMock(conn, 'get_instance_disk_info')
self.mox.StubOutWithMock(conn, '_get_instance_disk_info')
self.mox.StubOutWithMock(conn, '_get_guest_xml')
self.mox.StubOutWithMock(conn, '_create_images_and_backing')
self.mox.StubOutWithMock(conn, '_create_domain_and_network')
@@ -5550,7 +5550,7 @@ class LibvirtConnTestCase(test.TestCase):
block_device_info=block_device_info,
write_to_disk=True).AndReturn(dummyxml)
disk_info_json = '[{"virt_disk_size": 2}]'
conn.get_instance_disk_info(instance["name"], dummyxml,
conn._get_instance_disk_info(instance["name"], dummyxml,
block_device_info).AndReturn(disk_info_json)
conn._create_images_and_backing(self.context, instance,
libvirt_utils.get_instance_path(instance),
@@ -5622,7 +5622,7 @@ class LibvirtConnTestCase(test.TestCase):
return_value=(image_service_mock,
instance['image_ref']))):
conn.get_info = fake_get_info
conn.get_instance_disk_info = _check_xml_bus
conn._get_instance_disk_info = _check_xml_bus
conn._hard_reboot(self.context, instance, network_info,
block_device_info)
@@ -5888,7 +5888,7 @@ class LibvirtConnTestCase(test.TestCase):
'disk_size': '10737418240',
'over_committed_disk_size': '0'}]}
def get_info(instance_name):
def get_info(instance_name, block_device_mapping=None):
return jsonutils.dumps(fake_disks.get(instance_name))
self.stubs.Set(conn, 'get_instance_disk_info', get_info)
@@ -8449,7 +8449,7 @@ class LibvirtDriverTestCase(test.TestCase):
self.counter = 0
self.checked_shared_storage = False
def fake_get_instance_disk_info(instance, xml=None,
def fake_get_instance_disk_info(instance,
block_device_info=None):
return '[]'
@@ -8503,7 +8503,7 @@ class LibvirtDriverTestCase(test.TestCase):
'disk_size': '83886080'}]
disk_info_text = jsonutils.dumps(disk_info)
def fake_get_instance_disk_info(instance, xml=None,
def fake_get_instance_disk_info(instance,
block_device_info=None):
return disk_info_text

View File

@@ -119,7 +119,7 @@ class _FakeDriverBackendTestCase(object):
pass
self.stubs.Set(nova.virt.libvirt.driver.LibvirtDriver,
'get_instance_disk_info',
'_get_instance_disk_info',
fake_get_instance_disk_info)
self.stubs.Set(nova.virt.libvirt.driver.disk,

View File

@@ -764,6 +764,28 @@ class ComputeDriver(object):
"""
raise NotImplementedError()
def get_instance_disk_info(self, instance_name,
block_device_info=None):
"""Retrieve information about actual disk sizes of an instance.
:param instance_name:
name of a nova instance as returned by list_instances()
:param block_device_info:
Optional; Can be used to filter out devices which are
actually volumes.
:return:
json strings with below format::
"[{'path':'disk',
'type':'raw',
'virt_disk_size':'10737418240',
'backing_file':'backing_file',
'disk_size':'83886080'
'over_committed_disk_size':'10737418240'},
...]"
"""
raise NotImplementedError()
def refresh_security_group_rules(self, security_group_id):
"""This method is called after a change to security groups.

View File

@@ -2058,8 +2058,8 @@ class LibvirtDriver(driver.ComputeDriver):
write_to_disk=True)
# NOTE (rmk): Re-populate any missing backing files.
disk_info_json = self.get_instance_disk_info(instance['name'], xml,
block_device_info)
disk_info_json = self._get_instance_disk_info(instance['name'], xml,
block_device_info)
instance_dir = libvirt_utils.get_instance_path(instance)
self._create_images_and_backing(context, instance, instance_dir,
disk_info_json)
@@ -4675,42 +4675,8 @@ class LibvirtDriver(driver.ComputeDriver):
write_to_disk=True)
self._conn.defineXML(xml)
def get_instance_disk_info(self, instance_name, xml=None,
block_device_info=None):
"""Retrieve information about actual disk sizes of an instance.
:param instance_name:
name of a nova instance as returned by list_instances()
:param xml:
Optional; Domain XML of given libvirt instance.
If omitted, this method attempts to extract it from the
pre-existing definition.
:param block_device_info:
Optional; Can be used to filter out devices which are
actually volumes.
:return:
json strings with below format::
"[{'path':'disk', 'type':'raw',
'virt_disk_size':'10737418240',
'backing_file':'backing_file',
'disk_size':'83886080'},...]"
"""
if xml is None:
try:
virt_dom = self._lookup_by_name(instance_name)
xml = virt_dom.XMLDesc(0)
except libvirt.libvirtError as ex:
error_code = ex.get_error_code()
LOG.warn(_LW('Error from libvirt while getting description of '
'%(instance_name)s: [Error Code %(error_code)s] '
'%(ex)s'),
{'instance_name': instance_name,
'error_code': error_code,
'ex': ex})
raise exception.InstanceNotFound(instance_id=instance_name)
def _get_instance_disk_info(self, instance_name, xml,
block_device_info=None):
block_device_mapping = driver.block_device_info_get_mapping(
block_device_info)
@@ -4767,6 +4733,25 @@ class LibvirtDriver(driver.ComputeDriver):
'over_committed_disk_size': over_commit_size})
return jsonutils.dumps(disk_info)
def get_instance_disk_info(self, instance_name,
block_device_info=None):
try:
dom = self._lookup_by_name(instance_name)
xml = dom.XMLDesc(0)
except libvirt.libvirtError as ex:
error_code = ex.get_error_code()
msg = (_('Error from libvirt while getting description of '
'%(instance_name)s: [Error Code %(error_code)s] '
'%(ex)s') %
{'instance_name': instance_name,
'error_code': error_code,
'ex': ex})
LOG.warn(msg)
raise exception.InstanceNotFound(instance_id=instance_name)
return self._get_instance_disk_info(instance_name, xml,
block_device_info)
def _get_disk_over_committed_size_total(self):
"""Return total over committed disk size for all instances."""
# Disk size that all instance uses : virtual_size - disk_size

View File

@@ -504,7 +504,8 @@ class XenAPIDriver(driver.ComputeDriver):
return self._vmops.check_can_live_migrate_source(ctxt, instance_ref,
dest_check_data)
def get_instance_disk_info(self, instance_name):
def get_instance_disk_info(self, instance_name,
block_device_info=None):
"""Used by libvirt for live migration. We rely on xenapi
checks to do this for us.
"""