RBD_FLAG_OBJECT_MAP_INVALID = 1
+RBD_IMAGE_OPTION_FORMAT = 0
+RBD_IMAGE_OPTION_FEATURES = 1
+RBD_IMAGE_OPTION_ORDER = 2
+RBD_IMAGE_OPTION_STRIPE_UNIT = 3
+RBD_IMAGE_OPTION_STRIPE_COUNT = 4
+
+ # Are we running Python 2.x
+ _python2 = sys.hexversion < 0x03000000
+
+
+ if _python2:
+ str_type = basestring
+ else:
+ str_type = str
+
+
class Error(Exception):
pass
if (stripe_unit != 0 or stripe_count != 0) and not has_create3:
raise FunctionNotSupported('installed version of librbd does'
' not support stripe unit or count')
- if has_create3:
+ if has_create4:
+ format = old_format and 1 or 2
+ opts = c_void_p()
+ self.librbd.rbd_image_options_create(byref(opts))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_FORMAT,
+ c_uint64(format))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_FEATURES,
+ c_uint64(features))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_ORDER,
+ c_uint64(order))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_STRIPE_UNIT,
+ c_uint64(stripe_unit))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_STRIPE_COUNT,
+ c_uint64(stripe_count))
- ret = self.librbd.rbd_create4(ioctx.io, c_char_p(name),
++ ret = self.librbd.rbd_create4(ioctx.io, cstr(name),
+ c_uint64(size), opts)
+ self.librbd.rbd_image_options_get_uint64(opts,
+ RBD_IMAGE_OPTION_ORDER,
+ byref(c_uint64(order)))
+ self.librbd.rbd_image_options_destroy(opts)
+ elif has_create3:
- ret = self.librbd.rbd_create3(ioctx.io, c_char_p(name),
+ ret = self.librbd.rbd_create3(ioctx.io, cstr(name),
c_uint64(size),
c_uint64(features),
byref(c_int(order)),
"""
if order is None:
order = 0
- if not isinstance(p_snapname, str) or not isinstance(p_name, str):
+ if not isinstance(p_snapname, str_type) or not isinstance(p_name, str_type):
raise TypeError('parent name and snapname must be strings')
- if not isinstance(c_name, str):
+ if not isinstance(c_name, str_type):
raise TypeError('child name must be a string')
- ret = self.librbd.rbd_clone(p_ioctx.io, cstr(p_name),
- cstr(p_snapname),
- c_ioctx.io, cstr(c_name),
- c_uint64(features),
- byref(c_int(order)))
+ has_clone3 = hasattr(self.librbd, 'rbd_clone3')
+ if (stripe_unit != 0 or stripe_count != 0) and not has_clone3:
+ raise FunctionNotSupported('installed version of librbd does'
+ ' not support stripe unit or count')
+ if has_clone3:
+ opts = c_void_p()
+ self.librbd.rbd_image_options_create(byref(opts))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_FEATURES,
+ c_uint64(features))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_ORDER,
+ c_uint64(order))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_STRIPE_UNIT,
+ c_uint64(stripe_unit))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_STRIPE_COUNT,
+ c_uint64(stripe_count))
- ret = self.librbd.rbd_clone3(p_ioctx.io, c_char_p(p_name),
- c_char_p(p_snapname),
- c_ioctx.io, c_char_p(c_name),
++ ret = self.librbd.rbd_clone3(p_ioctx.io, cstr(p_name),
++ cstr(p_snapname),
++ c_ioctx.io, cstr(c_name),
+ opts)
+ self.librbd.rbd_image_options_get_uint64(opts,
+ RBD_IMAGE_OPTION_ORDER,
+ byref(c_uint64(order)))
+ self.librbd.rbd_image_options_destroy(opts)
+ else:
- ret = self.librbd.rbd_clone(p_ioctx.io, c_char_p(p_name),
- c_char_p(p_snapname),
- c_ioctx.io, c_char_p(c_name),
++ ret = self.librbd.rbd_clone(p_ioctx.io, cstr(p_name),
++ cstr(p_snapname),
++ c_ioctx.io, cstr(c_name),
+ c_uint64(features),
+ byref(c_int(order)))
if ret < 0:
raise make_ex(ret, 'error creating clone')
:type dest_ioctx: :class:`rados.Ioctx`
:param dest_name: the name of the copy
:type dest_name: str
+ :param features: bitmask of features to enable; if set, must include layering
+ :type features: int
+ :param order: the image is split into (2**order) byte objects
+ :type order: int
+ :param stripe_unit: stripe unit in bytes (default 0 for object size)
+ :type stripe_unit: int
+ :param stripe_count: objects to stripe over before looping
+ :type stripe_count: int
+ :raises: :class:`TypeError`
+ :raises: :class:`InvalidArgument`
:raises: :class:`ImageExists`
+ :raises: :class:`FunctionNotSupported`
+ :raises: :class:`ArgumentOutOfRange`
"""
- if not isinstance(dest_name, str):
+ if order is None:
+ order = 0
+ if not isinstance(dest_name, str_type):
raise TypeError('dest_name must be a string')
- ret = self.librbd.rbd_copy(self.image, dest_ioctx.io, cstr(dest_name))
+ has_copy3 = hasattr(self.librbd, 'rbd_copy3')
+ if (stripe_unit != 0 or stripe_count != 0) and not has_copy3:
+ raise FunctionNotSupported('installed version of librbd does'
+ ' not support stripe unit or count')
+ if has_copy3:
+ opts = c_void_p()
+ self.librbd.rbd_image_options_create(byref(opts))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_FEATURES,
+ c_uint64(features))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_ORDER,
+ c_uint64(order))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_STRIPE_UNIT,
+ c_uint64(stripe_unit))
+ self.librbd.rbd_image_options_set_uint64(opts,
+ RBD_IMAGE_OPTION_STRIPE_COUNT,
+ c_uint64(stripe_count))
+ ret = self.librbd.rbd_copy3(self.image, dest_ioctx.io,
- c_char_p(dest_name), opts)
++ cstr(dest_name), opts)
+ self.librbd.rbd_image_options_get_uint64(opts,
+ RBD_IMAGE_OPTION_ORDER,
+ byref(c_uint64(order)))
+ self.librbd.rbd_image_options_destroy(opts)
+ else:
- ret = self.librbd.rbd_copy(self.image, dest_ioctx.io, c_char_p(dest_name))
++ ret = self.librbd.rbd_copy(self.image, dest_ioctx.io, cstr(dest_name))
if ret < 0:
raise make_ex(ret, 'error copying image %s to %s' % (self.name, dest_name))
self.image.update_features(RBD_FEATURE_EXCLUSIVE_LOCK, True)
eq(features | RBD_FEATURE_EXCLUSIVE_LOCK, self.image.features())
+ @require_features([RBD_FEATURE_STRIPINGV2])
+ def test_create_with_params(self):
+ global features
+ image_name = get_temp_image_name()
+ order = 20
+ stripe_unit = 1 << 20
+ stripe_count = 10
+ self.rbd.create(ioctx, image_name, IMG_SIZE, order,
+ False, features, stripe_unit, stripe_count)
+ image = Image(ioctx, image_name)
+ info = image.stat()
+ check_stat(info, IMG_SIZE, order)
+ eq(image.features(), features)
+ eq(image.stripe_unit(), stripe_unit)
+ eq(image.stripe_count(), stripe_count)
+ image.close()
+ RBD().remove(ioctx, image_name)
+
def test_invalidate_cache(self):
- self.image.write('abc', 0)
- eq('abc', self.image.read(0, 3))
+ self.image.write(b'abc', 0)
+ eq(b'abc', self.image.read(0, 3))
self.image.invalidate_cache()
- eq('abc', self.image.read(0, 3))
+ eq(b'abc', self.image.read(0, 3))
def test_stat(self):
info = self.image.stat()
self.image.remove_snap('snap2')
def test_resize_down(self):
- new_size = IMG_SIZE / 2
+ new_size = IMG_SIZE // 2
data = rand_data(256)
- self.image.write(data, IMG_SIZE / 2);
+ self.image.write(data, IMG_SIZE // 2);
self.image.resize(new_size)
self.image.resize(IMG_SIZE)
- read = self.image.read(IMG_SIZE / 2, 256)
- eq('\0' * 256, read)
+ read = self.image.read(IMG_SIZE // 2, 256)
+ eq(b'\0' * 256, read)
def test_resize_bytes(self):
- new_size = IMG_SIZE / 2 - 5
+ new_size = IMG_SIZE // 2 - 5
data = rand_data(256)
- self.image.write(data, IMG_SIZE / 2 - 10);
+ self.image.write(data, IMG_SIZE // 2 - 10);
self.image.resize(new_size)
self.image.resize(IMG_SIZE)
- read = self.image.read(IMG_SIZE / 2 - 10, 5)
+ read = self.image.read(IMG_SIZE // 2 - 10, 5)
eq(data[:5], read)
- read = self.image.read(IMG_SIZE / 2 - 5, 251)
- eq('\0' * 251, read)
+ read = self.image.read(IMG_SIZE // 2 - 5, 251)
+ eq(b'\0' * 251, read)
- def test_copy(self):
+ def _test_copy(self, features=None, order=None, stripe_unit=None,
+ stripe_count=None):
global ioctx
data = rand_data(256)
self.image.write(data, 256)