From: Eric Harney Date: Thu, 14 Nov 2013 20:51:15 +0000 (-0500) Subject: GlusterFS: Synchronize operations that manipulate qcow2 data X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=8a1fd8889170c289910944db016a4206fe5e1e32;p=openstack-build%2Fcinder-build.git GlusterFS: Synchronize operations that manipulate qcow2 data Operations that modify qcow2 chains or the GlusterFS driver's snapshot info file should use locking so that more than one thread cannot run these operations at the same time. Without this it is possible for multiple threads to concurrently modify snapshot information resulting in an incomplete snapshot chain. Closes-Bug: #1251425 Change-Id: I93c6ffecd9aec38560cb19085243390b9120b363 --- diff --git a/cinder/volume/drivers/glusterfs.py b/cinder/volume/drivers/glusterfs.py index 0987be037..7f7497c37 100644 --- a/cinder/volume/drivers/glusterfs.py +++ b/cinder/volume/drivers/glusterfs.py @@ -30,6 +30,7 @@ from cinder import exception from cinder.image import image_utils from cinder.openstack.common import log as logging from cinder import units +from cinder import utils from cinder.volume.drivers import nfs LOG = logging.getLogger(__name__) @@ -62,6 +63,10 @@ CONF.import_opt('volume_name_template', 'cinder.db') class GlusterfsDriver(nfs.RemoteFsDriver): """Gluster based cinder driver. Creates file on Gluster share for using it as block device on hypervisor. + + Operations such as create/delete/extend volume/snapshot use locking on a + per-process basis to prevent multiple threads from modifying qcow2 chains + or the snapshot .info file simultaneously. """ driver_volume_type = 'glusterfs' @@ -187,6 +192,7 @@ class GlusterfsDriver(nfs.RemoteFsDriver): return {'provider_location': src_vref['provider_location']} + @utils.synchronized('glusterfs', external=False) def create_volume(self, volume): """Creates a volume.""" @@ -259,6 +265,7 @@ class GlusterfsDriver(nfs.RemoteFsDriver): path_to_new_vol, out_format) + @utils.synchronized('glusterfs', external=False) def delete_volume(self, volume): """Deletes a logical volume.""" @@ -273,6 +280,7 @@ class GlusterfsDriver(nfs.RemoteFsDriver): self._execute('rm', '-f', mounted_path, run_as_root=True) + @utils.synchronized('glusterfs', external=False) def create_snapshot(self, snapshot): """Create a snapshot. @@ -525,6 +533,7 @@ class GlusterfsDriver(nfs.RemoteFsDriver): return next(f for f in backing_chain if f.get('backing-filename', '') == snapshot_file) + @utils.synchronized('glusterfs', external=False) def delete_snapshot(self, snapshot): """Delete a snapshot. @@ -833,6 +842,7 @@ class GlusterfsDriver(nfs.RemoteFsDriver): def validate_connector(self, connector): pass + @utils.synchronized('glusterfs', external=False) def initialize_connection(self, volume, connector): """Allow connection to connector and return connection info.""" @@ -905,6 +915,7 @@ class GlusterfsDriver(nfs.RemoteFsDriver): if temp_path is not None: self._execute('rm', '-f', temp_path) + @utils.synchronized('glusterfs', external=False) def extend_volume(self, volume, size_gb): volume_path = self.local_path(volume) volume_filename = os.path.basename(volume_path)