+++ /dev/null
-#!/usr/bin/python
-import os
-import sys
-import time
-
-from rados import Rados
-from rbd import (RBD,
- Image,
- ImageNotFound,
- RBD_FEATURE_EXCLUSIVE_LOCK,
- RBD_FEATURE_LAYERING,
- RBD_FEATURE_OBJECT_MAP,
- RBD_FEATURE_FAST_DIFF,
- RBD_FLAG_OBJECT_MAP_INVALID)
-
-POOL_NAME='rbd'
-PARENT_IMG_NAME='test_notify_parent'
-CLONE_IMG_NAME='test_notify_clone'
-CLONE_IMG_RENAME='test_notify_clone2'
-IMG_SIZE = 16 << 20
-IMG_ORDER = 20
-
-def delete_image(ioctx, img_name):
- image = Image(ioctx, img_name)
- for snap in image.list_snaps():
- snap_name = snap['name']
- print("removing snapshot: %s@%s" % (img_name, snap_name))
- if image.is_protected_snap(snap_name):
- image.unprotect_snap(snap_name)
- image.remove_snap(snap_name)
- image.close()
- print("removing image: %s" % img_name)
- RBD().remove(ioctx, img_name)
-
-def safe_delete_image(ioctx, img_name):
- try:
- delete_image(ioctx, img_name)
- except ImageNotFound:
- pass
-
-def get_features():
- features = os.getenv("RBD_FEATURES")
- if features is not None:
- features = int(features)
- else:
- features = int(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_LAYERING |
- RBD_FEATURE_OBJECT_MAP | RBD_FEATURE_FAST_DIFF)
- assert((features & RBD_FEATURE_EXCLUSIVE_LOCK) != 0)
- assert((features & RBD_FEATURE_LAYERING) != 0)
- assert((features & RBD_FEATURE_OBJECT_MAP) != 0)
- assert((features & RBD_FEATURE_FAST_DIFF) != 0)
- return features
-
-def master(ioctx):
- print("starting master")
- safe_delete_image(ioctx, CLONE_IMG_RENAME)
- safe_delete_image(ioctx, CLONE_IMG_NAME)
- safe_delete_image(ioctx, PARENT_IMG_NAME)
-
- features = get_features()
- RBD().create(ioctx, PARENT_IMG_NAME, IMG_SIZE, IMG_ORDER, old_format=False,
- features=features)
- with Image(ioctx, PARENT_IMG_NAME) as image:
- image.create_snap('snap1')
- image.protect_snap('snap1')
-
- features = features & ~(RBD_FEATURE_OBJECT_MAP | RBD_FEATURE_FAST_DIFF)
- RBD().clone(ioctx, PARENT_IMG_NAME, 'snap1', ioctx, CLONE_IMG_NAME,
- features=features)
- with Image(ioctx, CLONE_IMG_NAME) as image:
- print("acquiring exclusive lock")
- offset = 0
- data = os.urandom(512)
- while offset < IMG_SIZE:
- image.write(data, offset)
- offset += (1 << IMG_ORDER)
- image.write(b'1', IMG_SIZE - 1)
- assert(image.is_exclusive_lock_owner())
-
- print("waiting for slave to complete")
- while image.is_exclusive_lock_owner():
- time.sleep(5)
-
- safe_delete_image(ioctx, CLONE_IMG_RENAME)
- safe_delete_image(ioctx, CLONE_IMG_NAME)
- delete_image(ioctx, PARENT_IMG_NAME)
- print("finished")
-
-def slave(ioctx):
- print("starting slave")
-
- while True:
- try:
- with Image(ioctx, CLONE_IMG_NAME) as image:
- if (image.list_lockers() != [] and
- image.read(IMG_SIZE - 1, 1) == b'1'):
- break
- except Exception:
- pass
-
- print("detected master")
-
- print("rename")
- RBD().rename(ioctx, CLONE_IMG_NAME, CLONE_IMG_RENAME);
- assert(not image.is_exclusive_lock_owner())
-
- with Image(ioctx, CLONE_IMG_RENAME) as image:
- print("flatten")
- image.flatten()
- assert(not image.is_exclusive_lock_owner())
-
- print("resize")
- image.resize(IMG_SIZE // 2)
- assert(not image.is_exclusive_lock_owner())
- assert(image.stat()['size'] == IMG_SIZE // 2)
-
- print("create_snap")
- image.create_snap('snap1')
- assert(not image.is_exclusive_lock_owner())
- assert(any(snap['name'] == 'snap1'
- for snap in image.list_snaps()))
-
- print("protect_snap")
- image.protect_snap('snap1')
- assert(not image.is_exclusive_lock_owner())
- assert(image.is_protected_snap('snap1'))
-
- print("unprotect_snap")
- image.unprotect_snap('snap1')
- assert(not image.is_exclusive_lock_owner())
- assert(not image.is_protected_snap('snap1'))
-
- print("rename_snap")
- image.rename_snap('snap1', 'snap1-new')
- assert(not image.is_exclusive_lock_owner())
- assert(any(snap['name'] == 'snap1-new'
- for snap in image.list_snaps()))
-
- print("remove_snap")
- image.remove_snap('snap1-new')
- assert(not image.is_exclusive_lock_owner())
- assert(list(image.list_snaps()) == [])
-
- print("rebuild object map")
- assert((image.features() & RBD_FEATURE_OBJECT_MAP) == 0)
- image.update_features(RBD_FEATURE_OBJECT_MAP, True)
- assert((image.flags() & RBD_FLAG_OBJECT_MAP_INVALID) != 0)
- image.rebuild_object_map()
- assert(not image.is_exclusive_lock_owner())
- assert((image.flags() & RBD_FLAG_OBJECT_MAP_INVALID) == 0)
-
- print("write")
- data = os.urandom(512)
- image.write(data, 0)
- assert(image.is_exclusive_lock_owner())
-
- print("finished")
-
-def main():
- if len(sys.argv) != 2 or sys.argv[1] not in ['master', 'slave']:
- print("usage: %s: [master/slave]" % sys.argv[0])
- sys.exit(2)
-
- rados = Rados(conffile='')
- rados.connect()
- ioctx = rados.open_ioctx(POOL_NAME)
- if sys.argv[1] == 'master':
- master(ioctx)
- else:
- slave(ioctx)
- rados.shutdown()
-
-if __name__ == "__main__":
- main()