compute: Take an instance.uuid lock when rebooting

Previously simultaneous requests to reboot and delete an instance could
race as only the latter took a lock against the uuid of the instance.

With the Libvirt driver this race could potentially result in attempts
being made to reconnect previously disconnected volumes on the host.
Depending on the volume backend being used this could then result in
stale block devices point to unmapped volumes being left on the host
that in turn could cause failures later on when connecting newly mapped
volumes.

This change avoids this race by ensuring any request to reboot an
instance takes an instance.uuid lock within the compute manager,
serialising requests to reboot and then delete the instance.

Closes-Bug: #1838392
Change-Id: Ieb59de10c63bb067f92ec054535766cdd722dae2
This commit is contained in:
Lee Yarwood 2019-07-29 16:25:45 +01:00
parent 9a2f45173a
commit 9ad54f3dac
1 changed files with 9 additions and 0 deletions

View File

@ -3653,6 +3653,15 @@ class ComputeManager(manager.Manager):
@wrap_instance_fault
def reboot_instance(self, context, instance, block_device_info,
reboot_type):
@utils.synchronized(instance.uuid)
def do_reboot_instance(context, instance, block_device_info,
reboot_type):
self._reboot_instance(context, instance, block_device_info,
reboot_type)
do_reboot_instance(context, instance, block_device_info, reboot_type)
def _reboot_instance(self, context, instance, block_device_info,
reboot_type):
"""Reboot an instance on this host."""
# acknowledge the request made it to the manager
if reboot_type == "SOFT":