summaryrefslogtreecommitdiff
path: root/nova/virt/disk/mount/api.py
diff options
context:
space:
mode:
authorAlexis Lee <alexisl@hp.com>2015-08-21 13:58:06 +0100
committerAlexis Lee <lxsli@hpe.com>2016-03-16 10:34:52 +0000
commit2c1b19761b3d960055ced11558dda22d022d77f4 (patch)
tree1228b4f02f82ae30e94e597d15eb75493c5c703a /nova/virt/disk/mount/api.py
parent4c18867424f09332cf5f7f5678e1f3a984b03618 (diff)
Wait for device to be mapped
There's a race condition when trying to perform file injection without libguestfs, which causes a fallback to nbd device. Although the kpartx command succeeds, it does so after the code has tested for success, so Nova thinks it failed. Retry a few times to avoid this. Co-Authored-By: Paul Carlton <paul.carlton2@hp.com> Change-Id: Ie5c186562475cd56c55520ad7123f47a0130b2a4 Closes-Bug: #1428639 Closes-Bug: #1484586
Notes
Notes (review): Code-Review+1: Andrea Rosa <andrea.rosa@hpe.com> Verified+1: DB Datasets CI <turbo-hipster@lists.rcbops.com> Verified+1: Citrix XenServer CI Verified+1: XenProject CI <openstack-ci@xenproject.org> Verified+1: VMware NSX CI Code-Review+1: Gleb Stepanov <gstepanov@mirantis.com> Code-Review+2: Michael Still <mikal@stillhq.com> Code-Review+2: Sean Dague <sean@dague.net> Workflow+1: Sean Dague <sean@dague.net> Verified+2: Jenkins Submitted-by: Jenkins Submitted-at: Tue, 26 Apr 2016 00:49:49 +0000 Reviewed-on: https://review.openstack.org/215613 Project: openstack/nova Branch: refs/heads/master
Diffstat (limited to 'nova/virt/disk/mount/api.py')
-rw-r--r--nova/virt/disk/mount/api.py20
1 files changed, 16 insertions, 4 deletions
diff --git a/nova/virt/disk/mount/api.py b/nova/virt/disk/mount/api.py
index 328e27d..0a85c06 100644
--- a/nova/virt/disk/mount/api.py
+++ b/nova/virt/disk/mount/api.py
@@ -17,6 +17,7 @@ import os
17import time 17import time
18 18
19from oslo_log import log as logging 19from oslo_log import log as logging
20from oslo_service import loopingcall
20from oslo_utils import importutils 21from oslo_utils import importutils
21 22
22from nova import exception 23from nova import exception
@@ -27,6 +28,8 @@ from nova.virt.image import model as imgmodel
27LOG = logging.getLogger(__name__) 28LOG = logging.getLogger(__name__)
28 29
29MAX_DEVICE_WAIT = 30 30MAX_DEVICE_WAIT = 30
31MAX_FILE_CHECKS = 6
32FILE_CHECK_INTERVAL = 0.25
30 33
31 34
32class Mount(object): 35class Mount(object):
@@ -200,15 +203,24 @@ class Mount(object):
200 _out, err = utils.trycmd('kpartx', '-a', self.device, 203 _out, err = utils.trycmd('kpartx', '-a', self.device,
201 run_as_root=True, discard_warnings=True) 204 run_as_root=True, discard_warnings=True)
202 205
206 @loopingcall.RetryDecorator(
207 max_retry_count=MAX_FILE_CHECKS - 1,
208 max_sleep_time=FILE_CHECK_INTERVAL,
209 exceptions=IOError)
210 def recheck_path(map_path):
211 if not os.path.exists(map_path):
212 raise IOError()
213
203 # Note kpartx does nothing when presented with a raw image, 214 # Note kpartx does nothing when presented with a raw image,
204 # so given we only use it when we expect a partitioned image, fail 215 # so given we only use it when we expect a partitioned image, fail
205 if not os.path.exists(map_path): 216 try:
217 recheck_path(map_path)
218 self.mapped_device = map_path
219 self.mapped = True
220 except IOError:
206 if not err: 221 if not err:
207 err = _('partition %s not found') % self.partition 222 err = _('partition %s not found') % self.partition
208 self.error = _('Failed to map partitions: %s') % err 223 self.error = _('Failed to map partitions: %s') % err
209 else:
210 self.mapped_device = map_path
211 self.mapped = True
212 elif self.partition and os.path.exists(automapped_path): 224 elif self.partition and os.path.exists(automapped_path):
213 # Note auto mapping can be enabled with the 'max_part' option 225 # Note auto mapping can be enabled with the 'max_part' option
214 # to the nbd or loop kernel modules. Beware of possible races 226 # to the nbd or loop kernel modules. Beware of possible races