Merge "Support setting block size for block devices"
This commit is contained in:
commit
3c83737896
@ -1863,6 +1863,39 @@ class LibvirtConnTestCase(test.TestCase):
|
||||
{"name": "fake-instance"},
|
||||
"/dev/sda")
|
||||
|
||||
def test_attach_blockio_invalid_hypervisor(self):
|
||||
self.flags(libvirt_type='fake_type')
|
||||
self.create_fake_libvirt_mock()
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
self.mox.ReplayAll()
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
self.assertRaises(exception.InvalidHypervisorType,
|
||||
conn.attach_volume,
|
||||
{"driver_volume_type": "fake",
|
||||
"data": {"logical_block_size": "4096",
|
||||
"physical_block_size": "4096"}
|
||||
},
|
||||
{"name": "fake-instance"},
|
||||
"/dev/sda")
|
||||
|
||||
def test_attach_blockio_invalid_version(self):
|
||||
def get_lib_version_stub():
|
||||
return (0 * 1000 * 1000) + (9 * 1000) + 8
|
||||
self.flags(libvirt_type='qemu')
|
||||
self.create_fake_libvirt_mock()
|
||||
libvirt_driver.LibvirtDriver._conn.lookupByName = self.fake_lookup
|
||||
self.mox.ReplayAll()
|
||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
|
||||
self.stubs.Set(self.conn, "getLibVersion", get_lib_version_stub)
|
||||
self.assertRaises(exception.Invalid,
|
||||
conn.attach_volume,
|
||||
{"driver_volume_type": "fake",
|
||||
"data": {"logical_block_size": "4096",
|
||||
"physical_block_size": "4096"}
|
||||
},
|
||||
{"name": "fake-instance"},
|
||||
"/dev/sda")
|
||||
|
||||
def test_multi_nic(self):
|
||||
instance_data = dict(self.test_instance)
|
||||
network_info = _fake_network_info(self.stubs, 2)
|
||||
|
@ -546,6 +546,23 @@ class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest):
|
||||
</iotune>
|
||||
</disk>""")
|
||||
|
||||
def test_config_blockio(self):
|
||||
obj = config.LibvirtConfigGuestDisk()
|
||||
obj.source_type = "file"
|
||||
obj.source_path = "/tmp/hello"
|
||||
obj.target_dev = "/dev/hda"
|
||||
obj.target_bus = "ide"
|
||||
obj.logical_block_size = "4096"
|
||||
obj.physical_block_size = "4096"
|
||||
|
||||
xml = obj.to_xml()
|
||||
self.assertXmlEqual("""
|
||||
<disk type="file" device="disk">
|
||||
<source file="/tmp/hello"/>
|
||||
<target bus="ide" dev="/dev/hda"/>
|
||||
<blockio logical_block_size="4096" physical_block_size="4096"/>
|
||||
</disk>""", xml)
|
||||
|
||||
|
||||
class LibvirtConfigGuestFilesysTest(LibvirtConfigBaseTest):
|
||||
|
||||
|
@ -97,8 +97,31 @@ class LibvirtVolumeTestCase(test.TestCase):
|
||||
}
|
||||
conf = libvirt_driver.connect_volume(connection_info, self.disk_info)
|
||||
tree = conf.format_dom()
|
||||
self.assertEqual(tree.get('type'), 'block')
|
||||
self.assertEqual(tree.find('./serial').text, 'fake_serial')
|
||||
self.assertEqual('block', tree.get('type'))
|
||||
self.assertEqual('fake_serial', tree.find('./serial').text)
|
||||
self.assertEqual(None, tree.find('./blockio'))
|
||||
|
||||
def test_libvirt_volume_driver_blockio(self):
|
||||
libvirt_driver = volume.LibvirtVolumeDriver(self.fake_conn)
|
||||
connection_info = {
|
||||
'driver_volume_type': 'fake',
|
||||
'data': {
|
||||
'device_path': '/foo',
|
||||
'logical_block_size': '4096',
|
||||
'physical_block_size': '4096',
|
||||
},
|
||||
'serial': 'fake_serial',
|
||||
}
|
||||
disk_info = {
|
||||
"bus": "virtio",
|
||||
"dev": "vde",
|
||||
"type": "disk",
|
||||
}
|
||||
conf = libvirt_driver.connect_volume(connection_info, disk_info)
|
||||
tree = conf.format_dom()
|
||||
blockio = tree.find('./blockio')
|
||||
self.assertEqual('4096', blockio.get('logical_block_size'))
|
||||
self.assertEqual('4096', blockio.get('physical_block_size'))
|
||||
|
||||
def iscsi_connection(self, volume, location, iqn):
|
||||
return {
|
||||
|
@ -476,6 +476,8 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
|
||||
self.disk_write_iops_sec = None
|
||||
self.disk_total_bytes_sec = None
|
||||
self.disk_total_iops_sec = None
|
||||
self.logical_block_size = None
|
||||
self.physical_block_size = None
|
||||
|
||||
def format_dom(self):
|
||||
dev = super(LibvirtConfigGuestDisk, self).format_dom()
|
||||
@ -556,6 +558,20 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
|
||||
|
||||
if len(iotune) > 0:
|
||||
dev.append(iotune)
|
||||
|
||||
# Block size tuning
|
||||
if (self.logical_block_size is not None or
|
||||
self.physical_block_size is not None):
|
||||
|
||||
blockio = etree.Element("blockio")
|
||||
if self.logical_block_size is not None:
|
||||
blockio.set('logical_block_size', self.logical_block_size)
|
||||
|
||||
if self.physical_block_size is not None:
|
||||
blockio.set('physical_block_size', self.physical_block_size)
|
||||
|
||||
dev.append(blockio)
|
||||
|
||||
return dev
|
||||
|
||||
|
||||
|
@ -291,6 +291,8 @@ MIN_LIBVIRT_CLOSE_CALLBACK_VERSION = (1, 0, 1)
|
||||
REQ_HYPERVISOR_LIVESNAPSHOT = "QEMU"
|
||||
MIN_LIBVIRT_LIVESNAPSHOT_VERSION = (1, 0, 0)
|
||||
MIN_QEMU_LIVESNAPSHOT_VERSION = (1, 3, 0)
|
||||
# block size tuning requirements
|
||||
MIN_LIBVIRT_BLOCKIO_VERSION = (0, 10, 2)
|
||||
|
||||
|
||||
def libvirt_error_handler(context, err):
|
||||
@ -1007,6 +1009,27 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
disk_dev),
|
||||
'type': 'disk',
|
||||
}
|
||||
|
||||
# Note(cfb): If the volume has a custom block size, check that
|
||||
# that we are using QEMU/KVM and libvirt >= 0.10.2. The
|
||||
# prescence of a block size is considered mandatory by
|
||||
# cinder so we fail if we can't honor the request.
|
||||
data = {}
|
||||
if ('data' in connection_info):
|
||||
data = connection_info['data']
|
||||
if ('logical_block_size' in data or 'physical_block_size' in data):
|
||||
if CONF.libvirt_type != "kvm" and CONF.libvirt_type != "qemu":
|
||||
msg = _("Volume sets block size, but the current "
|
||||
"libvirt hypervisor '%s' does not support custom "
|
||||
"block size") % CONF.libvirt_type
|
||||
raise exception.InvalidHypervisorType(msg)
|
||||
|
||||
if not self.has_min_version(MIN_LIBVIRT_BLOCKIO_VERSION):
|
||||
ver = ".".join([str(x) for x in MIN_LIBVIRT_BLOCKIO_VERSION])
|
||||
msg = _("Volume sets block size, but libvirt '%s' or later is "
|
||||
"required.") % ver
|
||||
raise exception.Invalid(msg)
|
||||
|
||||
conf = self.volume_driver_method('connect_volume',
|
||||
connection_info,
|
||||
disk_info)
|
||||
|
@ -99,6 +99,15 @@ class LibvirtBaseVolumeDriver(object):
|
||||
conf.target_dev = disk_info['dev']
|
||||
conf.target_bus = disk_info['bus']
|
||||
conf.serial = connection_info.get('serial')
|
||||
|
||||
# Support for block size tuning
|
||||
data = {}
|
||||
if 'data' in connection_info:
|
||||
data = connection_info['data']
|
||||
if 'logical_block_size' in data:
|
||||
conf.logical_block_size = data['logical_block_size']
|
||||
if 'physical_block_size' in data:
|
||||
conf.physical_block_size = data['physical_block_size']
|
||||
return conf
|
||||
|
||||
def disconnect_volume(self, connection_info, disk_dev):
|
||||
|
Loading…
Reference in New Issue
Block a user