From a6bd227ead49222a6a0a16f0dc2ba25fcec401bc Mon Sep 17 00:00:00 2001 From: nafei yang Date: Thu, 9 Mar 2017 16:11:33 +0800 Subject: [PATCH] Update root_disk_units with CYL or BLK units Now the root_disk_units just has disk size in it. It doesn't have units. So if customer specify a dismatch disk type, the driver will not detect it until the create disk prompt the space is not enough. This patch add units to root_disk_units, so it can give customer clearly advise if error happens. Change-Id: I1a31aa4bf77b774092fd04cc7174599252757538 --- nova/tests/unit/virt/zvm/test_zvm.py | 20 ++++++++++++++------ nova/virt/zvm/driver.py | 23 ++++++++++++++++++++++- nova/virt/zvm/imageop.py | 8 +++++--- nova/virt/zvm/instance.py | 10 ++++++++-- 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/nova/tests/unit/virt/zvm/test_zvm.py b/nova/tests/unit/virt/zvm/test_zvm.py index 6a73846..3d4eced 100644 --- a/nova/tests/unit/virt/zvm/test_zvm.py +++ b/nova/tests/unit/virt/zvm/test_zvm.py @@ -431,7 +431,7 @@ class ZVMDriverTestCases(ZVMTestCase): 'os_name': 'Linux', 'os_version': 'rhel6.2', 'provisioning_method': 'netboot', - 'root_disk_units': 578181045, + 'root_disk_units': '578181045:BLK', }, 'size': 578181045, 'status': 'active', @@ -533,6 +533,7 @@ class ZVMDriverTestCases(ZVMTestCase): self._fake_fun()) self.stubs.Set(self.driver._zvm_images, 'image_exist_xcat', self._fake_fun(False)) + self.stubs.Set(self.driver, '_import_image_to_nova', self._fake_fun()) self.stubs.Set(self.driver, '_import_image_to_xcat', self._fake_fun()) self.stubs.Set(instance.ZVMInstance, 'create_userid', self._fake_fun()) self.stubs.Set(instance.ZVMInstance, 'update_node_info', @@ -1858,7 +1859,8 @@ class ZVMInstanceTestCases(ZVMTestCase): 'properties': {'os_version': 'fake', 'architecture': 'fake', 'provisioning_method': 'fake', - 'root_disk_units': '3'}} + 'root_disk_units': '3338:CYL'}} + self.flags(zvm_diskpool_type='ECKD') self._instance._instance['ephemeral_gb'] = 20 self._instance._instance['root_gb'] = 0 cu_info = ['os000001: Defining OS000001 in directory... Done\n' @@ -1892,7 +1894,8 @@ class ZVMInstanceTestCases(ZVMTestCase): 'properties': {'os_version': 'fake', 'architecture': 'fake', 'provisioning_method': 'fake', - 'root_disk_units': '3338'}} + 'root_disk_units': '3338:CYL'}} + self.flags(zvm_diskpool_type='ECKD') self.mox.StubOutWithMock(zvmutils, 'xcat_request') self.mox.StubOutWithMock(self._instance, 'add_mdisk') @@ -1929,7 +1932,7 @@ class ZVMInstanceTestCases(ZVMTestCase): 'properties': {'os_version': 'fake', 'architecture': 'fake', 'provisioning_method': 'fake', - 'root_disk_units': '3'}} + 'root_disk_units': '3:CYL'}} self.mox.StubOutWithMock(zvmutils, 'xcat_request') self.mox.StubOutWithMock(self._instance, 'add_mdisk') self.mox.StubOutWithMock(self._instance, '_set_ipl') @@ -4296,8 +4299,13 @@ class ZVMImageOPTestCases(ZVMTestCase): @mock.patch('nova.utils.execute') def test_get_root_disk_units(self, mk_exec): - mk_exec.return_value = (''.join(['CKD', '1' * 160]), None) - self.assertEqual(111111111111, + # mk_exec.return_value = (''.join(['CKD', '1' * 160]), None) + mk_exec.return_value = (('00000000 78 43 41 54 20 43 4b 44 20 44 69' + ' 73 6b 20 49 6d |xCAT CKD Disk Im| 00000010 61 67 65 3a 20 20 20 20' + ' 20 20 20 20 33 33 33 38 |age: 3338| 00000020 20 43 59 4c' + ' 20 48 4c 65 6e 3a 20 30 30 35 35 20 | CYL HLen: 0055 | 00000030'), + None) + self.assertEqual('3338:CYL', self.imageop.get_root_disk_units('/fake')) @mock.patch('nova.utils.execute') diff --git a/nova/virt/zvm/driver.py b/nova/virt/zvm/driver.py index 1f6144a..10b9a33 100644 --- a/nova/virt/zvm/driver.py +++ b/nova/virt/zvm/driver.py @@ -321,8 +321,16 @@ class ZVMDriver(driver.ComputeDriver): if not boot_from_volume: tmp_file_fn = None bundle_file_path = None + with self._imageop_semaphore: - if 'root_disk_units' not in image_meta['properties']: + root_disk_units = image_meta['properties'].get( + 'root_disk_units', '') + # Currently, disk unit values have the form number:units, + # for example: '3338:CYL'. Images captured using older + # versions of the driver may lack the colon delimiter and + # units. If the unit-less form is found, convert it to the + # new form by adding the units. + if ':' not in root_disk_units: (tmp_file_fn, image_file_path, bundle_file_path) = self._import_image_to_nova( context, @@ -330,6 +338,19 @@ class ZVMDriver(driver.ComputeDriver): image_meta = self._zvm_images.\ set_image_root_disk_units( context, image_meta, image_file_path) + root_disk_units = image_meta['properties'][ + 'root_disk_units'] + disk_units = root_disk_units.split(":")[1] + if ((disk_units == "CYL" and CONF.zvm_diskpool_type == "FBA") + or (disk_units == "BLK" and + CONF.zvm_diskpool_type == "ECKD")): + msg = (_("The image's disk size units is: %(diskunits)s," + " it doesn't match the specified disk type" + " %(disktype)s in nova.conf."), + {'diskunits': disk_units, + 'disktype': CONF.zvm_diskpool_type}) + raise exception.ZVMImageError(msg=msg) + image_in_xcat = self._zvm_images.image_exist_xcat( instance['image_ref']) if not image_in_xcat: diff --git a/nova/virt/zvm/imageop.py b/nova/virt/zvm/imageop.py index 92fe461..a6d4b51 100644 --- a/nova/virt/zvm/imageop.py +++ b/nova/virt/zvm/imageop.py @@ -778,9 +778,11 @@ class ZVMImages(object): LOG.debug("hexdump result is %s", output) try: - root_disk_units = int(output[144:156]) + root_disk_size = int(output[144:156]) + disk_units = output[220:223] + root_disk_units = ':'.join([str(root_disk_size), disk_units]) except ValueError: - msg = (_("Image file at %s is missing imbeded disk size " + msg = (_("Image file at %s is missing built-in disk size " "metadata, it was probably not captured with xCAT") % image_file_path) raise exception.ZVMImageError(msg=msg) @@ -802,7 +804,7 @@ class ZVMImages(object): (glance_image_service, image_id) = glance.get_remote_image_service( context, image_meta['id']) new_image_meta = glance_image_service.show(context, image_id) - new_image_meta['properties']['root_disk_units'] = str(root_disk_units) + new_image_meta['properties']['root_disk_units'] = root_disk_units try: glance_image_service.update(context, image_id, diff --git a/nova/virt/zvm/instance.py b/nova/virt/zvm/instance.py index 6364ae9..2bda364 100644 --- a/nova/virt/zvm/instance.py +++ b/nova/virt/zvm/instance.py @@ -330,14 +330,20 @@ class ZVMInstance(object): url = self._xcat_url.mkvm('/' + self._name, self._instance.uuid, context) + # Note: driver.py:spawn() has already checked that the root disk units + # and the type of disks in the pool are compatible. try: zvmutils.xcat_request("POST", url, body) if not boot_from_volume: size = '%ig' % self._instance['root_gb'] - # use a flavor the disk size is 0 + # If the flavor specifies 0 for the root disk size, use the + # size in the image's metadata if size == '0g': - size = image_meta['properties']['root_disk_units'] + root_disk_units = image_meta['properties'][ + 'root_disk_units'] + size = root_disk_units.split(":")[0] + # Add root disk and set ipl self.add_mdisk(CONF.zvm_diskpool, CONF.zvm_user_root_vdev,