From 48bdfc8b2fe2c9a92050b0249f530df243d01244 Mon Sep 17 00:00:00 2001 From: Ghanshyam Maan Date: Mon, 23 Feb 2026 18:51:43 +0000 Subject: [PATCH] Fix the negative sleep value in graceful_shutdown() This fixes the following comment to avoid having the negative sleep value in manager graceful_shutdown() - https://review.opendev.org/c/openstack/nova/+/975586/comment/d5e3a603_0c746704/ Change-Id: I07a994bd05ac1e7f734f2a2144327bd2559c1416 Signed-off-by: Ghanshyam Maan --- nova/compute/manager.py | 2 +- nova/conductor/manager.py | 2 +- nova/scheduler/manager.py | 2 +- nova/tests/unit/compute/test_compute_mgr.py | 10 ++++++++++ nova/tests/unit/conductor/test_conductor.py | 7 +++++++ nova/tests/unit/scheduler/test_manager.py | 7 +++++++ 6 files changed, 27 insertions(+), 3 deletions(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index b20bbb8885..ae0db22166 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -1827,7 +1827,7 @@ class ComputeManager(manager.Manager): 'killed before the manager finishes waiting.', CONF.manager_shutdown_timeout, CONF.graceful_shutdown_timeout) - sleep_time = CONF.graceful_shutdown_timeout - 10 + sleep_time = max(0, CONF.graceful_shutdown_timeout - 10) else: sleep_time = CONF.manager_shutdown_timeout LOG.debug('Compute service manager is waiting for %s seconds to ' diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index 253cae84e3..5e3a90c6be 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -218,7 +218,7 @@ class ConductorManager(manager.Manager): 'killed before the manager finishes waiting.', CONF.manager_shutdown_timeout, CONF.graceful_shutdown_timeout) - sleep_time = CONF.graceful_shutdown_timeout - 10 + sleep_time = max(0, CONF.graceful_shutdown_timeout - 10) else: sleep_time = CONF.manager_shutdown_timeout LOG.debug('Conductor service manager is waiting for %s seconds to ' diff --git a/nova/scheduler/manager.py b/nova/scheduler/manager.py index 4f5aa1df3a..efff0d9e4a 100644 --- a/nova/scheduler/manager.py +++ b/nova/scheduler/manager.py @@ -172,7 +172,7 @@ class SchedulerManager(manager.Manager): 'killed before the manager finishes waiting.', CONF.manager_shutdown_timeout, CONF.graceful_shutdown_timeout) - sleep_time = CONF.graceful_shutdown_timeout - 10 + sleep_time = max(0, CONF.graceful_shutdown_timeout - 10) else: sleep_time = CONF.manager_shutdown_timeout LOG.debug('Scheduler service manager is waiting for %s seconds to ' diff --git a/nova/tests/unit/compute/test_compute_mgr.py b/nova/tests/unit/compute/test_compute_mgr.py index f06bb6ee42..3f88754c92 100644 --- a/nova/tests/unit/compute/test_compute_mgr.py +++ b/nova/tests/unit/compute/test_compute_mgr.py @@ -8005,6 +8005,16 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase, mock_sleep.assert_called_once_with(20) mock_cleanup.assert_called_once_with() + @mock.patch('time.sleep') + @mock.patch('nova.compute.manager.ComputeManager.cleanup_host') + def test_graceful_shutdown_no_negative_sleep_time( + self, mock_cleanup, mock_sleep): + # If sleep time end up with negative value, fallback to slep(0) + self.flags(manager_shutdown_timeout=50, graceful_shutdown_timeout=5) + self.compute.graceful_shutdown() + mock_sleep.assert_called_once_with(0) + mock_cleanup.assert_called_once_with() + @mock.patch('nova.objects.BlockDeviceMappingList.get_by_instance_uuid') @mock.patch('nova.compute.manager.ComputeManager._delete_instance') def test_terminate_instance_no_bdm_volume_id(self, mock_delete_instance, diff --git a/nova/tests/unit/conductor/test_conductor.py b/nova/tests/unit/conductor/test_conductor.py index 03bdfd2920..16f624ee4a 100644 --- a/nova/tests/unit/conductor/test_conductor.py +++ b/nova/tests/unit/conductor/test_conductor.py @@ -320,6 +320,13 @@ class ConductorTestCase(_BaseTestCase, test.TestCase): mock_log.warning.assert_called_once() mock_sleep.assert_called_once_with(20) + @mock.patch('time.sleep') + def test_graceful_shutdown_no_negative_sleep_time(self, mock_sleep): + # If sleep time end up with negative value, fallback to slep(0) + self.flags(manager_shutdown_timeout=50, graceful_shutdown_timeout=5) + self.conductor.graceful_shutdown() + mock_sleep.assert_called_once_with(0) + def test_provider_fw_rule_get_all(self): result = self.conductor.provider_fw_rule_get_all(self.context) self.assertEqual([], result) diff --git a/nova/tests/unit/scheduler/test_manager.py b/nova/tests/unit/scheduler/test_manager.py index e6c3446d09..fb091ca23d 100644 --- a/nova/tests/unit/scheduler/test_manager.py +++ b/nova/tests/unit/scheduler/test_manager.py @@ -1678,6 +1678,13 @@ class SchedulerManagerTestCase(test.NoDBTestCase): mock_log.warning.assert_called_once() mock_sleep.assert_called_once_with(20) + @mock.patch('time.sleep') + def test_graceful_shutdown_no_negative_sleep_time(self, mock_sleep): + # If sleep time end up with negative value, fallback to slep(0) + self.flags(manager_shutdown_timeout=50, graceful_shutdown_timeout=5) + self.manager.graceful_shutdown() + mock_sleep.assert_called_once_with(0) + @mock.patch('nova.objects.service.ServiceList.get_by_binary') @mock.patch('nova.objects.host_mapping.discover_hosts') def test_discover_hosts(self, mock_discover, mock_get_by_binary):