From 2402055b955656c7fffa66018c7b8cfcc1596b1b Mon Sep 17 00:00:00 2001 From: Ante Karamatić Date: Mon, 20 May 2013 07:21:31 +0200 Subject: Check the instance ID before creating it At least with libvirt 1.x instance goes into shutdown state before its ID is changed. This means that there's a race condition during reboot where nova might try to create an instance that's already defined. By checking if the ID of the new and old instance is the same, we avoid that situation and reiterate on the loop. The tests for this are added in I6215f80bd15820dac80151e7063916dbbc21d761 Change-Id: I493b828f0c6848fbadc591be2f47fd1b12fd3a51 Fixes: bug 1181924 --- nova/virt/libvirt/driver.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'nova') diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 6cfa2c7c7..ccde62b90 100755 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -1378,19 +1378,22 @@ class LibvirtDriver(driver.ComputeDriver): state = LIBVIRT_POWER_STATE[state] new_domid = dom.ID() - if state in [power_state.SHUTDOWN, - power_state.CRASHED]: - LOG.info(_("Instance shutdown successfully."), - instance=instance) - self._create_domain(domain=dom) - timer = loopingcall.FixedIntervalLoopingCall( - self._wait_for_running, instance) - timer.start(interval=0.5).wait() - return True - elif old_domid != new_domid: - LOG.info(_("Instance may have been rebooted during soft " - "reboot, so return now."), instance=instance) - return True + # NOTE(ivoks): By checking domain IDs, we make sure we are + # not recreating domain that's already running. + if old_domid != new_domid: + if state in [power_state.SHUTDOWN, + power_state.CRASHED]: + LOG.info(_("Instance shutdown successfully."), + instance=instance) + self._create_domain(domain=dom) + timer = loopingcall.FixedIntervalLoopingCall( + self._wait_for_running, instance) + timer.start(interval=0.5).wait() + return True + else: + LOG.info(_("Instance may have been rebooted during soft " + "reboot, so return now."), instance=instance) + return True greenthread.sleep(1) return False -- cgit