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