Skip to content

Commit 2888bc6

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "libvirt: set device address tag only if setting disk unit" into stable/stein
2 parents b3b1e6d + 7500c19 commit 2888bc6

File tree

4 files changed

+77
-10
lines changed

4 files changed

+77
-10
lines changed

nova/tests/unit/virt/libvirt/test_imagebackend.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import tempfile
2121

2222
from castellan import key_manager
23+
import ddt
2324
import fixtures
2425
import mock
2526
from oslo_concurrency import lockutils
@@ -58,6 +59,7 @@ def secretLookupByUUIDString(self, uuid):
5859
return FakeSecret()
5960

6061

62+
@ddt.ddt
6163
class _ImageTestCase(object):
6264

6365
def mock_create_image(self, image):
@@ -207,6 +209,28 @@ def test_get_disk_size(self, get_disk_size):
207209
self.assertEqual(2361393152, image.get_disk_size(image.path))
208210
get_disk_size.assert_called_once_with(image.path)
209211

212+
def _test_libvirt_info_scsi_with_unit(self, disk_unit):
213+
# The address should be set if bus is scsi and unit is set.
214+
# Otherwise, it should not be set at all.
215+
image = self.image_class(self.INSTANCE, self.NAME)
216+
disk_info = {
217+
'bus': 'scsi',
218+
'dev': '/dev/sda',
219+
'type': 'disk',
220+
}
221+
disk = image.libvirt_info(disk_info, cache_mode='none', extra_specs={},
222+
hypervisor_version=4004001,
223+
disk_unit=disk_unit)
224+
if disk_unit:
225+
self.assertEqual(0, disk.device_addr.controller)
226+
self.assertEqual(disk_unit, disk.device_addr.unit)
227+
else:
228+
self.assertIsNone(disk.device_addr)
229+
230+
@ddt.data(5, None)
231+
def test_libvirt_info_scsi_with_unit(self, disk_unit):
232+
self._test_libvirt_info_scsi_with_unit(disk_unit)
233+
210234

211235
class FlatTestCase(_ImageTestCase, test.NoDBTestCase):
212236

@@ -1279,6 +1303,7 @@ def test_get_model(self):
12791303
model)
12801304

12811305

1306+
@ddt.ddt
12821307
class RbdTestCase(_ImageTestCase, test.NoDBTestCase):
12831308
FSID = "FakeFsID"
12841309
POOL = "FakePool"
@@ -1503,6 +1528,17 @@ def get_mon_addrs():
15031528

15041529
super(RbdTestCase, self).test_libvirt_info()
15051530

1531+
@ddt.data(5, None)
1532+
@mock.patch.object(rbd_utils.RBDDriver, "get_mon_addrs")
1533+
def test_libvirt_info_scsi_with_unit(self, disk_unit, mock_mon_addrs):
1534+
def get_mon_addrs():
1535+
hosts = ["server1", "server2"]
1536+
ports = ["1899", "1920"]
1537+
return hosts, ports
1538+
mock_mon_addrs.side_effect = get_mon_addrs
1539+
1540+
super(RbdTestCase, self)._test_libvirt_info_scsi_with_unit(disk_unit)
1541+
15061542
@mock.patch.object(rbd_utils.RBDDriver, "get_mon_addrs")
15071543
def test_get_model(self, mock_mon_addrs):
15081544
pool = "FakePool"

nova/tests/unit/virt/libvirt/volume/test_volume.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# License for the specific language governing permissions and limitations
1414
# under the License.
1515

16+
import ddt
1617
import mock
1718
from oslo_utils.fixture import uuidsentinel as uuids
1819

