Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / librbd / test_notify.py
1 #!/usr/bin/python
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_OBJECT_MAP | 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     assert(not image.is_exclusive_lock_owner())
106
107     with Image(ioctx, CLONE_IMG_RENAME) as image:
108         print("flatten")
109         image.flatten()
110         assert(not image.is_exclusive_lock_owner())
111
112         print("resize")
113         image.resize(IMG_SIZE // 2)
114         assert(not image.is_exclusive_lock_owner())
115         assert(image.stat()['size'] == IMG_SIZE // 2)
116
117         print("create_snap")
118         image.create_snap('snap1')
119         assert(not image.is_exclusive_lock_owner())
120         assert(any(snap['name'] == 'snap1'
121                    for snap in image.list_snaps()))
122
123         print("protect_snap")
124         image.protect_snap('snap1')
125         assert(not image.is_exclusive_lock_owner())
126         assert(image.is_protected_snap('snap1'))
127
128         print("unprotect_snap")
129         image.unprotect_snap('snap1')
130         assert(not image.is_exclusive_lock_owner())
131         assert(not image.is_protected_snap('snap1'))
132
133         print("rename_snap")
134         image.rename_snap('snap1', 'snap1-new')
135         assert(not image.is_exclusive_lock_owner())
136         assert(any(snap['name'] == 'snap1-new'
137                    for snap in image.list_snaps()))
138
139         print("remove_snap")
140         image.remove_snap('snap1-new')
141         assert(not image.is_exclusive_lock_owner())
142         assert(list(image.list_snaps()) == [])
143
144         print("rebuild object map")
145         assert((image.features() & RBD_FEATURE_OBJECT_MAP) == 0)
146         image.update_features(RBD_FEATURE_OBJECT_MAP, True)
147         assert((image.flags() & RBD_FLAG_OBJECT_MAP_INVALID) != 0)
148         image.rebuild_object_map()
149         assert(not image.is_exclusive_lock_owner())
150         assert((image.flags() & RBD_FLAG_OBJECT_MAP_INVALID) == 0)
151
152         print("write")
153         data = os.urandom(512)
154         image.write(data, 0)
155         assert(image.is_exclusive_lock_owner())
156
157     print("finished")
158
159 def main():
160     if len(sys.argv) != 2 or sys.argv[1] not in ['master', 'slave']:
161         print("usage: %s: [master/slave]" % sys.argv[0])
162         sys.exit(2)
163
164     rados = Rados(conffile='')
165     rados.connect()
166     ioctx = rados.open_ioctx(POOL_NAME)
167     if sys.argv[1] == 'master':
168         master(ioctx)
169     else:
170         slave(ioctx)
171     rados.shutdown()
172
173 if __name__ == "__main__":
174     main()