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"
21 #include "libqos/libqtest.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
)
30 char *template = strdup("/tmp/qtest.XXXXXX");
33 fd
= mkstemp(template);
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 const char *template = "/tmp/qtest.XXXXXX";
426 char *raw_path
= strdup(template);
427 char *qcow2_path
= strdup(template);
428 char cmd
[100 + 2 * PATH_MAX
];
429 uint8_t buf
[512] = {};
430 int i
, ret
, fd
, offset
;
431 uint64_t qcow2_size
= sectors
* 512;
432 uint8_t status
, parttype
, head
, sector
, cyl
;
434 char *qemu_img_abs_path
;
438 for (i
= 0; i
< 4; i
++) {
439 status
= mbr
[i
].active
? 0x80 : 0x00;
440 g_assert(mbr
[i
].head
< 256);
441 g_assert(mbr
[i
].sector
< 64);
442 g_assert(mbr
[i
].cyl
< 1024);
444 sector
= mbr
[i
].sector
+ ((mbr
[i
].cyl
& 0x300) >> 2);
445 cyl
= mbr
[i
].cyl
& 0xff;
447 buf
[offset
+ 0x0] = status
;
448 buf
[offset
+ 0x1] = head
;
449 buf
[offset
+ 0x2] = sector
;
450 buf
[offset
+ 0x3] = cyl
;
453 g_assert(mbr
[i
].end_head
< 256);
454 g_assert(mbr
[i
].end_sector
< 64);
455 g_assert(mbr
[i
].end_cyl
< 1024);
456 head
= mbr
[i
].end_head
;
457 sector
= mbr
[i
].end_sector
+ ((mbr
[i
].end_cyl
& 0x300) >> 2);
458 cyl
= mbr
[i
].end_cyl
& 0xff;
460 buf
[offset
+ 0x4] = parttype
;
461 buf
[offset
+ 0x5] = head
;
462 buf
[offset
+ 0x6] = sector
;
463 buf
[offset
+ 0x7] = cyl
;
465 stl_le_p(&buf
[offset
+ 0x8], mbr
[i
].start_sect
);
466 stl_le_p(&buf
[offset
+ 0xc], mbr
[i
].nr_sects
);
471 fd
= mkstemp(raw_path
);
475 fd
= open(raw_path
, O_WRONLY
);
477 ret
= write(fd
, buf
, sizeof(buf
));
478 g_assert(ret
== sizeof(buf
));
481 fd
= mkstemp(qcow2_path
);
485 qemu_img_path
= getenv("QTEST_QEMU_IMG");
486 g_assert(qemu_img_path
);
487 qemu_img_abs_path
= realpath(qemu_img_path
, NULL
);
488 g_assert(qemu_img_abs_path
);
490 ret
= snprintf(cmd
, sizeof(cmd
),
491 "%s convert -f raw -O qcow2 %s %s > /dev/null",
493 raw_path
, qcow2_path
);
494 g_assert((0 < ret
) && (ret
<= sizeof(cmd
)));
498 ret
= snprintf(cmd
, sizeof(cmd
),
499 "%s resize %s %" PRIu64
" > /dev/null",
501 qcow2_path
, qcow2_size
);
502 g_assert((0 < ret
) && (ret
<= sizeof(cmd
)));
506 free(qemu_img_abs_path
);
514 #define BIOS_GEOMETRY_MAX_SIZE 10000
523 const char *dev_path
;
527 static void read_bootdevices(QFWCFG
*fw_cfg
, CHSResult expected
[])
529 char *buf
= g_malloc0(BIOS_GEOMETRY_MAX_SIZE
);
531 GList
*results
= NULL
, *cur_result
;
537 qfw_cfg_get_file(fw_cfg
, "bios-geometry", buf
, BIOS_GEOMETRY_MAX_SIZE
);
539 for (cur
= buf
; *cur
; cur
++) {
546 while (strlen(cur
)) {
548 r
= g_malloc0(sizeof(*r
));
549 r
->dev_path
= g_malloc0(strlen(cur
) + 1);
550 res
= sscanf(cur
, "%s %" PRIu32
" %" PRIu32
" %" PRIu32
,
552 &(r
->chs
.c
), &(r
->chs
.h
), &(r
->chs
.s
));
556 results
= g_list_prepend(results
, r
);
558 cur
+= strlen(cur
) + 1;
563 while (expected
[i
].dev_path
) {
565 cur_result
= results
;
567 r
= cur_result
->data
;
568 if (!strcmp(r
->dev_path
, expected
[i
].dev_path
) &&
569 !memcmp(&(r
->chs
), &(expected
[i
].chs
), sizeof(r
->chs
))) {
573 cur_result
= g_list_next(cur_result
);
576 g_free((char *)((CHSResult
*)cur_result
->data
)->dev_path
);
577 g_free(cur_result
->data
);
578 results
= g_list_delete_link(results
, cur_result
);
582 g_assert(results
== NULL
);
587 #define MAX_DRIVES 30
595 int n_scsi_controllers
;
599 static TestArgs
*create_args(void)
601 TestArgs
*args
= g_malloc0(sizeof(*args
));
602 args
->argv
= g_new0(char *, ARGV_SIZE
);
603 args
->argc
= append_arg(args
->argc
, args
->argv
,
604 ARGV_SIZE
, g_strdup("-nodefaults"));
605 args
->drives
= g_new0(char *, MAX_DRIVES
);
609 static void add_drive_with_mbr(TestArgs
*args
,
610 MBRpartitions mbr
, uint64_t sectors
)
616 g_assert(args
->n_drives
< MAX_DRIVES
);
618 img_file_name
= create_qcow2_with_mbr(mbr
, sectors
);
620 args
->drives
[args
->n_drives
] = img_file_name
;
621 ret
= snprintf(part
, sizeof(part
),
622 "-drive file=%s,if=none,format=qcow2,id=disk%d",
623 img_file_name
, args
->n_drives
);
624 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
625 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
629 static void add_ide_disk(TestArgs
*args
,
630 int drive_idx
, int bus
, int unit
, int c
, int h
, int s
)
635 ret
= snprintf(part
, sizeof(part
),
636 "-device ide-hd,drive=disk%d,bus=ide.%d,unit=%d,"
637 "lcyls=%d,lheads=%d,lsecs=%d",
638 drive_idx
, bus
, unit
, c
, h
, s
);
639 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
640 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
643 static void add_scsi_controller(TestArgs
*args
,
651 ret
= snprintf(part
, sizeof(part
),
652 "-device %s,id=scsi%d,bus=%s,addr=%d",
653 type
, args
->n_scsi_controllers
, bus
, addr
);
654 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
655 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
656 args
->n_scsi_controllers
++;
659 static void add_scsi_disk(TestArgs
*args
,
660 int drive_idx
, int bus
,
661 int channel
, int scsi_id
, int lun
,
667 ret
= snprintf(part
, sizeof(part
),
668 "-device scsi-hd,id=scsi-disk%d,drive=disk%d,"
670 "channel=%d,scsi-id=%d,lun=%d,"
671 "lcyls=%d,lheads=%d,lsecs=%d",
672 args
->n_scsi_disks
, drive_idx
, bus
, channel
, scsi_id
, lun
,
674 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
675 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
676 args
->n_scsi_disks
++;
679 static void add_virtio_disk(TestArgs
*args
,
680 int drive_idx
, const char *bus
, int addr
,
686 ret
= snprintf(part
, sizeof(part
),
687 "-device virtio-blk-pci,id=virtio-disk%d,"
688 "drive=disk%d,bus=%s,addr=%d,"
689 "lcyls=%d,lheads=%d,lsecs=%d",
690 args
->n_virtio_disks
, drive_idx
, bus
, addr
, c
, h
, s
);
691 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
692 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
693 args
->n_virtio_disks
++;
696 static void test_override(TestArgs
*args
, CHSResult expected
[])
703 joined_args
= g_strjoinv(" ", args
->argv
);
705 qts
= qtest_initf("-machine pc %s", joined_args
);
706 fw_cfg
= pc_fw_cfg_init(qts
);
708 read_bootdevices(fw_cfg
, expected
);
715 for (i
= 0; i
< args
->n_drives
; i
++) {
716 unlink(args
->drives
[i
]);
717 free(args
->drives
[i
]);
719 g_free(args
->drives
);
720 g_strfreev(args
->argv
);
724 static void test_override_ide(void)
726 TestArgs
*args
= create_args();
727 CHSResult expected
[] = {
728 {"/pci@i0cf8/ide@1,1/drive@0/disk@0", {10000, 120, 30} },
729 {"/pci@i0cf8/ide@1,1/drive@0/disk@1", {9000, 120, 30} },
730 {"/pci@i0cf8/ide@1,1/drive@1/disk@0", {0, 1, 1} },
731 {"/pci@i0cf8/ide@1,1/drive@1/disk@1", {1, 0, 0} },
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_drive_with_mbr(args
, empty_mbr
, 1);
738 add_ide_disk(args
, 0, 0, 0, 10000, 120, 30);
739 add_ide_disk(args
, 1, 0, 1, 9000, 120, 30);
740 add_ide_disk(args
, 2, 1, 0, 0, 1, 1);
741 add_ide_disk(args
, 3, 1, 1, 1, 0, 0);
742 test_override(args
, expected
);
745 static void test_override_scsi(void)
747 TestArgs
*args
= create_args();
748 CHSResult expected
[] = {
749 {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
750 {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
751 {"/pci@i0cf8/scsi@3/channel@0/disk@2,0", {1, 0, 0} },
752 {"/pci@i0cf8/scsi@3/channel@0/disk@3,0", {0, 1, 0} },
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_drive_with_mbr(args
, empty_mbr
, 1);
759 add_scsi_controller(args
, "lsi53c895a", "pci.0", 3);
760 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
761 add_scsi_disk(args
, 1, 0, 0, 1, 0, 9000, 120, 30);
762 add_scsi_disk(args
, 2, 0, 0, 2, 0, 1, 0, 0);
763 add_scsi_disk(args
, 3, 0, 0, 3, 0, 0, 1, 0);
764 test_override(args
, expected
);
767 static void test_override_scsi_2_controllers(void)
769 TestArgs
*args
= create_args();
770 CHSResult expected
[] = {
771 {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
772 {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
773 {"/pci@i0cf8/scsi@4/channel@0/disk@0,1", {1, 0, 0} },
774 {"/pci@i0cf8/scsi@4/channel@0/disk@1,2", {0, 1, 0} },
777 add_drive_with_mbr(args
, empty_mbr
, 1);
778 add_drive_with_mbr(args
, empty_mbr
, 1);
779 add_drive_with_mbr(args
, empty_mbr
, 1);
780 add_drive_with_mbr(args
, empty_mbr
, 1);
781 add_scsi_controller(args
, "lsi53c895a", "pci.0", 3);
782 add_scsi_controller(args
, "virtio-scsi-pci", "pci.0", 4);
783 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
784 add_scsi_disk(args
, 1, 0, 0, 1, 0, 9000, 120, 30);
785 add_scsi_disk(args
, 2, 1, 0, 0, 1, 1, 0, 0);
786 add_scsi_disk(args
, 3, 1, 0, 1, 2, 0, 1, 0);
787 test_override(args
, expected
);
790 static void test_override_virtio_blk(void)
792 TestArgs
*args
= create_args();
793 CHSResult expected
[] = {
794 {"/pci@i0cf8/scsi@3/disk@0,0", {10000, 120, 30} },
795 {"/pci@i0cf8/scsi@4/disk@0,0", {9000, 120, 30} },
798 add_drive_with_mbr(args
, empty_mbr
, 1);
799 add_drive_with_mbr(args
, empty_mbr
, 1);
800 add_virtio_disk(args
, 0, "pci.0", 3, 10000, 120, 30);
801 add_virtio_disk(args
, 1, "pci.0", 4, 9000, 120, 30);
802 test_override(args
, expected
);
805 static void test_override_zero_chs(void)
807 TestArgs
*args
= create_args();
808 CHSResult expected
[] = {
811 add_drive_with_mbr(args
, empty_mbr
, 1);
812 add_ide_disk(args
, 0, 1, 1, 0, 0, 0);
813 test_override(args
, expected
);
816 static void test_override_scsi_hot_unplug(void)
823 TestArgs
*args
= create_args();
824 CHSResult expected
[] = {
825 {"/pci@i0cf8/scsi@2/channel@0/disk@0,0", {10000, 120, 30} },
826 {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
829 CHSResult expected2
[] = {
830 {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
833 add_drive_with_mbr(args
, empty_mbr
, 1);
834 add_drive_with_mbr(args
, empty_mbr
, 1);
835 add_scsi_controller(args
, "virtio-scsi-pci", "pci.0", 2);
836 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
837 add_scsi_disk(args
, 1, 0, 0, 1, 0, 20, 20, 20);
839 joined_args
= g_strjoinv(" ", args
->argv
);
841 qts
= qtest_initf("-machine pc %s", joined_args
);
842 fw_cfg
= pc_fw_cfg_init(qts
);
844 read_bootdevices(fw_cfg
, expected
);
846 /* unplug device an restart */
847 response
= qtest_qmp(qts
,
848 "{ 'execute': 'device_del',"
849 " 'arguments': {'id': 'scsi-disk0' }}");
851 g_assert(!qdict_haskey(response
, "error"));
852 qobject_unref(response
);
853 response
= qtest_qmp(qts
,
854 "{ 'execute': 'system_reset', 'arguments': { }}");
856 g_assert(!qdict_haskey(response
, "error"));
857 qobject_unref(response
);
859 qtest_qmp_eventwait(qts
, "RESET");
861 read_bootdevices(fw_cfg
, expected2
);
868 for (i
= 0; i
< args
->n_drives
; i
++) {
869 unlink(args
->drives
[i
]);
870 free(args
->drives
[i
]);
872 g_free(args
->drives
);
873 g_strfreev(args
->argv
);
877 static void test_override_virtio_hot_unplug(void)
884 TestArgs
*args
= create_args();
885 CHSResult expected
[] = {
886 {"/pci@i0cf8/scsi@2/disk@0,0", {10000, 120, 30} },
887 {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
890 CHSResult expected2
[] = {
891 {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
894 add_drive_with_mbr(args
, empty_mbr
, 1);
895 add_drive_with_mbr(args
, empty_mbr
, 1);
896 add_virtio_disk(args
, 0, "pci.0", 2, 10000, 120, 30);
897 add_virtio_disk(args
, 1, "pci.0", 3, 20, 20, 20);
899 joined_args
= g_strjoinv(" ", args
->argv
);
901 qts
= qtest_initf("-machine pc %s", joined_args
);
902 fw_cfg
= pc_fw_cfg_init(qts
);
904 read_bootdevices(fw_cfg
, expected
);
906 /* unplug device an restart */
907 response
= qtest_qmp(qts
,
908 "{ 'execute': 'device_del',"
909 " 'arguments': {'id': 'virtio-disk0' }}");
911 g_assert(!qdict_haskey(response
, "error"));
912 qobject_unref(response
);
913 response
= qtest_qmp(qts
,
914 "{ 'execute': 'system_reset', 'arguments': { }}");
916 g_assert(!qdict_haskey(response
, "error"));
917 qobject_unref(response
);
919 qtest_qmp_eventwait(qts
, "RESET");
921 read_bootdevices(fw_cfg
, expected2
);
928 for (i
= 0; i
< args
->n_drives
; i
++) {
929 unlink(args
->drives
[i
]);
930 free(args
->drives
[i
]);
932 g_free(args
->drives
);
933 g_strfreev(args
->argv
);
937 int main(int argc
, char **argv
)
942 g_test_init(&argc
, &argv
, NULL
);
944 for (i
= 0; i
< backend_last
; i
++) {
945 if (img_secs
[i
] >= 0) {
946 img_file_name
[i
] = create_test_img(img_secs
[i
]);
947 if (!img_file_name
[i
]) {
948 g_test_message("Could not create test images.");
952 img_file_name
[i
] = NULL
;
956 qtest_add_func("hd-geo/ide/none", test_ide_none
);
957 qtest_add_func("hd-geo/ide/drive/mbr/blank", test_ide_drive_mbr_blank
);
958 qtest_add_func("hd-geo/ide/drive/mbr/lba", test_ide_drive_mbr_lba
);
959 qtest_add_func("hd-geo/ide/drive/mbr/chs", test_ide_drive_mbr_chs
);
960 qtest_add_func("hd-geo/ide/drive/cd_0", test_ide_drive_cd_0
);
961 qtest_add_func("hd-geo/ide/device/mbr/blank", test_ide_device_mbr_blank
);
962 qtest_add_func("hd-geo/ide/device/mbr/lba", test_ide_device_mbr_lba
);
963 qtest_add_func("hd-geo/ide/device/mbr/chs", test_ide_device_mbr_chs
);
964 qtest_add_func("hd-geo/ide/device/user/chs", test_ide_device_user_chs
);
965 qtest_add_func("hd-geo/ide/device/user/chst", test_ide_device_user_chst
);
966 if (have_qemu_img()) {
967 qtest_add_func("hd-geo/override/ide", test_override_ide
);
968 if (qtest_has_device("lsi53c895a")) {
969 qtest_add_func("hd-geo/override/scsi", test_override_scsi
);
970 qtest_add_func("hd-geo/override/scsi_2_controllers",
971 test_override_scsi_2_controllers
);
973 qtest_add_func("hd-geo/override/virtio_blk", test_override_virtio_blk
);
974 qtest_add_func("hd-geo/override/zero_chs", test_override_zero_chs
);
975 qtest_add_func("hd-geo/override/scsi_hot_unplug",
976 test_override_scsi_hot_unplug
);
977 qtest_add_func("hd-geo/override/virtio_hot_unplug",
978 test_override_virtio_hot_unplug
);
980 g_test_message("QTEST_QEMU_IMG not set or qemu-img missing; "
981 "skipping hd-geo/override/* tests");
987 for (i
= 0; i
< backend_last
; i
++) {
988 if (img_file_name
[i
]) {
989 unlink(img_file_name
[i
]);
990 free(img_file_name
[i
]);