2 * Hard disk geometry test cases.
4 * Copyright (c) 2012 Red Hat Inc.
7 * Markus Armbruster <armbru@redhat.com>,
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
14 * Covers only IDE and tests only CMOS contents. Better than nothing.
15 * Improvements welcome.
18 #include "qemu/osdep.h"
19 #include "qemu/bswap.h"
20 #include "qapi/qmp/qlist.h"
22 #include "libqos/fw_cfg.h"
23 #include "libqos/libqos.h"
24 #include "standard-headers/linux/qemu_fw_cfg.h"
28 static char *create_test_img(int secs
)
33 fd
= g_file_open_tmp("qtest.XXXXXX", &template, NULL
);
35 ret
= ftruncate(fd
, (off_t
)secs
* 512);
47 int cyls
, heads
, secs
, trans
;
51 mbr_blank
, mbr_lba
, mbr_chs
,
56 /* order is relevant */
57 backend_small
, backend_large
, backend_empty
,
61 static const int img_secs
[backend_last
] = {
62 [backend_small
] = 61440,
63 [backend_large
] = 8388608,
67 static const CHST hd_chst
[backend_last
][mbr_last
] = {
69 [mbr_blank
] = { 60, 16, 63, 0 },
70 [mbr_lba
] = { 60, 16, 63, 2 },
71 [mbr_chs
] = { 60, 16, 63, 0 }
74 [mbr_blank
] = { 8322, 16, 63, 1 },
75 [mbr_lba
] = { 8322, 16, 63, 1 },
76 [mbr_chs
] = { 8322, 16, 63, 0 }
80 static char *img_file_name
[backend_last
];
82 static const CHST
*cur_ide
[4];
84 static bool is_hd(const CHST
*expected_chst
)
86 return expected_chst
&& expected_chst
->cyls
;
89 static void test_cmos_byte(QTestState
*qts
, int reg
, int expected
)
91 enum { cmos_base
= 0x70 };
94 qtest_outb(qts
, cmos_base
+ 0, reg
);
95 actual
= qtest_inb(qts
, cmos_base
+ 1);
96 g_assert(actual
== expected
);
99 static void test_cmos_bytes(QTestState
*qts
, int reg0
, int n
,
104 for (i
= 0; i
< 9; i
++) {
105 test_cmos_byte(qts
, reg0
+ i
, expected
[i
]);
109 static void test_cmos_disk_data(QTestState
*qts
)
111 test_cmos_byte(qts
, 0x12,
112 (is_hd(cur_ide
[0]) ? 0xf0 : 0) |
113 (is_hd(cur_ide
[1]) ? 0x0f : 0));
116 static void test_cmos_drive_cyl(QTestState
*qts
, int reg0
,
117 const CHST
*expected_chst
)
119 if (is_hd(expected_chst
)) {
120 int c
= expected_chst
->cyls
;
121 int h
= expected_chst
->heads
;
122 int s
= expected_chst
->secs
;
123 uint8_t expected_bytes
[9] = {
124 c
& 0xff, c
>> 8, h
, 0xff, 0xff, 0xc0 | ((h
> 8) << 3),
127 test_cmos_bytes(qts
, reg0
, 9, expected_bytes
);
131 for (i
= 0; i
< 9; i
++) {
132 test_cmos_byte(qts
, reg0
+ i
, 0);
137 static void test_cmos_drive1(QTestState
*qts
)
139 test_cmos_byte(qts
, 0x19, is_hd(cur_ide
[0]) ? 47 : 0);
140 test_cmos_drive_cyl(qts
, 0x1b, cur_ide
[0]);
143 static void test_cmos_drive2(QTestState
*qts
)
145 test_cmos_byte(qts
, 0x1a, is_hd(cur_ide
[1]) ? 47 : 0);
146 test_cmos_drive_cyl(qts
, 0x24, cur_ide
[1]);
149 static void test_cmos_disktransflag(QTestState
*qts
)
154 for (i
= 0; i
< ARRAY_SIZE(cur_ide
); i
++) {
155 if (is_hd(cur_ide
[i
])) {
156 val
|= cur_ide
[i
]->trans
<< (2 * i
);
159 test_cmos_byte(qts
, 0x39, val
);
162 static void test_cmos(QTestState
*qts
)
164 test_cmos_disk_data(qts
);
165 test_cmos_drive1(qts
);
166 test_cmos_drive2(qts
);
167 test_cmos_disktransflag(qts
);
170 static int append_arg(int argc
, char *argv
[], int argv_sz
, char *arg
)
172 g_assert(argc
+ 1 < argv_sz
);
178 static int setup_common(char *argv
[], int argv_sz
)
181 memset(cur_ide
, 0, sizeof(cur_ide
));
182 new_argc
= append_arg(0, argv
, argv_sz
,
183 g_strdup("-nodefaults"));
184 new_argc
= append_arg(new_argc
, argv
, argv_sz
,
185 g_strdup("-machine"));
186 new_argc
= append_arg(new_argc
, argv
, argv_sz
,
191 static void setup_mbr(int img_idx
, MBRcontents mbr
)
193 static const uint8_t part_lba
[16] = {
194 /* chs 0,1,1 (lba 63) to chs 0,127,63 (8001 sectors) */
195 0x80, 1, 1, 0, 6, 127, 63, 0, 63, 0, 0, 0, 0x41, 0x1F, 0, 0,
197 static const uint8_t part_chs
[16] = {
198 /* chs 0,1,1 (lba 63) to chs 7,15,63 (8001 sectors) */
199 0x80, 1, 1, 0, 6, 15, 63, 7, 63, 0, 0, 0, 0x41, 0x1F, 0, 0,
204 memset(buf
, 0, sizeof(buf
));
206 if (mbr
!= mbr_blank
) {
209 memcpy(buf
+ 0x1BE, mbr
== mbr_lba
? part_lba
: part_chs
, 16);
212 fd
= open(img_file_name
[img_idx
], O_WRONLY
);
214 ret
= write(fd
, buf
, sizeof(buf
));
215 g_assert(ret
== sizeof(buf
));
219 static int setup_ide(int argc
, char *argv
[], int argv_sz
,
220 int ide_idx
, const char *dev
, int img_idx
,
225 s1
= g_strdup_printf("-drive id=drive%d,if=%s",
226 ide_idx
, dev
? "none" : "ide");
227 s2
= dev
? g_strdup("") : g_strdup_printf(",index=%d", ide_idx
);
229 if (img_secs
[img_idx
] >= 0) {
230 setup_mbr(img_idx
, mbr
);
231 s3
= g_strdup_printf(",format=raw,file=%s", img_file_name
[img_idx
]);
233 s3
= g_strdup(",media=cdrom");
235 argc
= append_arg(argc
, argv
, argv_sz
,
236 g_strdup_printf("%s%s%s", s1
, s2
, s3
));
242 argc
= append_arg(argc
, argv
, argv_sz
,
243 g_strdup_printf("-device %s,drive=drive%d,"
244 "bus=ide.%d,unit=%d",
246 ide_idx
/ 2, ide_idx
% 2));
252 * Test case: no IDE devices
254 static void test_ide_none(void)
256 char **argv
= g_new0(char *, ARGV_SIZE
);
260 setup_common(argv
, ARGV_SIZE
);
261 args
= g_strjoinv(" ", argv
);
262 qts
= qtest_init(args
);
269 static void test_ide_mbr(bool use_device
, MBRcontents mbr
)
271 char **argv
= g_new0(char *, ARGV_SIZE
);
278 argc
= setup_common(argv
, ARGV_SIZE
);
279 for (i
= 0; i
< backend_last
; i
++) {
280 cur_ide
[i
] = &hd_chst
[i
][mbr
];
281 dev
= use_device
? (is_hd(cur_ide
[i
]) ? "ide-hd" : "ide-cd") : NULL
;
282 argc
= setup_ide(argc
, argv
, ARGV_SIZE
, i
, dev
, i
, mbr
);
284 args
= g_strjoinv(" ", argv
);
285 qts
= qtest_init(args
);
293 * Test case: IDE devices (if=ide) with blank MBRs
295 static void test_ide_drive_mbr_blank(void)
297 test_ide_mbr(false, mbr_blank
);
301 * Test case: IDE devices (if=ide) with MBRs indicating LBA is in use
303 static void test_ide_drive_mbr_lba(void)
305 test_ide_mbr(false, mbr_lba
);
309 * Test case: IDE devices (if=ide) with MBRs indicating CHS is in use
311 static void test_ide_drive_mbr_chs(void)
313 test_ide_mbr(false, mbr_chs
);
317 * Test case: IDE devices (if=none) with blank MBRs
319 static void test_ide_device_mbr_blank(void)
321 test_ide_mbr(true, mbr_blank
);
325 * Test case: IDE devices (if=none) with MBRs indicating LBA is in use
327 static void test_ide_device_mbr_lba(void)
329 test_ide_mbr(true, mbr_lba
);
333 * Test case: IDE devices (if=none) with MBRs indicating CHS is in use
335 static void test_ide_device_mbr_chs(void)
337 test_ide_mbr(true, mbr_chs
);
340 static void test_ide_drive_user(const char *dev
, bool trans
)
342 char **argv
= g_new0(char *, ARGV_SIZE
);
345 int secs
= img_secs
[backend_small
];
346 const CHST expected_chst
= { secs
/ (4 * 32) , 4, 32, trans
};
349 argc
= setup_common(argv
, ARGV_SIZE
);
350 opts
= g_strdup_printf("%s,%scyls=%d,heads=%d,secs=%d",
351 dev
, trans
? "bios-chs-trans=lba," : "",
352 expected_chst
.cyls
, expected_chst
.heads
,
354 cur_ide
[0] = &expected_chst
;
355 argc
= setup_ide(argc
, argv
, ARGV_SIZE
, 0, opts
, backend_small
, mbr_chs
);
357 args
= g_strjoinv(" ", argv
);
358 qts
= qtest_init(args
);
366 * Test case: IDE device (if=none) with explicit CHS
368 static void test_ide_device_user_chs(void)
370 test_ide_drive_user("ide-hd", false);
374 * Test case: IDE device (if=none) with explicit CHS and translation
376 static void test_ide_device_user_chst(void)
378 test_ide_drive_user("ide-hd", true);
382 * Test case: IDE devices (if=ide), but use index=0 for CD-ROM
384 static void test_ide_drive_cd_0(void)
386 char **argv
= g_new0(char *, ARGV_SIZE
);
392 argc
= setup_common(argv
, ARGV_SIZE
);
393 for (i
= 0; i
<= backend_empty
; i
++) {
394 ide_idx
= backend_empty
- i
;
395 cur_ide
[ide_idx
] = &hd_chst
[i
][mbr_blank
];
396 argc
= setup_ide(argc
, argv
, ARGV_SIZE
, ide_idx
, NULL
, i
, mbr_blank
);
398 args
= g_strjoinv(" ", argv
);
399 qts
= qtest_init(args
);
418 static MBRpartitions empty_mbr
= { {false, 0, 0, 0, 0, 0, 0, 0, 0},
419 {false, 0, 0, 0, 0, 0, 0, 0, 0},
420 {false, 0, 0, 0, 0, 0, 0, 0, 0},
421 {false, 0, 0, 0, 0, 0, 0, 0, 0} };
423 static char *create_qcow2_with_mbr(MBRpartitions mbr
, uint64_t sectors
)
425 g_autofree
char *raw_path
= NULL
;
427 char cmd
[100 + 2 * PATH_MAX
];
428 uint8_t buf
[512] = {};
429 int i
, ret
, fd
, offset
;
430 uint64_t qcow2_size
= sectors
* 512;
431 uint8_t status
, parttype
, head
, sector
, cyl
;
433 char *qemu_img_abs_path
;
437 for (i
= 0; i
< 4; i
++) {
438 status
= mbr
[i
].active
? 0x80 : 0x00;
439 g_assert(mbr
[i
].head
< 256);
440 g_assert(mbr
[i
].sector
< 64);
441 g_assert(mbr
[i
].cyl
< 1024);
443 sector
= mbr
[i
].sector
+ ((mbr
[i
].cyl
& 0x300) >> 2);
444 cyl
= mbr
[i
].cyl
& 0xff;
446 buf
[offset
+ 0x0] = status
;
447 buf
[offset
+ 0x1] = head
;
448 buf
[offset
+ 0x2] = sector
;
449 buf
[offset
+ 0x3] = cyl
;
452 g_assert(mbr
[i
].end_head
< 256);
453 g_assert(mbr
[i
].end_sector
< 64);
454 g_assert(mbr
[i
].end_cyl
< 1024);
455 head
= mbr
[i
].end_head
;
456 sector
= mbr
[i
].end_sector
+ ((mbr
[i
].end_cyl
& 0x300) >> 2);
457 cyl
= mbr
[i
].end_cyl
& 0xff;
459 buf
[offset
+ 0x4] = parttype
;
460 buf
[offset
+ 0x5] = head
;
461 buf
[offset
+ 0x6] = sector
;
462 buf
[offset
+ 0x7] = cyl
;
464 stl_le_p(&buf
[offset
+ 0x8], mbr
[i
].start_sect
);
465 stl_le_p(&buf
[offset
+ 0xc], mbr
[i
].nr_sects
);
470 fd
= g_file_open_tmp("qtest.XXXXXX", &raw_path
, NULL
);
474 fd
= open(raw_path
, O_WRONLY
);
476 ret
= write(fd
, buf
, sizeof(buf
));
477 g_assert(ret
== sizeof(buf
));
480 fd
= g_file_open_tmp("qtest.XXXXXX", &qcow2_path
, NULL
);
484 qemu_img_path
= getenv("QTEST_QEMU_IMG");
485 g_assert(qemu_img_path
);
486 qemu_img_abs_path
= realpath(qemu_img_path
, NULL
);
487 g_assert(qemu_img_abs_path
);
489 ret
= snprintf(cmd
, sizeof(cmd
),
490 "%s convert -f raw -O qcow2 %s %s > /dev/null",
492 raw_path
, qcow2_path
);
493 g_assert((0 < ret
) && (ret
<= sizeof(cmd
)));
497 ret
= snprintf(cmd
, sizeof(cmd
),
498 "%s resize %s %" PRIu64
" > /dev/null",
500 qcow2_path
, qcow2_size
);
501 g_assert((0 < ret
) && (ret
<= sizeof(cmd
)));
505 free(qemu_img_abs_path
);
512 #define BIOS_GEOMETRY_MAX_SIZE 10000
521 const char *dev_path
;
525 static void read_bootdevices(QFWCFG
*fw_cfg
, CHSResult expected
[])
527 char *buf
= g_malloc0(BIOS_GEOMETRY_MAX_SIZE
);
529 GList
*results
= NULL
, *cur_result
;
535 qfw_cfg_get_file(fw_cfg
, "bios-geometry", buf
, BIOS_GEOMETRY_MAX_SIZE
);
537 for (cur
= buf
; *cur
; cur
++) {
544 while (strlen(cur
)) {
546 r
= g_malloc0(sizeof(*r
));
547 r
->dev_path
= g_malloc0(strlen(cur
) + 1);
548 res
= sscanf(cur
, "%s %" PRIu32
" %" PRIu32
" %" PRIu32
,
550 &(r
->chs
.c
), &(r
->chs
.h
), &(r
->chs
.s
));
554 results
= g_list_prepend(results
, r
);
556 cur
+= strlen(cur
) + 1;
561 while (expected
[i
].dev_path
) {
563 cur_result
= results
;
565 r
= cur_result
->data
;
566 if (!strcmp(r
->dev_path
, expected
[i
].dev_path
) &&
567 !memcmp(&(r
->chs
), &(expected
[i
].chs
), sizeof(r
->chs
))) {
571 cur_result
= g_list_next(cur_result
);
574 g_free((char *)((CHSResult
*)cur_result
->data
)->dev_path
);
575 g_free(cur_result
->data
);
576 results
= g_list_delete_link(results
, cur_result
);
580 g_assert(results
== NULL
);
585 #define MAX_DRIVES 30
593 int n_scsi_controllers
;
597 static TestArgs
*create_args(void)
599 TestArgs
*args
= g_malloc0(sizeof(*args
));
600 args
->argv
= g_new0(char *, ARGV_SIZE
);
601 args
->argc
= append_arg(args
->argc
, args
->argv
,
602 ARGV_SIZE
, g_strdup("-nodefaults"));
603 args
->drives
= g_new0(char *, MAX_DRIVES
);
607 static void add_drive_with_mbr(TestArgs
*args
,
608 MBRpartitions mbr
, uint64_t sectors
)
614 g_assert(args
->n_drives
< MAX_DRIVES
);
616 img_file_name
= create_qcow2_with_mbr(mbr
, sectors
);
618 args
->drives
[args
->n_drives
] = img_file_name
;
619 ret
= snprintf(part
, sizeof(part
),
620 "-drive file=%s,if=none,format=qcow2,id=disk%d",
621 img_file_name
, args
->n_drives
);
622 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
623 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
627 static void add_ide_disk(TestArgs
*args
,
628 int drive_idx
, int bus
, int unit
, int c
, int h
, int s
)
633 ret
= snprintf(part
, sizeof(part
),
634 "-device ide-hd,drive=disk%d,bus=ide.%d,unit=%d,"
635 "lcyls=%d,lheads=%d,lsecs=%d",
636 drive_idx
, bus
, unit
, c
, h
, s
);
637 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
638 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
641 static void add_scsi_controller(TestArgs
*args
,
649 ret
= snprintf(part
, sizeof(part
),
650 "-device %s,id=scsi%d,bus=%s,addr=%d",
651 type
, args
->n_scsi_controllers
, bus
, addr
);
652 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
653 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
654 args
->n_scsi_controllers
++;
657 static void add_scsi_disk(TestArgs
*args
,
658 int drive_idx
, int bus
,
659 int channel
, int scsi_id
, int lun
,
665 ret
= snprintf(part
, sizeof(part
),
666 "-device scsi-hd,id=scsi-disk%d,drive=disk%d,"
668 "channel=%d,scsi-id=%d,lun=%d,"
669 "lcyls=%d,lheads=%d,lsecs=%d",
670 args
->n_scsi_disks
, drive_idx
, bus
, channel
, scsi_id
, lun
,
672 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
673 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
674 args
->n_scsi_disks
++;
677 static void add_virtio_disk(TestArgs
*args
,
678 int drive_idx
, const char *bus
, int addr
,
684 ret
= snprintf(part
, sizeof(part
),
685 "-device virtio-blk-pci,id=virtio-disk%d,"
686 "drive=disk%d,bus=%s,addr=%d,"
687 "lcyls=%d,lheads=%d,lsecs=%d",
688 args
->n_virtio_disks
, drive_idx
, bus
, addr
, c
, h
, s
);
689 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
690 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
691 args
->n_virtio_disks
++;
694 static void test_override(TestArgs
*args
, const char *arch
,
695 CHSResult expected
[])
702 joined_args
= g_strjoinv(" ", args
->argv
);
704 qts
= qtest_initf("-machine %s %s", arch
, joined_args
);
705 fw_cfg
= pc_fw_cfg_init(qts
);
707 read_bootdevices(fw_cfg
, expected
);
714 for (i
= 0; i
< args
->n_drives
; i
++) {
715 unlink(args
->drives
[i
]);
716 g_free(args
->drives
[i
]);
718 g_free(args
->drives
);
719 g_strfreev(args
->argv
);
723 static void test_override_ide(void)
725 TestArgs
*args
= create_args();
726 CHSResult expected
[] = {
727 {"/pci@i0cf8/ide@1,1/drive@0/disk@0", {10000, 120, 30} },
728 {"/pci@i0cf8/ide@1,1/drive@0/disk@1", {9000, 120, 30} },
729 {"/pci@i0cf8/ide@1,1/drive@1/disk@0", {0, 1, 1} },
730 {"/pci@i0cf8/ide@1,1/drive@1/disk@1", {1, 0, 0} },
733 add_drive_with_mbr(args
, empty_mbr
, 1);
734 add_drive_with_mbr(args
, empty_mbr
, 1);
735 add_drive_with_mbr(args
, empty_mbr
, 1);
736 add_drive_with_mbr(args
, empty_mbr
, 1);
737 add_ide_disk(args
, 0, 0, 0, 10000, 120, 30);
738 add_ide_disk(args
, 1, 0, 1, 9000, 120, 30);
739 add_ide_disk(args
, 2, 1, 0, 0, 1, 1);
740 add_ide_disk(args
, 3, 1, 1, 1, 0, 0);
741 test_override(args
, "pc", expected
);
744 static void test_override_sata(void)
746 TestArgs
*args
= create_args();
747 CHSResult expected
[] = {
748 {"/pci@i0cf8/pci8086,2922@1f,2/drive@0/disk@0", {10000, 120, 30} },
749 {"/pci@i0cf8/pci8086,2922@1f,2/drive@1/disk@0", {9000, 120, 30} },
750 {"/pci@i0cf8/pci8086,2922@1f,2/drive@2/disk@0", {0, 1, 1} },
751 {"/pci@i0cf8/pci8086,2922@1f,2/drive@3/disk@0", {1, 0, 0} },
754 add_drive_with_mbr(args
, empty_mbr
, 1);
755 add_drive_with_mbr(args
, empty_mbr
, 1);
756 add_drive_with_mbr(args
, empty_mbr
, 1);
757 add_drive_with_mbr(args
, empty_mbr
, 1);
758 add_ide_disk(args
, 0, 0, 0, 10000, 120, 30);
759 add_ide_disk(args
, 1, 1, 0, 9000, 120, 30);
760 add_ide_disk(args
, 2, 2, 0, 0, 1, 1);
761 add_ide_disk(args
, 3, 3, 0, 1, 0, 0);
762 test_override(args
, "q35", expected
);
765 static void test_override_scsi(void)
767 TestArgs
*args
= create_args();
768 CHSResult expected
[] = {
769 {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
770 {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
771 {"/pci@i0cf8/scsi@3/channel@0/disk@2,0", {1, 0, 0} },
772 {"/pci@i0cf8/scsi@3/channel@0/disk@3,0", {0, 1, 0} },
775 add_drive_with_mbr(args
, empty_mbr
, 1);
776 add_drive_with_mbr(args
, empty_mbr
, 1);
777 add_drive_with_mbr(args
, empty_mbr
, 1);
778 add_drive_with_mbr(args
, empty_mbr
, 1);
779 add_scsi_controller(args
, "lsi53c895a", "pci.0", 3);
780 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
781 add_scsi_disk(args
, 1, 0, 0, 1, 0, 9000, 120, 30);
782 add_scsi_disk(args
, 2, 0, 0, 2, 0, 1, 0, 0);
783 add_scsi_disk(args
, 3, 0, 0, 3, 0, 0, 1, 0);
784 test_override(args
, "pc", expected
);
787 static void setup_pci_bridge(TestArgs
*args
, const char *id
)
791 br
= g_strdup_printf("-device pcie-pci-bridge,bus=pcie.0,id=%s", id
);
793 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, br
);
796 static void test_override_scsi_q35(void)
798 TestArgs
*args
= create_args();
799 CHSResult expected
[] = {
800 { "/pci@i0cf8/pci-bridge@1/scsi@3/channel@0/disk@0,0",
803 {"/pci@i0cf8/pci-bridge@1/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
804 {"/pci@i0cf8/pci-bridge@1/scsi@3/channel@0/disk@2,0", {1, 0, 0} },
805 {"/pci@i0cf8/pci-bridge@1/scsi@3/channel@0/disk@3,0", {0, 1, 0} },
808 add_drive_with_mbr(args
, empty_mbr
, 1);
809 add_drive_with_mbr(args
, empty_mbr
, 1);
810 add_drive_with_mbr(args
, empty_mbr
, 1);
811 add_drive_with_mbr(args
, empty_mbr
, 1);
812 setup_pci_bridge(args
, "pcie-pci-br");
813 add_scsi_controller(args
, "lsi53c895a", "pcie-pci-br", 3);
814 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
815 add_scsi_disk(args
, 1, 0, 0, 1, 0, 9000, 120, 30);
816 add_scsi_disk(args
, 2, 0, 0, 2, 0, 1, 0, 0);
817 add_scsi_disk(args
, 3, 0, 0, 3, 0, 0, 1, 0);
818 test_override(args
, "q35", expected
);
821 static void test_override_scsi_2_controllers(void)
823 TestArgs
*args
= create_args();
824 CHSResult expected
[] = {
825 {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
826 {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
827 {"/pci@i0cf8/scsi@4/channel@0/disk@0,1", {1, 0, 0} },
828 {"/pci@i0cf8/scsi@4/channel@0/disk@1,2", {0, 1, 0} },
831 add_drive_with_mbr(args
, empty_mbr
, 1);
832 add_drive_with_mbr(args
, empty_mbr
, 1);
833 add_drive_with_mbr(args
, empty_mbr
, 1);
834 add_drive_with_mbr(args
, empty_mbr
, 1);
835 add_scsi_controller(args
, "lsi53c895a", "pci.0", 3);
836 add_scsi_controller(args
, "virtio-scsi-pci", "pci.0", 4);
837 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
838 add_scsi_disk(args
, 1, 0, 0, 1, 0, 9000, 120, 30);
839 add_scsi_disk(args
, 2, 1, 0, 0, 1, 1, 0, 0);
840 add_scsi_disk(args
, 3, 1, 0, 1, 2, 0, 1, 0);
841 test_override(args
, "pc", expected
);
844 static void test_override_virtio_blk(void)
846 TestArgs
*args
= create_args();
847 CHSResult expected
[] = {
848 {"/pci@i0cf8/scsi@3/disk@0,0", {10000, 120, 30} },
849 {"/pci@i0cf8/scsi@4/disk@0,0", {9000, 120, 30} },
852 add_drive_with_mbr(args
, empty_mbr
, 1);
853 add_drive_with_mbr(args
, empty_mbr
, 1);
854 add_virtio_disk(args
, 0, "pci.0", 3, 10000, 120, 30);
855 add_virtio_disk(args
, 1, "pci.0", 4, 9000, 120, 30);
856 test_override(args
, "pc", expected
);
859 static void test_override_virtio_blk_q35(void)
861 TestArgs
*args
= create_args();
862 CHSResult expected
[] = {
863 {"/pci@i0cf8/pci-bridge@1/scsi@3/disk@0,0", {10000, 120, 30} },
864 {"/pci@i0cf8/pci-bridge@1/scsi@4/disk@0,0", {9000, 120, 30} },
867 add_drive_with_mbr(args
, empty_mbr
, 1);
868 add_drive_with_mbr(args
, empty_mbr
, 1);
869 setup_pci_bridge(args
, "pcie-pci-br");
870 add_virtio_disk(args
, 0, "pcie-pci-br", 3, 10000, 120, 30);
871 add_virtio_disk(args
, 1, "pcie-pci-br", 4, 9000, 120, 30);
872 test_override(args
, "q35", expected
);
875 static void test_override_zero_chs(void)
877 TestArgs
*args
= create_args();
878 CHSResult expected
[] = {
881 add_drive_with_mbr(args
, empty_mbr
, 1);
882 add_ide_disk(args
, 0, 1, 1, 0, 0, 0);
883 test_override(args
, "pc", expected
);
886 static void test_override_zero_chs_q35(void)
888 TestArgs
*args
= create_args();
889 CHSResult expected
[] = {
892 add_drive_with_mbr(args
, empty_mbr
, 1);
893 add_ide_disk(args
, 0, 0, 0, 0, 0, 0);
894 test_override(args
, "q35", expected
);
897 static void test_override_hot_unplug(TestArgs
*args
, const char *devid
,
898 CHSResult expected
[], CHSResult expected2
[])
906 joined_args
= g_strjoinv(" ", args
->argv
);
908 qts
= qtest_initf("%s", joined_args
);
909 fw_cfg
= pc_fw_cfg_init(qts
);
911 read_bootdevices(fw_cfg
, expected
);
913 /* unplug device an restart */
914 qtest_qmp_device_del_send(qts
, devid
);
916 response
= qtest_qmp(qts
,
917 "{ 'execute': 'system_reset', 'arguments': { }}");
919 g_assert(!qdict_haskey(response
, "error"));
920 qobject_unref(response
);
922 qtest_qmp_eventwait(qts
, "RESET");
924 read_bootdevices(fw_cfg
, expected2
);
931 for (i
= 0; i
< args
->n_drives
; i
++) {
932 unlink(args
->drives
[i
]);
933 g_free(args
->drives
[i
]);
935 g_free(args
->drives
);
936 g_strfreev(args
->argv
);
940 static void test_override_scsi_hot_unplug(void)
942 TestArgs
*args
= create_args();
943 CHSResult expected
[] = {
944 {"/pci@i0cf8/scsi@2/channel@0/disk@0,0", {10000, 120, 30} },
945 {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
948 CHSResult expected2
[] = {
949 {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
952 add_drive_with_mbr(args
, empty_mbr
, 1);
953 add_drive_with_mbr(args
, empty_mbr
, 1);
954 add_scsi_controller(args
, "virtio-scsi-pci", "pci.0", 2);
955 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
956 add_scsi_disk(args
, 1, 0, 0, 1, 0, 20, 20, 20);
958 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
,
959 g_strdup("-machine pc"));
961 test_override_hot_unplug(args
, "scsi-disk0", expected
, expected2
);
964 static void test_override_scsi_hot_unplug_q35(void)
966 TestArgs
*args
= create_args();
967 CHSResult expected
[] = {
969 "/pci@i0cf8/pci-bridge@1/pci-bridge@0/scsi@2/channel@0/disk@0,0",
973 "/pci@i0cf8/pci-bridge@1/pci-bridge@0/scsi@2/channel@0/disk@1,0",
978 CHSResult expected2
[] = {
980 "/pci@i0cf8/pci-bridge@1/pci-bridge@0/scsi@2/channel@0/disk@1,0",
986 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
,
987 g_strdup("-device pcie-root-port,id=p0 "
988 "-device pcie-pci-bridge,bus=p0,id=b1 "
991 add_drive_with_mbr(args
, empty_mbr
, 1);
992 add_drive_with_mbr(args
, empty_mbr
, 1);
993 add_scsi_controller(args
, "virtio-scsi-pci", "b1", 2);
994 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
995 add_scsi_disk(args
, 1, 0, 0, 1, 0, 20, 20, 20);
997 test_override_hot_unplug(args
, "scsi-disk0", expected
, expected2
);
1000 static void test_override_virtio_hot_unplug(void)
1002 TestArgs
*args
= create_args();
1003 CHSResult expected
[] = {
1004 {"/pci@i0cf8/scsi@2/disk@0,0", {10000, 120, 30} },
1005 {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
1008 CHSResult expected2
[] = {
1009 {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
1012 add_drive_with_mbr(args
, empty_mbr
, 1);
1013 add_drive_with_mbr(args
, empty_mbr
, 1);
1014 add_virtio_disk(args
, 0, "pci.0", 2, 10000, 120, 30);
1015 add_virtio_disk(args
, 1, "pci.0", 3, 20, 20, 20);
1017 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
,
1018 g_strdup("-machine pc"));
1020 test_override_hot_unplug(args
, "virtio-disk0", expected
, expected2
);
1023 static void test_override_virtio_hot_unplug_q35(void)
1025 TestArgs
*args
= create_args();
1026 CHSResult expected
[] = {
1028 "/pci@i0cf8/pci-bridge@1/pci-bridge@0/scsi@2/disk@0,0",
1032 "/pci@i0cf8/pci-bridge@1/pci-bridge@0/scsi@3/disk@0,0",
1037 CHSResult expected2
[] = {
1039 "/pci@i0cf8/pci-bridge@1/pci-bridge@0/scsi@3/disk@0,0",
1045 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
,
1046 g_strdup("-device pcie-root-port,id=p0 "
1047 "-device pcie-pci-bridge,bus=p0,id=b1 "
1050 add_drive_with_mbr(args
, empty_mbr
, 1);
1051 add_drive_with_mbr(args
, empty_mbr
, 1);
1052 add_virtio_disk(args
, 0, "b1", 2, 10000, 120, 30);
1053 add_virtio_disk(args
, 1, "b1", 3, 20, 20, 20);
1055 test_override_hot_unplug(args
, "virtio-disk0", expected
, expected2
);
1058 int main(int argc
, char **argv
)
1063 g_test_init(&argc
, &argv
, NULL
);
1065 for (i
= 0; i
< backend_last
; i
++) {
1066 if (img_secs
[i
] >= 0) {
1067 img_file_name
[i
] = create_test_img(img_secs
[i
]);
1068 if (!img_file_name
[i
]) {
1069 g_test_message("Could not create test images.");
1073 img_file_name
[i
] = NULL
;
1077 qtest_add_func("hd-geo/ide/none", test_ide_none
);
1078 qtest_add_func("hd-geo/ide/drive/mbr/blank", test_ide_drive_mbr_blank
);
1079 qtest_add_func("hd-geo/ide/drive/mbr/lba", test_ide_drive_mbr_lba
);
1080 qtest_add_func("hd-geo/ide/drive/mbr/chs", test_ide_drive_mbr_chs
);
1081 qtest_add_func("hd-geo/ide/drive/cd_0", test_ide_drive_cd_0
);
1082 qtest_add_func("hd-geo/ide/device/mbr/blank", test_ide_device_mbr_blank
);
1083 qtest_add_func("hd-geo/ide/device/mbr/lba", test_ide_device_mbr_lba
);
1084 qtest_add_func("hd-geo/ide/device/mbr/chs", test_ide_device_mbr_chs
);
1085 qtest_add_func("hd-geo/ide/device/user/chs", test_ide_device_user_chs
);
1086 qtest_add_func("hd-geo/ide/device/user/chst", test_ide_device_user_chst
);
1087 if (have_qemu_img()) {
1088 qtest_add_func("hd-geo/override/ide", test_override_ide
);
1089 if (qtest_has_device("lsi53c895a")) {
1090 qtest_add_func("hd-geo/override/scsi", test_override_scsi
);
1091 if (qtest_has_device("virtio-scsi-pci")) {
1092 qtest_add_func("hd-geo/override/scsi_2_controllers",
1093 test_override_scsi_2_controllers
);
1096 qtest_add_func("hd-geo/override/zero_chs", test_override_zero_chs
);
1097 if (qtest_has_device("virtio-scsi-pci")) {
1098 qtest_add_func("hd-geo/override/scsi_hot_unplug",
1099 test_override_scsi_hot_unplug
);
1101 if (qtest_has_device("virtio-blk-pci")) {
1102 qtest_add_func("hd-geo/override/virtio_hot_unplug",
1103 test_override_virtio_hot_unplug
);
1104 qtest_add_func("hd-geo/override/virtio_blk",
1105 test_override_virtio_blk
);
1108 if (qtest_has_machine("q35")) {
1109 qtest_add_func("hd-geo/override/sata", test_override_sata
);
1110 qtest_add_func("hd-geo/override/zero_chs_q35",
1111 test_override_zero_chs_q35
);
1112 if (qtest_has_device("lsi53c895a")) {
1113 qtest_add_func("hd-geo/override/scsi_q35",
1114 test_override_scsi_q35
);
1116 if (qtest_has_device("virtio-scsi-pci")) {
1117 qtest_add_func("hd-geo/override/scsi_hot_unplug_q35",
1118 test_override_scsi_hot_unplug_q35
);
1120 if (qtest_has_device("virtio-blk-pci")) {
1121 qtest_add_func("hd-geo/override/virtio_hot_unplug_q35",
1122 test_override_virtio_hot_unplug_q35
);
1123 qtest_add_func("hd-geo/override/virtio_blk_q35",
1124 test_override_virtio_blk_q35
);
1129 g_test_message("QTEST_QEMU_IMG not set or qemu-img missing; "
1130 "skipping hd-geo/override/* tests");
1136 for (i
= 0; i
< backend_last
; i
++) {
1137 if (img_file_name
[i
]) {
1138 unlink(img_file_name
[i
]);
1139 g_free(img_file_name
[i
]);