From fb4abd53d35a6be76a02962221d8cb8e24960b5e Mon Sep 17 00:00:00 2001 From: Prabhat Ranjan Date: Thu, 29 Jun 2017 14:37:05 +0530 Subject: [PATCH] PowerOn of a partition in paused state not working When we do inband shutdown of partition using command 'shutdown -P now' Then partition is not going to 'stopped' state. It is going to 'PAUSED' state. In DPM there is no such implementation so that we can start partition from PAUSED state. So workaround is we need to stop the partition then start. This patch also includes the cases when partition is in "starting/stopping" state. Closes-Bug: #1678002 Change-Id: I1898b85a8441c3175db0a6de6d620bca19af69ec Signed-off-by: Prabhat Ranjan --- nova_dpm/tests/unit/virt/dpm/test_vm.py | 22 ++++++++++++++ nova_dpm/virt/dpm/vm.py | 39 +++++++++++++++++++++---- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/nova_dpm/tests/unit/virt/dpm/test_vm.py b/nova_dpm/tests/unit/virt/dpm/test_vm.py index 1209e42..58bf0c8 100755 --- a/nova_dpm/tests/unit/virt/dpm/test_vm.py +++ b/nova_dpm/tests/unit/virt/dpm/test_vm.py @@ -45,6 +45,14 @@ def fake_session(): 'maximum-memory': 512, 'ifl-processors': 3 }) + cpc1.partitions.add({ + 'name': 'OpenStack-foo-cccccccc-cccc-cccc-cccc-cccccccccccc', + 'description': 'OpenStack CPCSubset=foo', + 'initial-memory': 1, + 'status': 'paused', + 'maximum-memory': 512, + 'ifl-processors': 3 + }) cpc1.partitions.add({ 'name': 'OpenStack-foo-6511ee0f-0d64-4392-aaaa-bbbbbbbbbbbb', 'description': 'OpenStack CPCSubset=foo', @@ -281,6 +289,14 @@ class VmPartitionInstanceTestCase(TestCase): 'object-uri') + '/hbas/1', self.partition_inst.get_boot_hba_uri()) + def test_power_on_vm_when_paused(self): + instance = instance_obj.Instance() + instance.uuid = 'cccccccc-cccc-cccc-cccc-cccccccccccc' + partition_inst = vm.PartitionInstance(instance, self.cpc) + partition_inst.power_on_vm() + self.assertEqual( + 'active', partition_inst.get_partition().get_property('status')) + def test_destroy_stopped_partition(self): instance = instance_obj.Instance() instance.save = mock.Mock() @@ -338,6 +354,12 @@ class PartitionInstanceInfoTestCase(TestCase): def test_state(self): self.assertEqual(power_state.RUNNING, self.instance_partition.state) + def test_paused_partition_state(self): + instance = instance_obj.Instance() + instance.uuid = 'cccccccc-cccc-cccc-cccc-cccccccccccc' + instance_partition = vm.PartitionInstanceInfo(instance, self.cpc) + self.assertEqual(power_state.SHUTDOWN, instance_partition.state) + def test_mem(self): self.assertEqual(1, self.instance_partition.mem) diff --git a/nova_dpm/virt/dpm/vm.py b/nova_dpm/virt/dpm/vm.py index 6f1b36a..625c980 100644 --- a/nova_dpm/virt/dpm/vm.py +++ b/nova_dpm/virt/dpm/vm.py @@ -38,12 +38,22 @@ CONF = conf.CONF OPENSTACK_PREFIX = 'OpenStack' CPCSUBSET_PREFIX = 'CPCSubset=' +STARTED_STATUSES = ( + utils.PartitionState.RUNNING, + utils.PartitionState.DEGRADED, + utils.PartitionState.RESERVATION_ERROR) +STOPPED_STATUSES = ( + utils.PartitionState.STOPPED, + utils.PartitionState.TERMINATED, + utils.PartitionState.PAUSED) + DPM_TO_NOVA_STATE = { utils.PartitionState.RUNNING: power_state.RUNNING, utils.PartitionState.STOPPED: power_state.SHUTDOWN, utils.PartitionState.UNKNOWN: power_state.NOSTATE, - utils.PartitionState.PAUSED: power_state.PAUSED, + # operation to get out of the "paused" status is "stop" + utils.PartitionState.PAUSED: power_state.SHUTDOWN, utils.PartitionState.STARTING: power_state.PAUSED } @@ -325,10 +335,29 @@ class PartitionInstance(object): def power_on_vm(self): LOG.debug('Partition power on triggered') - self.partition.start(True) - # TODO(preethipy): The below method to be removed once the bug - # on DPM(701894) is fixed to return correct status on API return - self._loop_status_update(5, 'Active') + + self._ensure_status_transitioned() + + if self.partition.get_property( + 'status') == utils.PartitionState.PAUSED: + self.partition.stop(True) + self.partition.wait_for_status( + status=utils.PartitionState.STOPPED, status_timeout=60) + + if self.partition.get_property('status') not in STARTED_STATUSES: + self.partition.start(True) + self.partition.wait_for_status( + status=STARTED_STATUSES, status_timeout=60) + + def _ensure_status_transitioned(self): + partition_state = self.partition.get_property('status') + + if partition_state == utils.PartitionState.STARTING: + self.partition.wait_for_status( + status=STARTED_STATUSES, status_timeout=60) + elif partition_state == utils.PartitionState.SHUTTING_DOWN: + self.partition.wait_for_status( + status=STOPPED_STATUSES, status_timeout=60) def power_off_vm(self): LOG.debug('Partition power off triggered')