@@ -140,6 +141,7 @@ def iscsi_connection(self, volume, location, iqn, auth=False,
140141
return ret
141142

142143

144+
@ddt.ddt
143145
class LibvirtVolumeTestCase(LibvirtISCSIVolumeBaseTestCase):
144146

145147
def _assertDiskInfoEquals(self, tree, disk_info):
@@ -383,3 +385,21 @@ def test_libvirt_volume_driver_encryption_missing_secret(self):
383385
conf = libvirt_driver.get_config(connection_info, self.disk_info)
384386
tree = conf.format_dom()
385387
self.assertIsNone(tree.find("encryption"))
388+
389+
@ddt.data(5, None)
390+
def test_libvirt_volume_driver_address_tag_scsi_unit(self, disk_unit):
391+
# The address tag should be set if bus is scsi and unit is set.
392+
# Otherwise, it should not be set at all.
393+
libvirt_driver = volume.LibvirtVolumeDriver(self.fake_host)
394+
connection_info = {'data': {'device_path': '/foo'}}
395+
disk_info = {'bus': 'scsi', 'dev': 'sda', 'type': 'disk'}
396+
if disk_unit:
397+
disk_info['unit'] = disk_unit
398+
conf = libvirt_driver.get_config(connection_info, disk_info)
399+
tree = conf.format_dom()
400+
address = tree.find('address')
401+
if disk_unit:
402+
self.assertEqual('0', address.attrib['controller'])
403+
self.assertEqual(str(disk_unit), address.attrib['unit'])
404+
else:
405+
self.assertIsNone(address)

nova/virt/libvirt/imagebackend.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,17 @@ def libvirt_info(self, disk_info, cache_mode,
180180
return info
181181

182182
def disk_scsi(self, info, disk_unit):
183-
# The driver is responsible to create the SCSI controller
184-
# at index 0.
185-
info.device_addr = vconfig.LibvirtConfigGuestDeviceAddressDrive()
186-
info.device_addr.controller = 0
183+
# NOTE(melwitt): We set the device address unit number manually in the
184+
# case of the virtio-scsi controller, in order to allow attachment of
185+
# up to 256 devices. So, we should only be setting the address tag
186+
# if we intend to set the unit number. Otherwise, we will let libvirt
187+
# handle autogeneration of the address tag.
188+
# See https://bugs.launchpad.net/nova/+bug/1792077 for details.
187189
if disk_unit is not None:
190+
# The driver is responsible to create the SCSI controller
191+
# at index 0.
192+
info.device_addr = vconfig.LibvirtConfigGuestDeviceAddressDrive()
193+
info.device_addr.controller = 0
188194
# In order to allow up to 256 disks handled by one
189195
# virtio-scsi controller, the device addr should be
190196
# specified.

nova/virt/libvirt/volume/volume.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,21 @@ def get_config(self, connection_info, disk_info):
9494
if data.get('discard', False) is True:
9595
conf.driver_discard = 'unmap'
9696

97-
if disk_info['bus'] == 'scsi':
97+
# NOTE(melwitt): We set the device address unit number manually in the
98+
# case of the virtio-scsi controller, in order to allow attachment of
99+
# up to 256 devices. So, we should only be setting the address tag
100+
# if we intend to set the unit number. Otherwise, we will let libvirt
101+
# handle autogeneration of the address tag.
102+
# See https://bugs.launchpad.net/nova/+bug/1792077 for details.
103+
if disk_info['bus'] == 'scsi' and 'unit' in disk_info:
98104
# The driver is responsible to create the SCSI controller
99105
# at index 0.
100106
conf.device_addr = vconfig.LibvirtConfigGuestDeviceAddressDrive()
101107
conf.device_addr.controller = 0
102-
if 'unit' in disk_info:
103-
# In order to allow up to 256 disks handled by one
104-
# virtio-scsi controller, the device addr should be
105-
# specified.
106-
conf.device_addr.unit = disk_info['unit']
108+
# In order to allow up to 256 disks handled by one
109+
# virtio-scsi controller, the device addr should be
110+
# specified.
111+
conf.device_addr.unit = disk_info['unit']
107112

108113
if connection_info.get('multiattach', False):
109114
# Note that driver_cache should be disabled (none) when using

0 commit comments

Comments
 (0)