import tempfile
import urllib
+from eventlet import tpool
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import encodeutils
with RADOSClient(self):
pass
+ def RBDProxy(self):
+ return tpool.Proxy(self.rbd.RBD())
+
def _ceph_args(self):
args = []
if self.configuration.rbd_user:
LOG.debug("opening connection to ceph cluster (timeout=%s)." %
(self.configuration.rados_connect_timeout))
- client = self.rados.Rados(
- rados_id=self.configuration.rbd_user,
- clustername=self.configuration.rbd_cluster_name,
- conffile=self.configuration.rbd_ceph_conf)
+ # NOTE (e0ne): rados is binding to C lbirary librados.
+ # It blocks eventlet loop so we need to run it in a native
+ # python thread.
+ client = tpool.Proxy(
+ self.rados.Rados(
+ rados_id=self.configuration.rbd_user,
+ clustername=self.configuration.rbd_cluster_name,
+ conffile=self.configuration.rbd_ceph_conf))
if pool is not None:
pool = encodeutils.safe_encode(pool)
else:
"'%(dest)s'" %
{'src_vol': src_name, 'src_snap': clone_snap,
'dest': dest_name})
- self.rbd.RBD().clone(client.ioctx, src_name, clone_snap,
- client.ioctx, dest_name,
- features=client.features)
+ self.RBDProxy().clone(client.ioctx, src_name, clone_snap,
+ client.ioctx, dest_name,
+ features=client.features)
except Exception as exc:
src_volume.unprotect_snap(clone_snap)
src_volume.remove_snap(clone_snap)
order = int(math.log(chunk_size, 2))
with RADOSClient(self) as client:
- self.rbd.RBD().create(client.ioctx,
- encodeutils.safe_encode(volume['name']),
- size,
- order,
- old_format=False,
- features=client.features)
+ self.RBDProxy().create(client.ioctx,
+ encodeutils.safe_encode(volume['name']),
+ size,
+ order,
+ old_format=False,
+ features=client.features)
def _flatten(self, pool, volume_name):
LOG.debug('flattening %(pool)s/%(img)s' %
dst=volume['name']))
with RADOSClient(self, src_pool) as src_client:
with RADOSClient(self) as dest_client:
- self.rbd.RBD().clone(src_client.ioctx,
- encodeutils.safe_encode(src_image),
- encodeutils.safe_encode(src_snap),
- dest_client.ioctx,
- encodeutils.safe_encode(volume['name']),
- features=src_client.features)
+ self.RBDProxy().clone(src_client.ioctx,
+ encodeutils.safe_encode(src_image),
+ encodeutils.safe_encode(src_snap),
+ dest_client.ioctx,
+ encodeutils.safe_encode(volume['name']),
+ features=src_client.features)
def _resize(self, volume, **kwargs):
size = kwargs.get('size', None)
# keep walking up the chain if it is itself a clone.
if (not parent_has_snaps) and parent_name.endswith('.deleted'):
LOG.debug("deleting parent %s" % (parent_name))
- self.rbd.RBD().remove(client.ioctx, parent_name)
+ self.RBDProxy().remove(client.ioctx, parent_name)
# Now move up to grandparent if there is one
if g_parent:
if clone_snap is None:
LOG.debug("deleting rbd volume %s" % (volume_name))
try:
- self.rbd.RBD().remove(client.ioctx, volume_name)
+ self.RBDProxy().remove(client.ioctx, volume_name)
except self.rbd.ImageBusy:
msg = (_("ImageBusy error raised while deleting rbd "
"volume. This may have been caused by a "
# delete it. Instead we will keep it as a silent volume which
# will be deleted when it's snapshot and clones are deleted.
new_name = "%s.deleted" % (volume_name)
- self.rbd.RBD().rename(client.ioctx, volume_name, new_name)
+ self.RBDProxy().rename(client.ioctx, volume_name, new_name)
def create_snapshot(self, snapshot):
"""Creates an rbd snapshot."""
# Raise an exception if we didn't find a suitable rbd image.
with RADOSClient(self) as client:
rbd_name = existing_ref['source-name']
- self.rbd.RBD().rename(client.ioctx,
- encodeutils.safe_encode(rbd_name),
- encodeutils.safe_encode(volume['name']))
+ self.RBDProxy().rename(client.ioctx,
+ encodeutils.safe_encode(rbd_name),
+ encodeutils.safe_encode(volume['name']))
def manage_existing_get_size(self, volume, existing_ref):
"""Return size of an existing image for manage_existing.