Skip to content

Commit 2a0cc70

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Limit the number of concurrent snapshots"
2 parents 8e2170d + 6bb0c4f commit 2a0cc70

File tree

4 files changed

+68
-2
lines changed

4 files changed

+68
-2
lines changed

nova/compute/manager.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,11 @@ def __init__(self, compute_driver=None, *args, **kwargs):
542542
CONF.max_concurrent_builds)
543543
else:
544544
self._build_semaphore = compute_utils.UnlimitedSemaphore()
545+
if CONF.max_concurrent_snapshots > 0:
546+
self._snapshot_semaphore = eventlet.semaphore.Semaphore(
547+
CONF.max_concurrent_snapshots)
548+
else:
549+
self._snapshot_semaphore = compute_utils.UnlimitedSemaphore()
545550
if CONF.max_concurrent_live_migrations > 0:
546551
self._live_migration_executor = futurist.GreenThreadPoolExecutor(
547552
max_workers=CONF.max_concurrent_live_migrations)
@@ -3819,8 +3824,9 @@ def snapshot_instance(self, context, image_id, instance):
38193824
instance=instance)
38203825
return
38213826

3822-
self._snapshot_instance(context, image_id, instance,
3823-
task_states.IMAGE_SNAPSHOT)
3827+
with self._snapshot_semaphore:
3828+
self._snapshot_instance(context, image_id, instance,
3829+
task_states.IMAGE_SNAPSHOT)
38243830

38253831
def _snapshot_instance(self, context, image_id, instance,
38263832
expected_task_state):

nova/conf/compute.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,20 @@
661661
662662
* 0 : treated as unlimited.
663663
* Any positive integer representing maximum concurrent builds.
664+
"""),
665+
cfg.IntOpt('max_concurrent_snapshots',
666+
default=5,
667+
min=0,
668+
help="""
669+
Maximum number of instance snapshot operations to run concurrently.
670+
This limit is enforced to prevent snapshots overwhelming the
671+
host/network/storage and causing failure. This value can be set per
672+
compute node.
673+
674+
Possible Values:
675+
676+
* 0 : treated as unlimited.
677+
* Any positive integer representing maximum concurrent snapshots.
664678
"""),
665679
cfg.IntOpt('max_concurrent_live_migrations',
666680
default=1,

nova/tests/unit/compute/test_compute_mgr.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,40 @@ def test_max_concurrent_builds_semaphore_unlimited(self):
748748
self.assertIsInstance(compute._build_semaphore,
749749
compute_utils.UnlimitedSemaphore)
750750

751+
@mock.patch('nova.objects.Instance.save')
752+
@mock.patch('nova.compute.manager.ComputeManager.'
753+
'_snapshot_instance')
754+
def _test_max_concurrent_snapshots(self, mock_si, mock_inst_save):
755+
756+
with mock.patch.object(self.compute,
757+
'_snapshot_semaphore') as mock_sem:
758+
instance = objects.Instance(uuid=uuidutils.generate_uuid())
759+
for i in (1, 2, 3):
760+
self.compute.snapshot_instance(self.context,
761+
mock.sentinel.image,
762+
instance)
763+
self.assertEqual(3, mock_sem.__enter__.call_count)
764+
765+
def test_max_concurrent_snapshots_limited(self):
766+
self.flags(max_concurrent_snapshots=2)
767+
self._test_max_concurrent_snapshots()
768+
769+
def test_max_concurrent_snapshots_unlimited(self):
770+
self.flags(max_concurrent_snapshots=0)
771+
self._test_max_concurrent_snapshots()
772+
773+
def test_max_concurrent_snapshots_semaphore_limited(self):
774+
self.flags(max_concurrent_snapshots=123)
775+
self.assertEqual(123,
776+
manager.ComputeManager()._snapshot_semaphore.balance)
777+
778+
def test_max_concurrent_snapshots_semaphore_unlimited(self):
779+
self.flags(max_concurrent_snapshots=0)
780+
compute = manager.ComputeManager()
781+
self.assertEqual(0, compute._snapshot_semaphore.balance)
782+
self.assertIsInstance(compute._snapshot_semaphore,
783+
compute_utils.UnlimitedSemaphore)
784+
751785
def test_nil_out_inst_obj_host_and_node_sets_nil(self):
752786
instance = fake_instance.fake_instance_obj(self.context,
753787
uuid=uuids.instance,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
features:
3+
- |
4+
A new configuration option, ``[DEFAULT]/max_concurrent_snapshots``,
5+
has been added. This allow operator to configure maximum concurrent
6+
snapshots on a compute host and prevent resource overuse related
7+
to snapshot.
8+
upgrade:
9+
- |
10+
Previously, the number of concurrent snapshots was unlimited, now it is
11+
limited via ``[DEFAULT]/max_concurrent_snapshots``, which currently
12+
defaults to 5.

0 commit comments

Comments
 (0)