]>
git.proxmox.com Git - ceph.git/blob - ceph/qa/tasks/rbd_fio.py
791cfd00af12bd511cb0b48011a62ce2e1edd998
2 Long running fio tests on rbd mapped devices for format/features provided in config
3 Many fio parameters can be configured so that this task can be used along with thrash/power-cut tests
4 and exercise IO on full disk for all format/features
5 - This test should not be run on VM due to heavy use of resource
14 from teuthology
.parallel
import parallel
15 from teuthology
import misc
as teuthology
16 from tempfile
import NamedTemporaryFile
17 from teuthology
.orchestra
import run
18 from teuthology
.packaging
import install_package
, remove_package
20 log
= logging
.getLogger(__name__
)
22 @contextlib.contextmanager
23 def task(ctx
, config
):
26 fio-io-size: 100g or 80% or 100m
29 features: [[layering],[striping],[layering,exclusive-lock,object-map]]
30 test-clone-io: 1 #remove this option to not run create rbd clone and not run io on clone
31 io-engine: "sync or rbd or any io-engine"
44 features: [[layering],[striping]]
47 Create rbd image + device and exercise IO for format/features provided in config file
48 Config can be per client or one config can be used for all clients, fio jobs are run in parallel for client provided
52 client_config
= config
['all']
53 clients
= ctx
.cluster
.only(teuthology
.is_type('client'))
54 rbd_test_dir
= teuthology
.get_testdir(ctx
) + "/rbd_fio_test"
55 for remote
,role
in clients
.remotes
.items():
56 if 'client_config' in locals():
58 p
.spawn(run_fio
, remote
, client_config
, rbd_test_dir
)
60 for client_config
in config
:
61 if client_config
in role
:
63 p
.spawn(run_fio
, remote
, config
[client_config
], rbd_test_dir
)
68 def get_ioengine_package_name(ioengine
, remote
):
69 system_type
= teuthology
.get_system_type(remote
)
71 return 'librbd1-devel' if system_type
== 'rpm' else 'librbd-dev'
72 elif ioengine
== 'libaio':
73 return 'libaio-devel' if system_type
== 'rpm' else 'libaio-dev'
78 def run_rbd_map(remote
, image
, iodepth
):
79 iodepth
= max(iodepth
, 128) # RBD_QUEUE_DEPTH_DEFAULT
80 out
= StringIO
.StringIO()
81 remote
.run(args
=['sudo', 'rbd', 'device', 'map', '-o',
82 'queue_depth={}'.format(iodepth
), image
], stdout
=out
)
83 dev
= out
.getvalue().rstrip('\n')
84 teuthology
.sudo_write_file(
86 '/sys/block/{}/queue/nr_requests'.format(os
.path
.basename(dev
)),
91 def run_fio(remote
, config
, rbd_test_dir
):
93 create fio config file with options based on above config
94 get the fio from github, generate binary, and use it to run on
95 the generated fio config file
97 fio_config
=NamedTemporaryFile(prefix
='fio_rbd_', dir='/tmp/', delete
=False)
98 fio_config
.write('[global]\n')
99 if config
.get('io-engine'):
100 ioengine
=config
['io-engine']
101 fio_config
.write('ioengine={ioe}\n'.format(ioe
=ioengine
))
103 fio_config
.write('ioengine=sync\n')
106 fio_config
.write('bs={bs}\n'.format(bs
=bs
))
108 fio_config
.write('bs=4k\n')
109 iodepth
= config
.get('io-depth', 2)
110 fio_config
.write('iodepth={iod}\n'.format(iod
=iodepth
))
111 if config
.get('fio-io-size'):
112 size
=config
['fio-io-size']
113 fio_config
.write('size={size}\n'.format(size
=size
))
115 fio_config
.write('size=100m\n')
117 fio_config
.write('time_based\n')
118 if config
.get('runtime'):
119 runtime
=config
['runtime']
120 fio_config
.write('runtime={runtime}\n'.format(runtime
=runtime
))
122 fio_config
.write('runtime=1800\n')
123 fio_config
.write('allow_file_create=0\n')
125 if config
.get('image_size'):
126 image_size
=config
['image_size']
129 features
=[['layering'],['striping'],['exclusive-lock','object-map']]
131 if config
.get('formats'):
132 formats
=config
['formats']
133 if config
.get('features'):
134 features
=config
['features']
135 if config
.get('fio-version'):
136 fio_version
=config
['fio-version']
138 # handle package required for ioengine, if any
140 ioengine_pkg
= get_ioengine_package_name(ioengine
, remote
)
142 install_package(ioengine_pkg
, remote
)
144 fio_config
.write('norandommap\n')
145 if ioengine
== 'rbd':
146 fio_config
.write('clientname=admin\n')
147 fio_config
.write('pool=rbd\n')
148 fio_config
.write('invalidate=0\n')
149 elif ioengine
== 'libaio':
150 fio_config
.write('direct=1\n')
152 for feature
in features
:
153 log
.info("Creating rbd images on {sn}".format(sn
=sn
))
154 feature_name
= '-'.join(feature
)
155 rbd_name
= 'i{i}f{f}{sn}'.format(i
=frmt
,f
=feature_name
,sn
=sn
)
156 rbd_snap_name
= 'i{i}f{f}{sn}@i{i}f{f}{sn}Snap'.format(i
=frmt
,f
=feature_name
,sn
=sn
)
157 rbd_clone_name
= 'i{i}f{f}{sn}Clone'.format(i
=frmt
,f
=feature_name
,sn
=sn
)
158 create_args
=['rbd', 'create',
159 '--size', '{size}'.format(size
=image_size
),
161 '--image-format', '{f}'.format(f
=frmt
)]
162 map(lambda x
: create_args
.extend(['--image-feature', x
]), feature
)
163 remote
.run(args
=create_args
)
164 remote
.run(args
=['rbd', 'info', rbd_name
])
165 if ioengine
!= 'rbd':
166 rbd_dev
= run_rbd_map(remote
, rbd_name
, iodepth
)
167 if config
.get('test-clone-io'):
168 log
.info("Testing clones using fio")
169 remote
.run(args
=['rbd', 'snap', 'create', rbd_snap_name
])
170 remote
.run(args
=['rbd', 'snap', 'protect', rbd_snap_name
])
171 remote
.run(args
=['rbd', 'clone', rbd_snap_name
, rbd_clone_name
])
172 rbd_clone_dev
= run_rbd_map(remote
, rbd_clone_name
, iodepth
)
173 fio_config
.write('[{rbd_dev}]\n'.format(rbd_dev
=rbd_dev
))
176 fio_config
.write('rw={rw}\n'.format(rw
=rw
))
178 fio_config
.write('rw=randrw\n')
179 fio_config
.write('filename={rbd_dev}\n'.format(rbd_dev
=rbd_dev
))
180 if config
.get('test-clone-io'):
181 fio_config
.write('[{rbd_clone_dev}]\n'.format(rbd_clone_dev
=rbd_clone_dev
))
182 fio_config
.write('rw={rw}\n'.format(rw
=rw
))
183 fio_config
.write('filename={rbd_clone_dev}\n'.format(rbd_clone_dev
=rbd_clone_dev
))
185 if config
.get('test-clone-io'):
186 log
.info("Testing clones using fio")
187 remote
.run(args
=['rbd', 'snap', 'create', rbd_snap_name
])
188 remote
.run(args
=['rbd', 'snap', 'protect', rbd_snap_name
])
189 remote
.run(args
=['rbd', 'clone', rbd_snap_name
, rbd_clone_name
])
190 fio_config
.write('[{img_name}]\n'.format(img_name
=rbd_name
))
193 fio_config
.write('rw={rw}\n'.format(rw
=rw
))
195 fio_config
.write('rw=randrw\n')
196 fio_config
.write('rbdname={img_name}\n'.format(img_name
=rbd_name
))
197 if config
.get('test-clone-io'):
198 fio_config
.write('[{clone_img_name}]\n'.format(clone_img_name
=rbd_clone_name
))
199 fio_config
.write('rw={rw}\n'.format(rw
=rw
))
200 fio_config
.write('rbdname={clone_img_name}\n'.format(clone_img_name
=rbd_clone_name
))
204 remote
.put_file(fio_config
.name
,fio_config
.name
)
206 log
.info("Running rbd feature - fio test on {sn}".format(sn
=sn
))
207 fio
= "https://github.com/axboe/fio/archive/fio-" + fio_version
+ ".tar.gz"
208 remote
.run(args
=['mkdir', run
.Raw(rbd_test_dir
),])
209 remote
.run(args
=['cd' , run
.Raw(rbd_test_dir
),
210 run
.Raw(';'), 'wget', fio
, run
.Raw(';'), run
.Raw('tar -xvf fio*tar.gz'), run
.Raw(';'),
211 run
.Raw('cd fio-fio*'), run
.Raw(';'), './configure', run
.Raw(';'), 'make'])
212 remote
.run(args
=['ceph', '-s'])
213 remote
.run(args
=[run
.Raw('{tdir}/fio-fio-{v}/fio --showcmd {f}'.format(tdir
=rbd_test_dir
,v
=fio_version
,f
=fio_config
.name
))])
214 remote
.run(args
=['sudo', run
.Raw('{tdir}/fio-fio-{v}/fio {f}'.format(tdir
=rbd_test_dir
,v
=fio_version
,f
=fio_config
.name
))])
215 remote
.run(args
=['ceph', '-s'])
217 out
=StringIO
.StringIO()
218 remote
.run(args
=['rbd', 'device', 'list', '--format=json'], stdout
=out
)
219 mapped_images
= json
.loads(out
.getvalue())
221 log
.info("Unmapping rbd images on {sn}".format(sn
=sn
))
222 for image
in mapped_images
:
223 remote
.run(args
=['sudo', 'rbd', 'device', 'unmap',
224 str(image
['device'])])
225 log
.info("Cleaning up fio install")
226 remote
.run(args
=['rm','-rf', run
.Raw(rbd_test_dir
)])
228 remove_package(ioengine_pkg
, remote
)