I'm about to add fields to virStorageFileMetadata, which means also adding fields to the testFileData struct in virstoragetest. Alas, adding even one pointer on an x86_64 machine gave me a dreaded compiler error: virstoragetest.c:712:1: error: the frame size of 4208 bytes is larger than 4096 bytes [-Werror=frame-larger-than=] After some experimentation, I realized that each test was creating yet another testChainData (which contains testFileData) on the stack; forcing the reuse of one of these structures instead of creating a fresh one each time drastically reduces the size requirements. While at it, I also got rid of a lot of intermediate structs, with some macro magic that lets me directly build up the destination chains inline. * tests/virstoragetest.c (mymain): Rewrite TEST_ONE_CHAIN to reuse the same struct for each test, and to take the data inline rather than via intermediate variables. (testChainData): Use bounded array of pointers instead of unlimited array of struct. (testStorageChain): Reflect struct change. Signed-off-by: Eric Blake <eblake@xxxxxxxxxx> --- tests/virstoragetest.c | 167 ++++++++++++++++++++++++------------------------- 1 file changed, 81 insertions(+), 86 deletions(-) diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 9a3b3a3..efd920a 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -218,7 +218,7 @@ struct testChainData { const char *start; enum virStorageFileFormat format; - const testFileData *files; + const testFileData *files[5]; int nfiles; unsigned int flags; }; @@ -267,13 +267,13 @@ testStorageChain(const void *args) if (virAsprintf(&expect, "store:%s\nraw:%s\ndirectory:%s\nother:%d %d %lld %d", - NULLSTR(data->files[i].expBackingStore), - NULLSTR(data->files[i].expBackingStoreRaw), - NULLSTR(data->files[i].expDirectory), - data->files[i].expFormat, - data->files[i].expIsFile, - data->files[i].expCapacity, - data->files[i].expEncrypted) < 0 || + NULLSTR(data->files[i]->expBackingStore), + NULLSTR(data->files[i]->expBackingStoreRaw), + NULLSTR(data->files[i]->expDirectory), + data->files[i]->expFormat, + data->files[i]->expIsFile, + data->files[i]->expCapacity, + data->files[i]->expEncrypted) < 0 || virAsprintf(&actual, "store:%s\nraw:%s\ndirectory:%s\nother:%d %d %lld %d", NULLSTR(elt->backingStore), @@ -312,29 +312,42 @@ mymain(void) { int ret; virCommandPtr cmd = NULL; + struct testChainData data; /* Prep some files with qemu-img; if that is not found on PATH, or * if it lacks support for qcow2 and qed, skip this test. */ if ((ret = testPrepImages()) != 0) return ret; -#define TEST_ONE_CHAIN(id, start, format, chain, flags) \ +#define TEST_ONE_CHAIN(id, start, format, flags, ...) \ do { \ - struct testChainData data = { \ - start, format, chain, ARRAY_CARDINALITY(chain), flags, \ + size_t i; \ + memset(&data, 0, sizeof(data)); \ + data = (struct testChainData){ \ + start, format, { __VA_ARGS__ }, 0, flags, \ }; \ + for (i = 0; i < ARRAY_CARDINALITY(data.files); i++) \ + if (data.files[i]) \ + data.nfiles++; \ if (virtTestRun("Storage backing chain " id, \ testStorageChain, &data) < 0) \ ret = -1; \ } while (0) +#define VIR_FLATTEN_2(...) __VA_ARGS__ +#define VIR_FLATTEN_1(_1) VIR_FLATTEN_2 _1 + #define TEST_CHAIN(id, relstart, absstart, format, chain1, flags1, \ chain2, flags2, chain3, flags3, chain4, flags4) \ do { \ - TEST_ONE_CHAIN(#id "a", relstart, format, chain1, flags1); \ - TEST_ONE_CHAIN(#id "b", relstart, format, chain2, flags2); \ - TEST_ONE_CHAIN(#id "c", absstart, format, chain3, flags3); \ - TEST_ONE_CHAIN(#id "d", absstart, format, chain4, flags4); \ + TEST_ONE_CHAIN(#id "a", relstart, format, flags1, \ + VIR_FLATTEN_1(chain1)); \ + TEST_ONE_CHAIN(#id "b", relstart, format, flags2, \ + VIR_FLATTEN_1(chain2)); \ + TEST_ONE_CHAIN(#id "c", absstart, format, flags3, \ + VIR_FLATTEN_1(chain3)); \ + TEST_ONE_CHAIN(#id "d", absstart, format, flags4, \ + VIR_FLATTEN_1(chain4)); \ } while (0) /* Expected details about files in chains */ @@ -454,36 +467,31 @@ mymain(void) /* The actual tests, in several groups. */ /* Missing file */ - const testFileData chain0[] = { }; - TEST_ONE_CHAIN("0", "bogus", VIR_STORAGE_FILE_RAW, chain0, EXP_FAIL); + TEST_ONE_CHAIN("0", "bogus", VIR_STORAGE_FILE_RAW, EXP_FAIL); /* Raw image, whether with right format or no specified format */ - const testFileData chain1[] = { raw }; TEST_CHAIN(1, "raw", absraw, VIR_STORAGE_FILE_RAW, - chain1, EXP_PASS, - chain1, ALLOW_PROBE | EXP_PASS, - chain1, EXP_PASS, - chain1, ALLOW_PROBE | EXP_PASS); + (&raw), EXP_PASS, + (&raw), ALLOW_PROBE | EXP_PASS, + (&raw), EXP_PASS, + (&raw), ALLOW_PROBE | EXP_PASS); TEST_CHAIN(2, "raw", absraw, VIR_STORAGE_FILE_AUTO, - chain1, EXP_PASS, - chain1, ALLOW_PROBE | EXP_PASS, - chain1, EXP_PASS, - chain1, ALLOW_PROBE | EXP_PASS); + (&raw), EXP_PASS, + (&raw), ALLOW_PROBE | EXP_PASS, + (&raw), EXP_PASS, + (&raw), ALLOW_PROBE | EXP_PASS); /* Qcow2 file with relative raw backing, format provided */ - const testFileData chain3a[] = { qcow2_relback_relstart, raw }; - const testFileData chain3c[] = { qcow2_relback_absstart, raw }; - const testFileData chain4a[] = { raw }; TEST_CHAIN(3, "qcow2", absqcow2, VIR_STORAGE_FILE_QCOW2, - chain3a, EXP_PASS, - chain3a, ALLOW_PROBE | EXP_PASS, - chain3c, EXP_PASS, - chain3c, ALLOW_PROBE | EXP_PASS); + (&qcow2_relback_relstart, &raw), EXP_PASS, + (&qcow2_relback_relstart, &raw), ALLOW_PROBE | EXP_PASS, + (&qcow2_relback_absstart, &raw), EXP_PASS, + (&qcow2_relback_absstart, &raw), ALLOW_PROBE | EXP_PASS); TEST_CHAIN(4, "qcow2", absqcow2, VIR_STORAGE_FILE_AUTO, - chain4a, EXP_PASS, - chain3a, ALLOW_PROBE | EXP_PASS, - chain4a, EXP_PASS, - chain3c, ALLOW_PROBE | EXP_PASS); + (&raw), EXP_PASS, + (&qcow2_relback_relstart, &raw), ALLOW_PROBE | EXP_PASS, + (&raw), EXP_PASS, + (&qcow2_relback_absstart, &raw), ALLOW_PROBE | EXP_PASS); /* Rewrite qcow2 file to use absolute backing name */ virCommandFree(cmd); @@ -493,26 +501,23 @@ mymain(void) ret = -1; /* Qcow2 file with raw as absolute backing, backing format provided */ - const testFileData chain5[] = { qcow2_absback, raw }; - const testFileData chain6[] = { raw }; TEST_CHAIN(5, "qcow2", absqcow2, VIR_STORAGE_FILE_QCOW2, - chain5, EXP_PASS, - chain5, ALLOW_PROBE | EXP_PASS, - chain5, EXP_PASS, - chain5, ALLOW_PROBE | EXP_PASS); + (&qcow2_absback, &raw), EXP_PASS, + (&qcow2_absback, &raw), ALLOW_PROBE | EXP_PASS, + (&qcow2_absback, &raw), EXP_PASS, + (&qcow2_absback, &raw), ALLOW_PROBE | EXP_PASS); TEST_CHAIN(6, "qcow2", absqcow2, VIR_STORAGE_FILE_AUTO, - chain6, EXP_PASS, - chain5, ALLOW_PROBE | EXP_PASS, - chain6, EXP_PASS, - chain5, ALLOW_PROBE | EXP_PASS); + (&raw), EXP_PASS, + (&qcow2_absback, &raw), ALLOW_PROBE | EXP_PASS, + (&raw), EXP_PASS, + (&qcow2_absback, &raw), ALLOW_PROBE | EXP_PASS); /* Wrapped file access */ - const testFileData chain7[] = { wrap, qcow2_absback, raw }; TEST_CHAIN(7, "wrap", abswrap, VIR_STORAGE_FILE_QCOW2, - chain7, EXP_PASS, - chain7, ALLOW_PROBE | EXP_PASS, - chain7, EXP_PASS, - chain7, ALLOW_PROBE | EXP_PASS); + (&wrap, &qcow2_absback, &raw), EXP_PASS, + (&wrap, &qcow2_absback, &raw), ALLOW_PROBE | EXP_PASS, + (&wrap, &qcow2_absback, &raw), EXP_PASS, + (&wrap, &qcow2_absback, &raw), ALLOW_PROBE | EXP_PASS); /* Rewrite qcow2 and wrap file to omit backing file type */ virCommandFree(cmd); @@ -528,13 +533,11 @@ mymain(void) ret = -1; /* Qcow2 file with raw as absolute backing, backing format omitted */ - const testFileData chain8a[] = { wrap_as_raw, raw }; - const testFileData chain8b[] = { wrap_as_probe, qcow2_as_probe, raw }; TEST_CHAIN(8, "wrap", abswrap, VIR_STORAGE_FILE_QCOW2, - chain8a, EXP_PASS, - chain8b, ALLOW_PROBE | EXP_PASS, - chain8a, EXP_PASS, - chain8b, ALLOW_PROBE | EXP_PASS); + (&wrap_as_raw, &raw), EXP_PASS, + (&wrap_as_probe, &qcow2_as_probe, &raw), ALLOW_PROBE | EXP_PASS, + (&wrap_as_raw, &raw), EXP_PASS, + (&wrap_as_probe, &qcow2_as_probe, &raw), ALLOW_PROBE | EXP_PASS); /* Rewrite qcow2 to a missing backing file, with backing type */ virCommandFree(cmd); @@ -545,12 +548,11 @@ mymain(void) ret = -1; /* Qcow2 file with missing backing file but specified type */ - const testFileData chain9[] = { qcow2_bogus }; TEST_CHAIN(9, "qcow2", absqcow2, VIR_STORAGE_FILE_QCOW2, - chain9, EXP_WARN, - chain9, ALLOW_PROBE | EXP_WARN, - chain9, EXP_WARN, - chain9, ALLOW_PROBE | EXP_WARN); + (&qcow2_bogus), EXP_WARN, + (&qcow2_bogus), ALLOW_PROBE | EXP_WARN, + (&qcow2_bogus), EXP_WARN, + (&qcow2_bogus), ALLOW_PROBE | EXP_WARN); /* Rewrite qcow2 to a missing backing file, without backing type */ virCommandFree(cmd); @@ -560,12 +562,11 @@ mymain(void) ret = -1; /* Qcow2 file with missing backing file and no specified type */ - const testFileData chain10[] = { qcow2_bogus }; TEST_CHAIN(10, "qcow2", absqcow2, VIR_STORAGE_FILE_QCOW2, - chain10, EXP_WARN, - chain10, ALLOW_PROBE | EXP_WARN, - chain10, EXP_WARN, - chain10, ALLOW_PROBE | EXP_WARN); + (&qcow2_bogus), EXP_WARN, + (&qcow2_bogus), ALLOW_PROBE | EXP_WARN, + (&qcow2_bogus), EXP_WARN, + (&qcow2_bogus), ALLOW_PROBE | EXP_WARN); /* Rewrite qcow2 to use an nbd: protocol as backend */ virCommandFree(cmd); @@ -576,21 +577,18 @@ mymain(void) ret = -1; /* Qcow2 file with backing protocol instead of file */ - const testFileData chain11[] = { qcow2_protocol }; TEST_CHAIN(11, "qcow2", absqcow2, VIR_STORAGE_FILE_QCOW2, - chain11, EXP_PASS, - chain11, ALLOW_PROBE | EXP_PASS, - chain11, EXP_PASS, - chain11, ALLOW_PROBE | EXP_PASS); + (&qcow2_protocol), EXP_PASS, + (&qcow2_protocol), ALLOW_PROBE | EXP_PASS, + (&qcow2_protocol), EXP_PASS, + (&qcow2_protocol), ALLOW_PROBE | EXP_PASS); /* qed file */ - const testFileData chain12a[] = { raw }; - const testFileData chain12b[] = { qed, raw }; TEST_CHAIN(12, "qed", absqed, VIR_STORAGE_FILE_AUTO, - chain12a, EXP_PASS, - chain12b, ALLOW_PROBE | EXP_PASS, - chain12a, EXP_PASS, - chain12b, ALLOW_PROBE | EXP_PASS); + (&raw), EXP_PASS, + (&qed, &raw), ALLOW_PROBE | EXP_PASS, + (&raw), EXP_PASS, + (&qed, &raw), ALLOW_PROBE | EXP_PASS); #ifdef HAVE_SYMLINK /* Rewrite qcow2 and wrap file to use backing names relative to a @@ -609,15 +607,12 @@ mymain(void) ret = -1; /* Behavior of symlinks to qcow2 with relative backing files */ - const testFileData chain13a[] = { link2_rel, link1_rel, raw }; - const testFileData chain13c[] = { link2_abs, link1_abs, raw }; TEST_CHAIN(13, "sub/link2", abslink2, VIR_STORAGE_FILE_QCOW2, - chain13a, EXP_PASS, - chain13a, ALLOW_PROBE | EXP_PASS, - chain13c, EXP_PASS, - chain13c, ALLOW_PROBE | EXP_PASS); + (&link2_rel, &link1_rel, &raw), EXP_PASS, + (&link2_rel, &link1_rel, &raw), ALLOW_PROBE | EXP_PASS, + (&link2_abs, &link1_abs, &raw), EXP_PASS, + (&link2_abs, &link1_abs, &raw), ALLOW_PROBE | EXP_PASS); #endif - /* Final cleanup */ testCleanupImages(); virCommandFree(cmd); -- 1.9.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list