]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librbd/test_notify.py
import ceph pacific 16.2.5
[ceph.git] / ceph / src / test / librbd / test_notify.py
1 #!/usr/bin/python3
2 import os
3 import sys
4 import time
5
6 from rados import Rados
7 from rbd import (RBD,
8 Image,
9 ImageNotFound,
10 RBD_FEATURE_EXCLUSIVE_LOCK,
11 RBD_FEATURE_LAYERING,
12 RBD_FEATURE_OBJECT_MAP,
13 RBD_FEATURE_FAST_DIFF,
14 RBD_FLAG_OBJECT_MAP_INVALID)
15
16 POOL_NAME='rbd'
17 PARENT_IMG_NAME='test_notify_parent'
18 CLONE_IMG_NAME='test_notify_clone'
19 CLONE_IMG_RENAME='test_notify_clone2'
20 IMG_SIZE = 16 << 20
21 IMG_ORDER = 20
22
23 def delete_image(ioctx, img_name):
24 image = Image(ioctx, img_name)
25 for snap in image.list_snaps():
26 snap_name = snap['name']
27 print("removing snapshot: %s@%s" % (img_name, snap_name))
28 if image.is_protected_snap(snap_name):
29 image.unprotect_snap(snap_name)
30 image.remove_snap(snap_name)
31 image.close()
32 print("removing image: %s" % img_name)
33 RBD().remove(ioctx, img_name)
34
35 def safe_delete_image(ioctx, img_name):
36 try:
37 delete_image(ioctx, img_name)
38 except ImageNotFound:
39 pass
40
41 def get_features():
42 features = os.getenv("RBD_FEATURES")
43 if features is not None:
44 features = int(features)
45 else:
46 features = int(RBD_FEATURE_EXCLUSIVE_LOCK | RBD_FEATURE_LAYERING |
47 RBD_FEATURE_OBJECT_MAP | RBD_FEATURE_FAST_DIFF)
48 assert((features & RBD_FEATURE_EXCLUSIVE_LOCK) != 0)
49 assert((features & RBD_FEATURE_LAYERING) != 0)
50 assert((features & RBD_FEATURE_OBJECT_MAP) != 0)
51 assert((features & RBD_FEATURE_FAST_DIFF) != 0)
52 return features
53
54 def master(ioctx):
55 print("starting master")
56 safe_delete_image(ioctx, CLONE_IMG_RENAME)
57 safe_delete_image(ioctx, CLONE_IMG_NAME)
58 safe_delete_image(ioctx, PARENT_IMG_NAME)
59
60 features = get_features()
61 RBD().create(ioctx, PARENT_IMG_NAME, IMG_SIZE, IMG_ORDER, old_format=False,
62 features=features)
63 with Image(ioctx, PARENT_IMG_NAME) as image:
64 image.create_snap('snap1')
65 image.protect_snap('snap1')
66
67 features = features & ~(RBD_FEATURE_FAST_DIFF)
68 RBD().clone(ioctx, PARENT_IMG_NAME, 'snap1', ioctx, CLONE_IMG_NAME,
69 features=features)
70 with Image(ioctx, CLONE_IMG_NAME) as image:
71 print("acquiring exclusive lock")
72 offset = 0
73 data = os.urandom(512)
74 while offset < IMG_SIZE:
75 image.write(data, offset)
76 offset += (1 << IMG_ORDER)
77 image.write(b'1', IMG_SIZE - 1)
78 assert(image.is_exclusive_lock_owner())
79
80 print("waiting for slave to complete")
81 while image.is_exclusive_lock_owner():
82 time.sleep(5)
83
84 safe_delete_image(ioctx, CLONE_IMG_RENAME)
85 safe_delete_image(ioctx, CLONE_IMG_NAME)
86 delete_image(ioctx, PARENT_IMG_NAME)
87 print("finished")
88
89 def slave(ioctx):
90 print("starting slave")
91
92 while True:
93 try:
94 with Image(ioctx, CLONE_IMG_NAME) as image:
95 if (image.list_lockers() != [] and
96 image.read(IMG_SIZE - 1, 1) == b'1'):
97 break
98 except Exception:
99 pass
100
101 print("detected master")
102
103 print("rename")
104 RBD().rename(ioctx, CLONE_IMG_NAME, CLONE_IMG_RENAME);
105
106 with Image(ioctx, CLONE_IMG_RENAME) as image:
107 print("flatten")
108 image.flatten()
109 assert(not image.is_exclusive_lock_owner())
110
111 print("resize")
112 image.resize(IMG_SIZE // 2)
113 assert(not image.is_exclusive_lock_owner())
114 assert(image.stat()['size'] == IMG_SIZE // 2)
115
116 print("create_snap")
117 image.create_snap('snap1')
118 assert(not image.is_exclusive_lock_owner())
119 assert(any(snap['name'] == 'snap1'
120 for snap in image.list_snaps()))
121
122 print("protect_snap")
123 image.protect_snap('snap1')
124 assert(not image.is_exclusive_lock_owner())
125 assert(image.is_protected_snap('snap1'))
126
127 print("unprotect_snap")
128 image.unprotect_snap('snap1')
129 assert(not image.is_exclusive_lock_owner())
130 assert(not image.is_protected_snap('snap1'))
131
132 print("rename_snap")
133 image.rename_snap('snap1', 'snap1-new')
134 assert(not image.is_exclusive_lock_owner())
135 assert(any(snap['name'] == 'snap1-new'
136 for snap in image.list_snaps()))
137
138 print("remove_snap")
139 image.remove_snap('snap1-new')
140 assert(not image.is_exclusive_lock_owner())
141 assert(list(image.list_snaps()) == [])
142
143 print("rebuild object map")
144 image.rebuild_object_map()
145 assert(not image.is_exclusive_lock_owner())
146 assert((image.flags() & RBD_FLAG_OBJECT_MAP_INVALID) == 0)
147
148 if 'RBD_DISABLE_UPDATE_FEATURES' not in os.environ:
149 print("update_features")
150 assert((image.features() & RBD_FEATURE_OBJECT_MAP) != 0)
151 image.update_features(RBD_FEATURE_OBJECT_MAP, False)
152 assert(not image.is_exclusive_lock_owner())
153 assert((image.features() & RBD_FEATURE_OBJECT_MAP) == 0)
154 image.update_features(RBD_FEATURE_OBJECT_MAP, True)
155 assert(not image.is_exclusive_lock_owner())
156 assert((image.features() & RBD_FEATURE_OBJECT_MAP) != 0)
157 assert((image.flags() & RBD_FLAG_OBJECT_MAP_INVALID) != 0)
158
159 print("write")
160 data = os.urandom(512)
161 image.write(data, 0)
162 assert(image.is_exclusive_lock_owner())
163
164 print("finished")
165
166 def main():
167 if len(sys.argv) != 2 or sys.argv[1] not in ['master', 'slave']:
168 print("usage: %s: [master/slave]" % sys.argv[0])
169 sys.exit(2)
170
171 rados = Rados(conffile='')
172 rados.connect()
173 ioctx = rados.open_ioctx(POOL_NAME)
174 if sys.argv[1] == 'master':
175 master(ioctx)
176 else:
177 slave(ioctx)
178 rados.shutdown()
179
180 if __name__ == "__main__":
181 main()