From: Denis V. Lunev <[email protected]> The two backing images are raw and are grown with ftruncate(), one to 30 MiB and one to 4 GiB, so on a host where sparse files are not free the test skips and the BIOS geometry goes untested.
The override tests already build their images with qemu-img, so use the same route here. The convert and resize pair moves into mkqcow2_with_mbr(), which both users call and which reports a failed qemu-img rather than asserting. setup_mbr() stamps the MBR by rebuilding the image, that being the only way to reach sector 0 of a qcow2 from outside QEMU. Only the setup running before any test can skip, so the rest keep asserting. Without qemu-img the images stay raw. Peak scratch space drops from 4126 MiB to 1.5 MiB. Cc: John Snow <[email protected]> Cc: Thomas Huth <[email protected]> Signed-off-by: Denis V. Lunev <[email protected]> --- tests/qtest/hd-geo-test.c | 129 +++++++++++++++++++++++++------------- 1 file changed, 86 insertions(+), 43 deletions(-) diff --git a/tests/qtest/hd-geo-test.c b/tests/qtest/hd-geo-test.c index e3b4a4db31..160bdc7216 100644 --- a/tests/qtest/hd-geo-test.c +++ b/tests/qtest/hd-geo-test.c @@ -25,9 +25,69 @@ #define ARGV_SIZE 256 +#define MBR_SIZE 512 + +static const char *imgfmt = "raw"; + +static bool mkqcow2_with_mbr(const char *path, const uint8_t *mbr, + uint64_t size) +{ + g_autoptr(GError) error = NULL; + g_autofree char *raw_path = NULL; + char cmd[100 + 2 * PATH_MAX]; + char *qemu_img_path; + char *qemu_img_abs_path = NULL; + bool ok = false; + int fd, ret; + + fd = g_file_open_tmp("qtest.XXXXXX", &raw_path, &error); + if (fd < 0) { + g_test_message("Could not create a temporary file: %s", + error->message); + return false; + } + ret = write(fd, mbr, MBR_SIZE); + g_assert(ret == MBR_SIZE); + close(fd); + + qemu_img_path = getenv("QTEST_QEMU_IMG"); + g_assert(qemu_img_path); + qemu_img_abs_path = realpath(qemu_img_path, NULL); + g_assert(qemu_img_abs_path); + + ret = snprintf(cmd, sizeof(cmd), + "%s convert -f raw -O qcow2 %s %s > /dev/null", + qemu_img_abs_path, + raw_path, path); + g_assert((0 < ret) && (ret <= sizeof(cmd))); + if (system(cmd) != 0) { + g_test_message("Could not create %s with qemu-img", path); + goto out; + } + + ret = snprintf(cmd, sizeof(cmd), + "%s resize %s %" PRIu64 " > /dev/null", + qemu_img_abs_path, + path, size); + g_assert((0 < ret) && (ret <= sizeof(cmd))); + if (system(cmd) != 0) { + g_test_message("Could not size %s with qemu-img", path); + goto out; + } + + ok = true; + +out: + free(qemu_img_abs_path); + unlink(raw_path); + + return ok; +} + static char *create_test_img(int secs) { g_autoptr(GError) error = NULL; + uint8_t blank_mbr[MBR_SIZE] = {}; char *template; int fd, ret, err; @@ -38,6 +98,16 @@ static char *create_test_img(int secs) return NULL; } + if (!strcmp(imgfmt, "qcow2")) { + close(fd); + if (!mkqcow2_with_mbr(template, blank_mbr, (uint64_t)secs * 512)) { + unlink(template); + g_free(template); + return NULL; + } + return template; + } + ret = ftruncate(fd, (off_t)secs * 512); err = errno; close(fd); @@ -207,7 +277,7 @@ static void setup_mbr(int img_idx, MBRcontents mbr) /* chs 0,1,1 (lba 63) to chs 7,15,63 (8001 sectors) */ 0x80, 1, 1, 0, 6, 15, 63, 7, 63, 0, 0, 0, 0x41, 0x1F, 0, 0, }; - uint8_t buf[512]; + uint8_t buf[MBR_SIZE]; int fd, ret; memset(buf, 0, sizeof(buf)); @@ -218,6 +288,12 @@ static void setup_mbr(int img_idx, MBRcontents mbr) memcpy(buf + 0x1BE, mbr == mbr_lba ? part_lba : part_chs, 16); } + if (!strcmp(imgfmt, "qcow2")) { + g_assert_true(mkqcow2_with_mbr(img_file_name[img_idx], buf, + (uint64_t)img_secs[img_idx] * 512)); + return; + } + fd = open(img_file_name[img_idx], O_WRONLY); g_assert(fd >= 0); ret = write(fd, buf, sizeof(buf)); @@ -237,7 +313,8 @@ static int setup_ide(int argc, char *argv[], int argv_sz, if (img_secs[img_idx] >= 0) { setup_mbr(img_idx, mbr); - s3 = g_strdup_printf(",format=raw,file=%s", img_file_name[img_idx]); + s3 = g_strdup_printf(",format=%s,file=%s", imgfmt, + img_file_name[img_idx]); } else { s3 = g_strdup(",media=cdrom"); } @@ -431,15 +508,10 @@ static MBRpartitions empty_mbr = { {false, 0, 0, 0, 0, 0, 0, 0, 0}, static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors) { - g_autofree char *raw_path = NULL; char *qcow2_path; - char cmd[100 + 2 * PATH_MAX]; - uint8_t buf[512] = {}; - int i, ret, fd, offset; - uint64_t qcow2_size = sectors * 512; + uint8_t buf[MBR_SIZE] = {}; + int i, fd, offset; uint8_t status, parttype, head, sector, cyl; - char *qemu_img_path; - char *qemu_img_abs_path; offset = 0xbe; @@ -476,44 +548,11 @@ static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors) offset += 0x10; } - fd = g_file_open_tmp("qtest.XXXXXX", &raw_path, NULL); - g_assert(fd >= 0); - close(fd); - - fd = open(raw_path, O_WRONLY); - g_assert(fd >= 0); - ret = write(fd, buf, sizeof(buf)); - g_assert(ret == sizeof(buf)); - close(fd); - fd = g_file_open_tmp("qtest.XXXXXX", &qcow2_path, NULL); g_assert(fd >= 0); close(fd); - qemu_img_path = getenv("QTEST_QEMU_IMG"); - g_assert(qemu_img_path); - qemu_img_abs_path = realpath(qemu_img_path, NULL); - g_assert(qemu_img_abs_path); - - ret = snprintf(cmd, sizeof(cmd), - "%s convert -f raw -O qcow2 %s %s > /dev/null", - qemu_img_abs_path, - raw_path, qcow2_path); - g_assert((0 < ret) && (ret <= sizeof(cmd))); - ret = system(cmd); - g_assert(ret == 0); - - ret = snprintf(cmd, sizeof(cmd), - "%s resize %s %" PRIu64 " > /dev/null", - qemu_img_abs_path, - qcow2_path, qcow2_size); - g_assert((0 < ret) && (ret <= sizeof(cmd))); - ret = system(cmd); - g_assert(ret == 0); - - free(qemu_img_abs_path); - - unlink(raw_path); + g_assert_true(mkqcow2_with_mbr(qcow2_path, buf, sectors * 512)); return qcow2_path; } @@ -1064,6 +1103,10 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); + if (have_qemu_img()) { + imgfmt = "qcow2"; + } + for (i = 0; i < backend_last; i++) { if (img_secs[i] >= 0) { img_file_name[i] = create_test_img(img_secs[i]); -- 2.53.0
