Skip to content

Commit

Permalink
Clear volumes stuck in 'downloading'
Browse files Browse the repository at this point in the history
If the CinderVolume service is restarted while an image-copy is
happening, the volume gets left in a 'downloading' state and
cannot be used or deleted. This fix adds code to init_host to
look for volumes (on this host) in such a state, and move them
to an error state. It also calls clear_download in the driver
in case the driver needs to perform an action, such as
detaching the volume.

Fixes Bug #1172645

Change-Id: Ia5dab9ebf997f573c0b4e57d983f5996af81ede5
  • Loading branch information
Dermot Tynan committed Apr 25, 2013
1 parent f4f75ca commit 3d18b30
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
13 changes: 11 additions & 2 deletions cinder/tests/test_volume.py
Expand Up @@ -77,7 +77,7 @@ def fake_get_target(obj, iqn):

@staticmethod
def _create_volume(size=0, snapshot_id=None, image_id=None,
metadata=None):
metadata=None, status="creating"):
"""Create a volume object."""
vol = {}
vol['size'] = size
Expand All @@ -86,13 +86,22 @@ def _create_volume(size=0, snapshot_id=None, image_id=None,
vol['user_id'] = 'fake'
vol['project_id'] = 'fake'
vol['availability_zone'] = FLAGS.storage_availability_zone
vol['status'] = "creating"
vol['status'] = status
vol['attach_status'] = "detached"
vol['host'] = FLAGS.host
if metadata is not None:
vol['metadata'] = metadata
return db.volume_create(context.get_admin_context(), vol)

def test_init_host_clears_downloads(self):
"""Test that init_host will unwedge a volume stuck in downloading."""
volume = self._create_volume(status='downloading')
volume_id = volume['id']
self.volume.init_host()
volume = db.volume_get(context.get_admin_context(), volume_id)
self.assertEquals(volume['status'], "error")
self.volume.delete_volume(self.context, volume_id)

def test_create_delete_volume(self):
"""Test volume can be created and deleted."""
# Need to stub out reserve, commit, and rollback
Expand Down
4 changes: 4 additions & 0 deletions cinder/volume/driver.py
Expand Up @@ -191,6 +191,10 @@ def restore_backup(self, context, backup, volume, backup_service):
"""Restore an existing backup to a new or existing volume."""
raise NotImplementedError()

def clear_download(self, context, volume):
"""Clean up after an interrupted image copy."""
pass


class ISCSIDriver(VolumeDriver):
"""Executes commands relating to ISCSI volumes.
Expand Down
5 changes: 5 additions & 0 deletions cinder/volume/manager.py
Expand Up @@ -147,6 +147,11 @@ def init_host(self):
for volume in volumes:
if volume['status'] in ['available', 'in-use']:
self.driver.ensure_export(ctxt, volume)
elif volume['status'] == 'downloading':
LOG.info(_("volume %s stuck in a downloading state"),
volume['id'])
self.driver.clear_download(ctxt, volume)
self.db.volume_update(ctxt, volume['id'], {'status': 'error'})
else:
LOG.info(_("volume %s: skipping export"), volume['name'])

Expand Down

0 comments on commit 3d18b30

Please sign in to comment.