[PATCH 11/15] tests/qtest/ide-test: cover a rejected CHS translation in the stream
"Denis V. Lunev" <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu,gmane.comp.emulators.qemu.block |
|---|---|
| Message-ID | <[email protected]> |
From: Denis V. Lunev <[email protected]> ide_drive_post_load() refuses a logical CHS translation that no command could have selected, as the fields are a divisor in ide_set_sector() and a factor in ide_get_sector(). Nothing exercised that, a fixed QEMU having no way to produce such a stream. Migrate a guest that selected a translation to a file, replace the number of sectors per logical track in the subsection with a zero, and let a destination read the result back. The load has to fail rather than take the value, so the destination is asked not to exit on a failed incoming migration and its migration status is what the test looks at. Cc: John Snow <[email protected]> Cc: Peter Maydell <[email protected]> Signed-off-by: Denis V. Lunev <[email protected]> --- tests/qtest/ide-test.c | 81 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c index 19e9734d3c..4fa58ac525 100644 --- a/tests/qtest/ide-test.c +++ b/tests/qtest/ide-test.c @@ -1483,6 +1483,86 @@ static void test_migrate_chs_snapshot(void) unlink(img); } +/* A migration stream holds NUL bytes, so this cannot be a string search */ +static char *ide_stream_find(char *stream, gsize len, const char *name) +{ + gsize name_len = strlen(name); + gsize i; + + if (len < name_len) { + return NULL; + } + for (i = 0; i <= len - name_len; i++) { + if (memcmp(stream + i, name, name_len) == 0) { + return stream + i; + } + } + + return NULL; +} + +/* A translation no command could have selected has to be refused on load */ +static void test_migrate_chs_rejected(void) +{ + const char *name = "ide_drive/chs_translation"; + QTestState *src, *dst; + QPCIDevice *dev; + QPCIBar bmdma_bar, ide_bar; + g_autofree char *path = NULL; + g_autofree char *uri = NULL; + g_autofree char *dst_args = NULL; + g_autofree char *stream = NULL; + char *subsection; + gsize len; + int fd; + + fd = g_file_open_tmp("qtest-ide-stream.XXXXXX", &path, NULL); + g_assert(fd >= 0); + close(fd); + uri = g_strdup_printf("file:%s", path); + + src = ide_test_start( + "-blockdev driver=file,node-name=hda,filename=%s " + "-device ide-hd,drive=hda,bus=ide.0,unit=0 ", + tmp_path[0]); + dev = get_pci_device(src, &bmdma_bar, &ide_bar); + + ide_set_translation(dev, ide_bar, 8, 32); + qtest_qmp_assert_success(src, "{ 'execute': 'migrate'," + " 'arguments': { 'uri': %s } }", uri); + qtest_qmp_eventwait(src, "STOP"); + ide_migration_wait(src, "completed"); + free_pci_device(dev); + ide_test_quit(src); + + /* + * Behind the name come version, heads and sectors, each big endian 32 bit. + * The name recurs in the description at the end of the stream, so the + * first match is the one carrying data. + */ + g_assert(g_file_get_contents(path, &stream, &len, NULL)); + subsection = ide_stream_find(stream, len, name); + g_assert(subsection); + g_assert_cmpint(subsection - stream + strlen(name) + 12, <=, len); + memset(subsection + strlen(name) + 8, 0, 4); + g_assert(g_file_set_contents(path, stream, len, NULL)); + + dst_args = g_strdup_printf( + "-machine pc " + "-blockdev driver=file,node-name=hda,filename=%s " + "-device ide-hd,drive=hda,bus=ide.0,unit=0 -incoming defer", + tmp_path[0]); + dst = qtest_init(dst_args); + + qtest_qmp_assert_success(dst, "{ 'execute': 'migrate-incoming'," + " 'arguments': { 'uri': %s," + " 'exit-on-error': false } }", uri); + ide_migration_wait(dst, "failed"); + + qtest_quit(dst); + unlink(path); +} + static void test_cdrom_pio(void) { cdrom_read_impl(1, CDROM_PIO); @@ -1558,6 +1638,7 @@ int main(int argc, char **argv) qtest_add_func("/ide/migration/chs_translation", test_migrate_chs_translation); qtest_add_func("/ide/migration/chs_snapshot", test_migrate_chs_snapshot); + qtest_add_func("/ide/migration/chs_rejected", test_migrate_chs_rejected); qtest_add_func("/ide/identify", test_identify); -- 2.53.0