1483
unlink(img);
1484
}
1485
1486
+/* A migration stream holds NUL bytes, so this cannot be a string search */
1487
+static char *ide_stream_find(char *stream, gsize len, const char *name)
1488
+{
1489
+ gsize name_len = strlen(name);
1490
+ gsize i;
1491
+
1492
+ if (len < name_len) {
1493
+ return NULL;
1494
+ }
1495
+ for (i = 0; i <= len - name_len; i++) {
1496
+ if (memcmp(stream + i, name, name_len) == 0) {
1497
+ return stream + i;
1498
+ }
1499
+ }
1500
+
1501
+ return NULL;
1502
+}
1503
+
1504
+/* A translation no command could have selected has to be refused on load */
1505
+static void test_migrate_chs_rejected(void)
1506
+{
1507
+ const char *name = "ide_drive/chs_translation";
1508
+ QTestState *src, *dst;
1509
+ QPCIDevice *dev;
1510
+ QPCIBar bmdma_bar, ide_bar;
1511
+ g_autofree char *path = NULL;
1512
+ g_autofree char *uri = NULL;
1513
+ g_autofree char *dst_args = NULL;
1514
+ g_autofree char *stream = NULL;
1515
+ char *subsection;
1516
+ gsize len;
1517
+ int fd;
1518
+
1519
+ fd = g_file_open_tmp("qtest-ide-stream.XXXXXX", &path, NULL);
1520
+ g_assert(fd >= 0);
1521
+ close(fd);
1522
+ uri = g_strdup_printf("file:%s", path);
1523
+
1524
+ src = ide_test_start(
1525
+ "-blockdev driver=file,node-name=hda,filename=%s "
1526
+ "-device ide-hd,drive=hda,bus=ide.0,unit=0 ",
1527
+ tmp_path[0]);
1528
+ dev = get_pci_device(src, &bmdma_bar, &ide_bar);
1529
+
1530
+ ide_set_translation(dev, ide_bar, 8, 32);
1531
+ qtest_qmp_assert_success(src, "{ 'execute': 'migrate',"
1532
+ " 'arguments': { 'uri': %s } }", uri);
1533
+ qtest_qmp_eventwait(src, "STOP");
1534
+ ide_migration_wait(src, "completed");
1535
+ free_pci_device(dev);
1536
+ ide_test_quit(src);
1537
+
1538
+ /*
1539
+ * Behind the name come version, heads and sectors, each big endian 32 bit.
1540
+ * The name recurs in the description at the end of the stream, so the
1541
+ * first match is the one carrying data.
1542
+ */
1543
+ g_assert(g_file_get_contents(path, &stream, &len, NULL));
1544
+ subsection = ide_stream_find(stream, len, name);
1545
+ g_assert(subsection);
1546
+ g_assert_cmpint(subsection - stream + strlen(name) + 12, <=, len);
1547
+ memset(subsection + strlen(name) + 8, 0, 4);
1548
+ g_assert(g_file_set_contents(path, stream, len, NULL));
1549
+
1550
+ dst_args = g_strdup_printf(
1551
+ "-machine pc "
1552
+ "-blockdev driver=file,node-name=hda,filename=%s "
1553
+ "-device ide-hd,drive=hda,bus=ide.0,unit=0 -incoming defer",
1554
+ tmp_path[0]);
1555
+ dst = qtest_init(dst_args);
1556
+
1557
+ qtest_qmp_assert_success(dst, "{ 'execute': 'migrate-incoming',"
1558
+ " 'arguments': { 'uri': %s,"
1559
+ " 'exit-on-error': false } }", uri);
1560
+ ide_migration_wait(dst, "failed");
1561
+
1562
+ qtest_quit(dst);
1563
+ unlink(path);
1564
+}
1565
+
1566
static void test_cdrom_pio(void)
1567
{
1568
cdrom_read_impl(1, CDROM_PIO);
1638
qtest_add_func("/ide/migration/chs_translation",
1639
test_migrate_chs_translation);
1640
qtest_add_func("/ide/migration/chs_snapshot", test_migrate_chs_snapshot);
1641
+ qtest_add_func("/ide/migration/chs_rejected", test_migrate_chs_rejected);
1642
1643
qtest_add_func("/ide/identify", test_identify);
1644