]>
Commit | Line | Data |
---|---|---|
309874bd | 1 | From 37ec0e0badcbf3cc6d3959f1867b8a1d6db3be13 Mon Sep 17 00:00:00 2001 |
5ad5891c DM |
2 | From: Dietmar Maurer <dietmar@proxmox.com> |
3 | Date: Wed, 14 Nov 2012 09:57:04 +0100 | |
309874bd | 4 | Subject: [PATCH v3 5/7] add regression tests for backup |
5ad5891c | 5 | |
16aecab6 | 6 | Simple regression tests using vma-reader and vma-writer. |
5ad5891c | 7 | |
309874bd DM |
8 | Note: the call to g_thread_init() solves problems with g_slice_alloc() - without that call we get arbitrary crashes. |
9 | ||
5ad5891c DM |
10 | Signed-off-by: Dietmar Maurer <dietmar@proxmox.com> |
11 | --- | |
16aecab6 | 12 | tests/Makefile | 11 +- |
309874bd DM |
13 | tests/backup-test.c | 515 +++++++++++++++++++++++++++++++++++++++++++++++++++ |
14 | 2 files changed, 524 insertions(+), 2 deletions(-) | |
5ad5891c DM |
15 | create mode 100644 tests/backup-test.c |
16 | ||
5ad5891c DM |
17 | diff --git a/tests/Makefile b/tests/Makefile |
18 | index b60f0fb..cffbd22 100644 | |
19 | --- a/tests/Makefile | |
20 | +++ b/tests/Makefile | |
21 | @@ -20,6 +20,8 @@ check-unit-y += tests/test-thread-pool$(EXESUF) | |
22 | ||
23 | check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh | |
24 | ||
25 | +check-backup-y = tests/backup-test$(EXESUF) | |
26 | + | |
27 | # All QTests for now are POSIX-only, but the dependencies are | |
28 | # really in libqtest, not in the testcases themselves. | |
29 | check-qtest-i386-y = tests/fdc-test$(EXESUF) | |
30 | @@ -54,6 +56,7 @@ tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools | |
31 | tests/test-aio$(EXESUF): tests/test-aio.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) libqemustub.a | |
32 | tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) libqemustub.a | |
33 | tests/test-iov$(EXESUF): tests/test-iov.o iov.o | |
34 | +tests/backup-test$(EXESUF): tests/backup-test.o vma-reader.o $(tools-obj-y) $(block-obj-y) libqemustub.a | |
35 | ||
36 | tests/test-qapi-types.c tests/test-qapi-types.h :\ | |
37 | $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py | |
38 | @@ -146,10 +149,14 @@ check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) | |
39 | ||
40 | # Consolidated targets | |
41 | ||
42 | -.PHONY: check-qtest check-unit check | |
43 | +.PHONY: check-backup check-qtest check-unit check | |
44 | check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS)) | |
45 | check-unit: $(patsubst %,check-%, $(check-unit-y)) | |
46 | check-block: $(patsubst %,check-%, $(check-block-y)) | |
47 | -check: check-unit check-qtest | |
48 | + | |
49 | +check-backup: tests/backup-test$(EXESUF) | |
50 | + $< | |
51 | + | |
52 | +check: check-unit check-qtest check-backup | |
53 | ||
54 | -include $(wildcard tests/*.d) | |
55 | diff --git a/tests/backup-test.c b/tests/backup-test.c | |
56 | new file mode 100644 | |
309874bd | 57 | index 0000000..813590e |
5ad5891c DM |
58 | --- /dev/null |
59 | +++ b/tests/backup-test.c | |
309874bd | 60 | @@ -0,0 +1,515 @@ |
5ad5891c DM |
61 | +/* |
62 | + * QEMU backup test suit | |
63 | + * | |
64 | + * Copyright (C) Proxmox Server Solutions | |
65 | + * | |
66 | + * Authors: | |
67 | + * Dietmar Maurer (dietmar@proxmox.com) | |
68 | + * | |
69 | + * This work is licensed under the terms of the GNU GPL, version 2. See | |
70 | + * the COPYING file in the top-level directory. | |
71 | + * | |
72 | + * Fixme: running 'backup-test -l' trigger a bug in g_slice_alloc() | |
73 | + * Note: 'G_SLICE=always-malloc ./tests/backup-test -l' works | |
74 | + * | |
75 | + */ | |
76 | + | |
77 | +#include <sys/time.h> | |
78 | +#include <sys/types.h> | |
79 | +#include <stdarg.h> | |
80 | +#include <stdio.h> | |
81 | +#include <getopt.h> | |
82 | +#include <libgen.h> | |
83 | + | |
84 | +#include "qemu-common.h" | |
85 | +#include "main-loop.h" | |
86 | +#include "block_int.h" | |
87 | + | |
88 | +#include "vma.h" | |
89 | + | |
90 | +static int opt_debug; | |
91 | +static int opt_loop; | |
92 | + | |
93 | +#define DPRINTF(fmt, ...) \ | |
94 | + do { if (opt_debug) { printf(fmt, ## __VA_ARGS__); } } while (0) | |
95 | + | |
96 | +#define CLUSTER(x) (x*BACKUP_CLUSTER_SIZE) | |
97 | + | |
98 | +#define RUN_TEST(testfunc, speed) \ | |
99 | + backup_test(#testfunc " speed " #speed, speed, testfunc); | |
100 | + | |
101 | + | |
102 | +static unsigned char buf_sec_pattern_cd[BDRV_SECTOR_SIZE]; | |
103 | +static unsigned char buf_sec_pattern_32[BDRV_SECTOR_SIZE]; | |
104 | + | |
105 | +#define TEST_IMG_SIZE (6*1024*1024+BDRV_SECTOR_SIZE) | |
106 | +#define TEST_IMG_NAME "backuptest.raw" | |
107 | +#define TEST_IMG_RESTORE_NAME "backuptest.raw.restore" | |
108 | +#define TEST_VMA_NAME "backuptest.vma" | |
109 | + | |
110 | +typedef struct BackupCB { | |
111 | + VmaWriter *vmaw; | |
112 | + uint8_t dev_id; | |
113 | +} BackupCB; | |
114 | + | |
115 | +static int backup_dump_cb(void *opaque, BlockDriverState *bs, | |
116 | + int64_t cluster_num, unsigned char *buf) | |
117 | +{ | |
118 | + BackupCB *bcb = opaque; | |
119 | + | |
120 | + DPRINTF("backup_dump_cb C%zd %d\n", cluster_num, bcb->dev_id); | |
121 | + | |
122 | + size_t zb = 0; | |
123 | + if (vma_writer_write(bcb->vmaw, bcb->dev_id, cluster_num, buf, &zb) < 0) { | |
124 | + printf("backup_dump_cb vma_writer_write failed\n"); | |
125 | + return -1; | |
126 | + } | |
127 | + | |
128 | + return 0; | |
129 | +} | |
130 | + | |
131 | +static void backup_complete_cb(void *opaque, int ret) | |
132 | +{ | |
133 | + BackupCB *bcb = opaque; | |
134 | + | |
135 | + DPRINTF("backup_complete_cb %d %d\n", bcb->dev_id, ret); | |
136 | + | |
137 | + if (ret < 0) { | |
138 | + vma_writer_set_error(bcb->vmaw, "backup_complete_cb %d", ret); | |
139 | + } | |
140 | + | |
141 | + if (vma_writer_close_stream(bcb->vmaw, bcb->dev_id) <= 0) { | |
142 | + Error *err = NULL; | |
143 | + if (vma_writer_close(bcb->vmaw, &err) != 0) { | |
144 | + g_error("vma_writer_close failed %s", error_get_pretty(err)); | |
145 | + } | |
146 | + } | |
147 | + DPRINTF("backup_complete_cb finish\n"); | |
148 | +} | |
149 | + | |
150 | +static void write_sec_pattern_cd(BlockDriverState *bs, int64_t offset) | |
151 | +{ | |
152 | + int ret; | |
153 | + | |
154 | + DPRINTF("write_sec_pattern_cd %zd\n", offset); | |
155 | + | |
156 | + if (offset & 0x1ff) { | |
157 | + g_error("write_sec_pattern_cd offset %zd is not sector aligned\n", | |
158 | + offset); | |
159 | + } | |
160 | + | |
161 | + ret = bdrv_write(bs, offset >> 9, buf_sec_pattern_cd, 1); | |
162 | + if (ret < 0) { | |
163 | + g_error("write_sec_pattern_cd %zd failed", offset); | |
164 | + } | |
165 | + | |
166 | +} | |
167 | + | |
168 | +static void read_sec(BlockDriverState *bs, int64_t offset, unsigned char *buf) | |
169 | +{ | |
170 | + DPRINTF("read_sec C%zd start %zd\n", offset>>VMA_CLUSTER_BITS, offset); | |
171 | + | |
172 | + if (offset & 0x1ff) { | |
173 | + g_error("read_sec offset %zd is not sector aligned\n", offset); | |
174 | + } | |
175 | + | |
176 | + if (bdrv_read(bs, offset >> 9, buf, 1) < 0) { | |
177 | + g_error("bdrv_read failed"); | |
178 | + } | |
179 | +} | |
180 | + | |
181 | +static bool request_term; | |
182 | + | |
183 | +typedef struct TestCB { | |
184 | + Coroutine *co; | |
185 | + BlockDriverState *bs; | |
186 | + bool finished; | |
187 | +} TestCB; | |
188 | + | |
189 | +static TestCB *enter_test_co(BlockDriverState *bs, CoroutineEntry *entry) | |
190 | +{ | |
191 | + TestCB *cb = g_new0(TestCB, 1); | |
192 | + cb->bs = bs; | |
193 | + cb->co = qemu_coroutine_create(entry); | |
194 | + qemu_coroutine_enter(cb->co, cb); | |
195 | + return cb; | |
196 | +} | |
197 | + | |
198 | +static void test_co_sleep(double sec) | |
199 | +{ | |
200 | + co_sleep_ns(rt_clock, (int64_t)(sec*1000000000)); | |
201 | +}; | |
202 | + | |
203 | +static void test_co_yield(void) | |
204 | +{ | |
205 | + co_sleep_ns(rt_clock, (int64_t)(1000)); | |
206 | +}; | |
207 | + | |
208 | +static void coroutine_fn run_co_test1(void *opaque) | |
209 | +{ | |
210 | + assert(opaque); | |
211 | + TestCB *cb = (TestCB *)opaque; | |
212 | + | |
213 | + test_co_sleep(0.2); | |
214 | + write_sec_pattern_cd(cb->bs, 5*BACKUP_CLUSTER_SIZE); | |
215 | + test_co_sleep(0.2); | |
216 | + write_sec_pattern_cd(cb->bs, 10*BACKUP_CLUSTER_SIZE); | |
217 | + test_co_sleep(0.2); | |
218 | + write_sec_pattern_cd(cb->bs, 10*BACKUP_CLUSTER_SIZE); | |
219 | + | |
220 | + cb->finished = true; | |
221 | +} | |
222 | + | |
223 | +static void coroutine_fn run_co_test2(void *opaque) | |
224 | +{ | |
225 | + assert(opaque); | |
226 | + TestCB *cb = (TestCB *)opaque; | |
227 | + unsigned char buf[512]; | |
228 | + | |
229 | + test_co_sleep(0.2); | |
230 | + read_sec(cb->bs, 5*BACKUP_CLUSTER_SIZE, buf); | |
231 | + write_sec_pattern_cd(cb->bs, 6*BACKUP_CLUSTER_SIZE); | |
232 | + | |
233 | + cb->finished = true; | |
234 | +} | |
235 | + | |
236 | +static void coroutine_fn run_co_random_read(void *opaque) | |
237 | +{ | |
238 | + assert(opaque); | |
239 | + TestCB *cb = (TestCB *)opaque; | |
240 | + int64_t sectors = bdrv_getlength(cb->bs)/BDRV_SECTOR_SIZE - 1; | |
241 | + unsigned char buf[512]; | |
242 | + | |
243 | + while (1) { | |
244 | + test_co_yield(); | |
245 | + if (request_term) { | |
246 | + DPRINTF("finish run_co_random_read\n"); | |
247 | + break; | |
248 | + } | |
249 | + int64_t s = (rand()*sectors)/RAND_MAX; | |
250 | + read_sec(cb->bs, s*BDRV_SECTOR_SIZE, buf); | |
251 | + } | |
252 | + | |
253 | + cb->finished = true; | |
254 | +} | |
255 | + | |
256 | +static void coroutine_fn run_co_random_write(void *opaque) | |
257 | +{ | |
258 | + assert(opaque); | |
259 | + TestCB *cb = (TestCB *)opaque; | |
260 | + int64_t sectors = bdrv_getlength(cb->bs)/BDRV_SECTOR_SIZE; | |
261 | + | |
262 | + while (1) { | |
263 | + test_co_yield(); | |
264 | + if (request_term) { | |
265 | + DPRINTF("finish run_co_random_write\n"); | |
266 | + break; | |
267 | + } | |
268 | + int64_t s = (rand()*sectors)/RAND_MAX; | |
269 | + write_sec_pattern_cd(cb->bs, s*BDRV_SECTOR_SIZE); | |
270 | + } | |
271 | + | |
272 | + cb->finished = true; | |
273 | +} | |
274 | + | |
275 | +static void fill_test_sector(void *buf, size_t sector_num) | |
276 | +{ | |
277 | + int64_t *i64buf = (int64_t *)buf; | |
278 | + int i; | |
279 | + | |
280 | + int data = sector_num; | |
281 | + if (sector_num >= 8 && sector_num < 8*(2*16+2)) { | |
282 | + data = 0; /* add zero region for testing */ | |
283 | + } | |
284 | + | |
285 | + for (i = 0; i < (512/sizeof(int64_t)); i++) { | |
286 | + i64buf[i] = data; | |
287 | + } | |
288 | +} | |
289 | + | |
290 | +static void verify_archive(const char *archive, size_t size) | |
291 | +{ | |
292 | + Error *errp = NULL; | |
293 | + | |
294 | + VmaReader *vmar = vma_reader_create(archive, &errp); | |
295 | + | |
296 | + if (!vmar) { | |
297 | + g_error("%s", error_get_pretty(errp)); | |
298 | + } | |
299 | + | |
300 | + VmaDeviceInfo *di = vma_reader_get_device_info(vmar, 1); | |
301 | + if (!di || strcmp((char *)di->devname, "hda") || di->size != size) { | |
302 | + g_error("got wrong device info"); | |
303 | + } | |
304 | + | |
305 | + unlink(TEST_IMG_RESTORE_NAME); | |
306 | + | |
307 | + int flags = BDRV_O_NATIVE_AIO|BDRV_O_RDWR|BDRV_O_CACHE_WB; | |
308 | + | |
309 | + if (bdrv_img_create(TEST_IMG_RESTORE_NAME, "raw", NULL, NULL, NULL, | |
310 | + size, flags)) { | |
311 | + g_error("can't create file %s", TEST_IMG_RESTORE_NAME); | |
312 | + } | |
313 | + | |
314 | + BlockDriverState *bs = NULL; | |
315 | + if (bdrv_file_open(&bs, TEST_IMG_RESTORE_NAME, flags)) { | |
316 | + g_error("can't open file %s", TEST_IMG_RESTORE_NAME); | |
317 | + } | |
318 | + if (vma_reader_register_bs(vmar, 1, bs, false, &errp) < 0) { | |
319 | + g_error("%s", error_get_pretty(errp)); | |
320 | + } | |
321 | + | |
4244016d | 322 | + if (vma_reader_restore(vmar, -1, false, &errp) < 0) { |
5ad5891c DM |
323 | + g_error("restore failed - %s", error_get_pretty(errp)); |
324 | + } | |
325 | + | |
326 | + size_t i; | |
327 | + size_t sectors = size/BDRV_SECTOR_SIZE; | |
328 | + int64_t buf[512/sizeof(int64_t)]; | |
329 | + int64_t buf2[512/sizeof(int64_t)]; | |
330 | + | |
331 | + for (i = 0; i < sectors; i++) { | |
332 | + if (bdrv_read(bs, i, (uint8_t *)buf, 1) != 0) { | |
333 | + g_error("bdrv_read failed"); | |
334 | + } | |
335 | + fill_test_sector(buf2, i); | |
336 | + if (bcmp(buf, buf2, sizeof(buf))) { | |
337 | + g_error("data is different at sector %zd", i); | |
338 | + } | |
339 | + } | |
340 | + | |
341 | + vma_reader_destroy(vmar); | |
342 | + | |
343 | + unlink(TEST_IMG_RESTORE_NAME); | |
344 | +} | |
345 | + | |
346 | +static void prepare_vm_image(const char *filename, size_t sectors) | |
347 | +{ | |
348 | + int fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644); | |
349 | + if (fd < 0) { | |
350 | + g_error("can't open file %s\n", filename); | |
351 | + } | |
352 | + | |
353 | + size_t i; | |
354 | + int64_t buf[512/sizeof(int64_t)]; | |
355 | + | |
356 | + for (i = 0; i < sectors; i++) { | |
357 | + fill_test_sector(buf, i); | |
358 | + | |
359 | + int res = 0; | |
360 | + while (1) { | |
361 | + res = write(fd, buf, sizeof(buf)); | |
362 | + if (!(res < 0 && errno == EINTR)) { | |
363 | + break; | |
364 | + } | |
365 | + } | |
366 | + if (res != sizeof(buf)) { | |
367 | + g_error("can't initialize file %s - %s %d\n", | |
368 | + filename, strerror(errno), res); | |
369 | + } | |
370 | + } | |
371 | + | |
372 | + if (close(fd) != 0) { | |
373 | + g_error("close failed"); | |
374 | + } | |
375 | +} | |
376 | + | |
377 | +static GList *simple_test(BlockDriverState *bs) | |
378 | +{ | |
379 | + GList *cb_list = NULL; | |
380 | + | |
381 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_test1)); | |
382 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_test2)); | |
383 | + | |
384 | + return cb_list; | |
385 | +} | |
386 | + | |
387 | +static GList *random_read_write_test(BlockDriverState *bs) | |
388 | +{ | |
389 | + GList *cb_list = NULL; | |
390 | + | |
391 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_random_read)); | |
392 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_random_read)); | |
393 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_random_write)); | |
394 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_random_write)); | |
395 | + | |
396 | + return cb_list; | |
397 | +} | |
398 | + | |
399 | +static void backup_test(const char *testname, int64_t speed, | |
400 | + GList *(*start_test_cb)(BlockDriverState *bs)) | |
401 | +{ | |
402 | + BlockDriverState *bs = bdrv_new("hda"); | |
403 | + | |
404 | + static int test_counter; | |
405 | + | |
406 | + test_counter++; | |
407 | + | |
408 | + printf("starting test #%d '%s'\n", test_counter, testname); | |
409 | + | |
410 | + const char *filename = TEST_IMG_NAME; | |
411 | + | |
412 | + prepare_vm_image(TEST_IMG_NAME, TEST_IMG_SIZE/BDRV_SECTOR_SIZE); | |
413 | + | |
414 | + int flags = BDRV_O_NATIVE_AIO|BDRV_O_RDWR|BDRV_O_CACHE_WB; | |
415 | + | |
416 | + if (bdrv_open(bs, filename, flags, NULL) < 0) { | |
417 | + g_error("can't open device %s\n", filename); | |
418 | + } | |
419 | + | |
420 | + Error *err = NULL; | |
421 | + uuid_t uuid; | |
422 | + uuid_generate(uuid); | |
423 | + | |
424 | + unlink(TEST_VMA_NAME); | |
425 | + | |
426 | + VmaWriter *vmaw = vma_writer_create(TEST_VMA_NAME, uuid, speed, &err); | |
427 | + if (!vmaw) { | |
428 | + g_error("%s", error_get_pretty(err)); | |
429 | + } | |
430 | + | |
431 | + BackupCB bcb; | |
432 | + bcb.vmaw = vmaw; | |
433 | + bcb.dev_id = vma_writer_register_stream(vmaw, bdrv_get_device_name(bs), | |
434 | + bdrv_getlength(bs)); | |
309874bd DM |
435 | + if (backup_job_create(bs, backup_dump_cb, backup_complete_cb, &bcb) < 0) { |
436 | + g_error("backup_job_create failed"); | |
437 | + } else { | |
438 | + backup_job_start(bs); | |
5ad5891c DM |
439 | + } |
440 | + | |
441 | + request_term = false; | |
442 | + | |
443 | + GList *cb_list = start_test_cb(bs); | |
444 | + | |
445 | + while (1) { | |
446 | + main_loop_wait(false); | |
447 | + | |
448 | + VmaStatus vmastat; | |
449 | + vma_writer_get_status(vmaw, &vmastat); | |
450 | + if (vmastat.closed) { | |
451 | + break; | |
452 | + } | |
453 | + } | |
454 | + | |
455 | + request_term = true; | |
456 | + | |
457 | + while (1) { | |
458 | + GList *l = cb_list; | |
459 | + bool active = 0; | |
460 | + while (l && l->data) { | |
461 | + TestCB *cb = (TestCB *)l->data; | |
462 | + l = g_list_next(l); | |
463 | + if (!cb->finished) { | |
464 | + active = true; | |
465 | + break; | |
466 | + } | |
467 | + } | |
468 | + if (!active) { | |
469 | + DPRINTF("All test coroutines finished\n"); | |
470 | + break; | |
471 | + } | |
472 | + main_loop_wait(false); | |
473 | + } | |
474 | + | |
475 | + /* Make sure all outstanding requests complete */ | |
476 | + bdrv_drain_all(); | |
477 | + | |
478 | + VmaStatus vmastat; | |
479 | + vma_writer_get_status(vmaw, &vmastat); | |
480 | + DPRINTF("statistic %zd %zd\n", vmastat.stream_info[1].size, | |
481 | + vmastat.stream_info[1].transferred); | |
482 | + assert(vmastat.stream_info[1].size == vmastat.stream_info[1].transferred); | |
483 | + | |
484 | + vma_writer_destroy(vmaw); | |
485 | + | |
486 | + bdrv_delete(bs); | |
487 | + | |
488 | + /* start verification */ | |
489 | + verify_archive(TEST_VMA_NAME, TEST_IMG_SIZE); | |
490 | + | |
491 | + bdrv_close_all(); | |
492 | + | |
493 | + unlink(TEST_IMG_NAME); | |
494 | + unlink(TEST_VMA_NAME); | |
495 | + | |
496 | + printf("finish test #%d '%s' OK\n", test_counter, testname); | |
497 | +} | |
498 | + | |
499 | +static void help(void) | |
500 | +{ | |
501 | + const char *help_msg = | |
502 | + "usage: backup-test [options]\n" | |
503 | + "\n" | |
504 | + "backup-test run default regression test (fast)\n" | |
505 | + "backup-test -l run long running test loop (endless)\n" | |
506 | + "\n" | |
507 | + "use option -d to turn on verbose debug output\n" | |
508 | + ; | |
509 | + | |
510 | + printf("%s", help_msg); | |
511 | + exit(1); | |
512 | +} | |
513 | + | |
514 | +int main(int argc, char **argv) | |
515 | +{ | |
516 | + int c; | |
517 | + | |
309874bd DM |
518 | + g_thread_init(NULL); |
519 | + | |
5ad5891c DM |
520 | + for (;;) { |
521 | + c = getopt(argc, argv, "hdl"); | |
522 | + if (c == -1) { | |
523 | + break; | |
524 | + } | |
525 | + switch (c) { | |
526 | + case '?': | |
527 | + case 'h': | |
528 | + help(); | |
529 | + break; | |
530 | + case 'd': | |
531 | + opt_debug = 1; | |
532 | + break; | |
533 | + case 'l': | |
534 | + opt_loop = 1; | |
535 | + break; | |
536 | + default: | |
537 | + g_assert_not_reached(); | |
538 | + } | |
539 | + } | |
540 | + | |
541 | + memset(buf_sec_pattern_cd, 0xcd, sizeof(buf_sec_pattern_cd)); | |
542 | + memset(buf_sec_pattern_32, 0x32, sizeof(buf_sec_pattern_32)); | |
543 | + | |
544 | + srand(1234); | |
545 | + | |
546 | + /* ignore SIGPIPE */ | |
547 | + struct sigaction act; | |
548 | + sigfillset(&act.sa_mask); | |
549 | + act.sa_flags = 0; | |
550 | + act.sa_handler = SIG_IGN; | |
551 | + sigaction(SIGPIPE, &act, NULL); | |
552 | + | |
553 | + qemu_init_main_loop(); | |
554 | + | |
555 | + bdrv_init(); | |
556 | + | |
557 | + if (opt_loop) { /* endless test loop */ | |
558 | + while (1) { | |
559 | + RUN_TEST(random_read_write_test, 0); | |
560 | + } | |
561 | + return 0; | |
562 | + } | |
563 | + | |
564 | + if (opt_debug) { /* run simple test (rate limited) */ | |
565 | + RUN_TEST(simple_test, 1024*1024); | |
566 | + return 0; | |
567 | + } | |
568 | + | |
569 | + /* run default regression tests at full speed */ | |
570 | + | |
571 | + RUN_TEST(simple_test, 0); | |
572 | + RUN_TEST(random_read_write_test, 0); | |
573 | + | |
574 | + return 0; | |
575 | +} | |
576 | -- | |
577 | 1.7.2.5 | |
578 |