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-common.h"
20 #include "qemu/bswap.h"
21 #include "qapi/qmp/qlist.h"
23 #include "libqos/fw_cfg.h"
24 #include "libqos/libqos.h"
25 #include "standard-headers/linux/qemu_fw_cfg.h"
29 static char *create_test_img(int secs
)
31 char *template = strdup("/tmp/qtest.XXXXXX");
34 fd
= mkstemp(template);
36 ret
= ftruncate(fd
, (off_t
)secs
* 512);
43 int cyls
, heads
, secs
, trans
;
47 mbr_blank
, mbr_lba
, mbr_chs
,
52 /* order is relevant */
53 backend_small
, backend_large
, backend_empty
,
57 static const int img_secs
[backend_last
] = {
58 [backend_small
] = 61440,
59 [backend_large
] = 8388608,
63 static const CHST hd_chst
[backend_last
][mbr_last
] = {
65 [mbr_blank
] = { 60, 16, 63, 0 },
66 [mbr_lba
] = { 60, 16, 63, 2 },
67 [mbr_chs
] = { 60, 16, 63, 0 }
70 [mbr_blank
] = { 8322, 16, 63, 1 },
71 [mbr_lba
] = { 8322, 16, 63, 1 },
72 [mbr_chs
] = { 8322, 16, 63, 0 }
76 static char *img_file_name
[backend_last
];
78 static const CHST
*cur_ide
[4];
80 static bool is_hd(const CHST
*expected_chst
)
82 return expected_chst
&& expected_chst
->cyls
;
85 static void test_cmos_byte(QTestState
*qts
, int reg
, int expected
)
87 enum { cmos_base
= 0x70 };
90 qtest_outb(qts
, cmos_base
+ 0, reg
);
91 actual
= qtest_inb(qts
, cmos_base
+ 1);
92 g_assert(actual
== expected
);
95 static void test_cmos_bytes(QTestState
*qts
, int reg0
, int n
,
100 for (i
= 0; i
< 9; i
++) {
101 test_cmos_byte(qts
, reg0
+ i
, expected
[i
]);
105 static void test_cmos_disk_data(QTestState
*qts
)
107 test_cmos_byte(qts
, 0x12,
108 (is_hd(cur_ide
[0]) ? 0xf0 : 0) |
109 (is_hd(cur_ide
[1]) ? 0x0f : 0));
112 static void test_cmos_drive_cyl(QTestState
*qts
, int reg0
,
113 const CHST
*expected_chst
)
115 if (is_hd(expected_chst
)) {
116 int c
= expected_chst
->cyls
;
117 int h
= expected_chst
->heads
;
118 int s
= expected_chst
->secs
;
119 uint8_t expected_bytes
[9] = {
120 c
& 0xff, c
>> 8, h
, 0xff, 0xff, 0xc0 | ((h
> 8) << 3),
123 test_cmos_bytes(qts
, reg0
, 9, expected_bytes
);
127 for (i
= 0; i
< 9; i
++) {
128 test_cmos_byte(qts
, reg0
+ i
, 0);
133 static void test_cmos_drive1(QTestState
*qts
)
135 test_cmos_byte(qts
, 0x19, is_hd(cur_ide
[0]) ? 47 : 0);
136 test_cmos_drive_cyl(qts
, 0x1b, cur_ide
[0]);
139 static void test_cmos_drive2(QTestState
*qts
)
141 test_cmos_byte(qts
, 0x1a, is_hd(cur_ide
[1]) ? 47 : 0);
142 test_cmos_drive_cyl(qts
, 0x24, cur_ide
[1]);
145 static void test_cmos_disktransflag(QTestState
*qts
)
150 for (i
= 0; i
< ARRAY_SIZE(cur_ide
); i
++) {
151 if (is_hd(cur_ide
[i
])) {
152 val
|= cur_ide
[i
]->trans
<< (2 * i
);
155 test_cmos_byte(qts
, 0x39, val
);
158 static void test_cmos(QTestState
*qts
)
160 test_cmos_disk_data(qts
);
161 test_cmos_drive1(qts
);
162 test_cmos_drive2(qts
);
163 test_cmos_disktransflag(qts
);
166 static int append_arg(int argc
, char *argv
[], int argv_sz
, char *arg
)
168 g_assert(argc
+ 1 < argv_sz
);
174 static int setup_common(char *argv
[], int argv_sz
)
176 memset(cur_ide
, 0, sizeof(cur_ide
));
177 return append_arg(0, argv
, argv_sz
,
178 g_strdup("-nodefaults"));
181 static void setup_mbr(int img_idx
, MBRcontents mbr
)
183 static const uint8_t part_lba
[16] = {
184 /* chs 0,1,1 (lba 63) to chs 0,127,63 (8001 sectors) */
185 0x80, 1, 1, 0, 6, 127, 63, 0, 63, 0, 0, 0, 0x41, 0x1F, 0, 0,
187 static const uint8_t part_chs
[16] = {
188 /* chs 0,1,1 (lba 63) to chs 7,15,63 (8001 sectors) */
189 0x80, 1, 1, 0, 6, 15, 63, 7, 63, 0, 0, 0, 0x41, 0x1F, 0, 0,
194 memset(buf
, 0, sizeof(buf
));
196 if (mbr
!= mbr_blank
) {
199 memcpy(buf
+ 0x1BE, mbr
== mbr_lba
? part_lba
: part_chs
, 16);
202 fd
= open(img_file_name
[img_idx
], O_WRONLY
);
204 ret
= write(fd
, buf
, sizeof(buf
));
205 g_assert(ret
== sizeof(buf
));
209 static int setup_ide(int argc
, char *argv
[], int argv_sz
,
210 int ide_idx
, const char *dev
, int img_idx
,
215 s1
= g_strdup_printf("-drive id=drive%d,if=%s",
216 ide_idx
, dev
? "none" : "ide");
217 s2
= dev
? g_strdup("") : g_strdup_printf(",index=%d", ide_idx
);
219 if (img_secs
[img_idx
] >= 0) {
220 setup_mbr(img_idx
, mbr
);
221 s3
= g_strdup_printf(",format=raw,file=%s", img_file_name
[img_idx
]);
223 s3
= g_strdup(",media=cdrom");
225 argc
= append_arg(argc
, argv
, argv_sz
,
226 g_strdup_printf("%s%s%s", s1
, s2
, s3
));
232 argc
= append_arg(argc
, argv
, argv_sz
,
233 g_strdup_printf("-device %s,drive=drive%d,"
234 "bus=ide.%d,unit=%d",
236 ide_idx
/ 2, ide_idx
% 2));
242 * Test case: no IDE devices
244 static void test_ide_none(void)
246 char **argv
= g_new0(char *, ARGV_SIZE
);
250 setup_common(argv
, ARGV_SIZE
);
251 args
= g_strjoinv(" ", argv
);
252 qts
= qtest_init(args
);
259 static void test_ide_mbr(bool use_device
, MBRcontents mbr
)
261 char **argv
= g_new0(char *, ARGV_SIZE
);
268 argc
= setup_common(argv
, ARGV_SIZE
);
269 for (i
= 0; i
< backend_last
; i
++) {
270 cur_ide
[i
] = &hd_chst
[i
][mbr
];
271 dev
= use_device
? (is_hd(cur_ide
[i
]) ? "ide-hd" : "ide-cd") : NULL
;
272 argc
= setup_ide(argc
, argv
, ARGV_SIZE
, i
, dev
, i
, mbr
);
274 args
= g_strjoinv(" ", argv
);
275 qts
= qtest_init(args
);
283 * Test case: IDE devices (if=ide) with blank MBRs
285 static void test_ide_drive_mbr_blank(void)
287 test_ide_mbr(false, mbr_blank
);
291 * Test case: IDE devices (if=ide) with MBRs indicating LBA is in use
293 static void test_ide_drive_mbr_lba(void)
295 test_ide_mbr(false, mbr_lba
);
299 * Test case: IDE devices (if=ide) with MBRs indicating CHS is in use
301 static void test_ide_drive_mbr_chs(void)
303 test_ide_mbr(false, mbr_chs
);
307 * Test case: IDE devices (if=none) with blank MBRs
309 static void test_ide_device_mbr_blank(void)
311 test_ide_mbr(true, mbr_blank
);
315 * Test case: IDE devices (if=none) with MBRs indicating LBA is in use
317 static void test_ide_device_mbr_lba(void)
319 test_ide_mbr(true, mbr_lba
);
323 * Test case: IDE devices (if=none) with MBRs indicating CHS is in use
325 static void test_ide_device_mbr_chs(void)
327 test_ide_mbr(true, mbr_chs
);
330 static void test_ide_drive_user(const char *dev
, bool trans
)
332 char **argv
= g_new0(char *, ARGV_SIZE
);
335 int secs
= img_secs
[backend_small
];
336 const CHST expected_chst
= { secs
/ (4 * 32) , 4, 32, trans
};
339 argc
= setup_common(argv
, ARGV_SIZE
);
340 opts
= g_strdup_printf("%s,%scyls=%d,heads=%d,secs=%d",
341 dev
, trans
? "bios-chs-trans=lba," : "",
342 expected_chst
.cyls
, expected_chst
.heads
,
344 cur_ide
[0] = &expected_chst
;
345 argc
= setup_ide(argc
, argv
, ARGV_SIZE
, 0, opts
, backend_small
, mbr_chs
);
347 args
= g_strjoinv(" ", argv
);
348 qts
= qtest_init(args
);
356 * Test case: IDE device (if=none) with explicit CHS
358 static void test_ide_device_user_chs(void)
360 test_ide_drive_user("ide-hd", false);
364 * Test case: IDE device (if=none) with explicit CHS and translation
366 static void test_ide_device_user_chst(void)
368 test_ide_drive_user("ide-hd", true);
372 * Test case: IDE devices (if=ide), but use index=0 for CD-ROM
374 static void test_ide_drive_cd_0(void)
376 char **argv
= g_new0(char *, ARGV_SIZE
);
382 argc
= setup_common(argv
, ARGV_SIZE
);
383 for (i
= 0; i
<= backend_empty
; i
++) {
384 ide_idx
= backend_empty
- i
;
385 cur_ide
[ide_idx
] = &hd_chst
[i
][mbr_blank
];
386 argc
= setup_ide(argc
, argv
, ARGV_SIZE
, ide_idx
, NULL
, i
, mbr_blank
);
388 args
= g_strjoinv(" ", argv
);
389 qts
= qtest_init(args
);
408 static MBRpartitions empty_mbr
= { {false, 0, 0, 0, 0, 0, 0, 0, 0},
409 {false, 0, 0, 0, 0, 0, 0, 0, 0},
410 {false, 0, 0, 0, 0, 0, 0, 0, 0},
411 {false, 0, 0, 0, 0, 0, 0, 0, 0} };
413 static char *create_qcow2_with_mbr(MBRpartitions mbr
, uint64_t sectors
)
415 const char *template = "/tmp/qtest.XXXXXX";
416 char *raw_path
= strdup(template);
417 char *qcow2_path
= strdup(template);
418 char cmd
[100 + 2 * PATH_MAX
];
420 int i
, ret
, fd
, offset
;
421 uint64_t qcow2_size
= sectors
* 512;
422 uint8_t status
, parttype
, head
, sector
, cyl
;
424 char *qemu_img_abs_path
;
428 for (i
= 0; i
< 4; i
++) {
429 status
= mbr
[i
].active
? 0x80 : 0x00;
430 g_assert(mbr
[i
].head
< 256);
431 g_assert(mbr
[i
].sector
< 64);
432 g_assert(mbr
[i
].cyl
< 1024);
434 sector
= mbr
[i
].sector
+ ((mbr
[i
].cyl
& 0x300) >> 2);
435 cyl
= mbr
[i
].cyl
& 0xff;
437 buf
[offset
+ 0x0] = status
;
438 buf
[offset
+ 0x1] = head
;
439 buf
[offset
+ 0x2] = sector
;
440 buf
[offset
+ 0x3] = cyl
;
443 g_assert(mbr
[i
].end_head
< 256);
444 g_assert(mbr
[i
].end_sector
< 64);
445 g_assert(mbr
[i
].end_cyl
< 1024);
446 head
= mbr
[i
].end_head
;
447 sector
= mbr
[i
].end_sector
+ ((mbr
[i
].end_cyl
& 0x300) >> 2);
448 cyl
= mbr
[i
].end_cyl
& 0xff;
450 buf
[offset
+ 0x4] = parttype
;
451 buf
[offset
+ 0x5] = head
;
452 buf
[offset
+ 0x6] = sector
;
453 buf
[offset
+ 0x7] = cyl
;
455 (*(uint32_t *)&buf
[offset
+ 0x8]) = cpu_to_le32(mbr
[i
].start_sect
);
456 (*(uint32_t *)&buf
[offset
+ 0xc]) = cpu_to_le32(mbr
[i
].nr_sects
);
461 fd
= mkstemp(raw_path
);
465 fd
= open(raw_path
, O_WRONLY
);
467 ret
= write(fd
, buf
, sizeof(buf
));
468 g_assert(ret
== sizeof(buf
));
471 fd
= mkstemp(qcow2_path
);
475 qemu_img_path
= getenv("QTEST_QEMU_IMG");
476 g_assert(qemu_img_path
);
477 qemu_img_abs_path
= realpath(qemu_img_path
, NULL
);
478 g_assert(qemu_img_abs_path
);
480 ret
= snprintf(cmd
, sizeof(cmd
),
481 "%s convert -f raw -O qcow2 %s %s > /dev/null",
483 raw_path
, qcow2_path
);
484 g_assert((0 < ret
) && (ret
<= sizeof(cmd
)));
488 ret
= snprintf(cmd
, sizeof(cmd
),
489 "%s resize %s %" PRIu64
" > /dev/null",
491 qcow2_path
, qcow2_size
);
492 g_assert((0 < ret
) && (ret
<= sizeof(cmd
)));
496 free(qemu_img_abs_path
);
504 #define BIOS_GEOMETRY_MAX_SIZE 10000
513 const char *dev_path
;
517 static void read_bootdevices(QFWCFG
*fw_cfg
, CHSResult expected
[])
519 char *buf
= g_malloc0(BIOS_GEOMETRY_MAX_SIZE
);
521 GList
*results
= NULL
, *cur_result
;
527 qfw_cfg_get_file(fw_cfg
, "bios-geometry", buf
, BIOS_GEOMETRY_MAX_SIZE
);
529 for (cur
= buf
; *cur
; cur
++) {
536 while (strlen(cur
)) {
538 r
= g_malloc0(sizeof(*r
));
539 r
->dev_path
= g_malloc0(strlen(cur
) + 1);
540 res
= sscanf(cur
, "%s %" PRIu32
" %" PRIu32
" %" PRIu32
,
542 &(r
->chs
.c
), &(r
->chs
.h
), &(r
->chs
.s
));
546 results
= g_list_prepend(results
, r
);
548 cur
+= strlen(cur
) + 1;
553 while (expected
[i
].dev_path
) {
555 cur_result
= results
;
557 r
= cur_result
->data
;
558 if (!strcmp(r
->dev_path
, expected
[i
].dev_path
) &&
559 !memcmp(&(r
->chs
), &(expected
[i
].chs
), sizeof(r
->chs
))) {
563 cur_result
= g_list_next(cur_result
);
566 g_free((char *)((CHSResult
*)cur_result
->data
)->dev_path
);
567 g_free(cur_result
->data
);
568 results
= g_list_delete_link(results
, cur_result
);
572 g_assert(results
== NULL
);
577 #define MAX_DRIVES 30
585 int n_scsi_controllers
;
589 static TestArgs
*create_args(void)
591 TestArgs
*args
= g_malloc0(sizeof(*args
));
592 args
->argv
= g_new0(char *, ARGV_SIZE
);
593 args
->argc
= append_arg(args
->argc
, args
->argv
,
594 ARGV_SIZE
, g_strdup("-nodefaults"));
595 args
->drives
= g_new0(char *, MAX_DRIVES
);
599 static void add_drive_with_mbr(TestArgs
*args
,
600 MBRpartitions mbr
, uint64_t sectors
)
606 g_assert(args
->n_drives
< MAX_DRIVES
);
608 img_file_name
= create_qcow2_with_mbr(mbr
, sectors
);
610 args
->drives
[args
->n_drives
] = img_file_name
;
611 ret
= snprintf(part
, sizeof(part
),
612 "-drive file=%s,if=none,format=qcow2,id=disk%d",
613 img_file_name
, args
->n_drives
);
614 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
615 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
619 static void add_ide_disk(TestArgs
*args
,
620 int drive_idx
, int bus
, int unit
, int c
, int h
, int s
)
625 ret
= snprintf(part
, sizeof(part
),
626 "-device ide-hd,drive=disk%d,bus=ide.%d,unit=%d,"
627 "lcyls=%d,lheads=%d,lsecs=%d",
628 drive_idx
, bus
, unit
, c
, h
, s
);
629 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
630 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
633 static void add_scsi_controller(TestArgs
*args
,
641 ret
= snprintf(part
, sizeof(part
),
642 "-device %s,id=scsi%d,bus=%s,addr=%d",
643 type
, args
->n_scsi_controllers
, bus
, addr
);
644 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
645 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
646 args
->n_scsi_controllers
++;
649 static void add_scsi_disk(TestArgs
*args
,
650 int drive_idx
, int bus
,
651 int channel
, int scsi_id
, int lun
,
657 ret
= snprintf(part
, sizeof(part
),
658 "-device scsi-hd,id=scsi-disk%d,drive=disk%d,"
660 "channel=%d,scsi-id=%d,lun=%d,"
661 "lcyls=%d,lheads=%d,lsecs=%d",
662 args
->n_scsi_disks
, drive_idx
, bus
, channel
, scsi_id
, lun
,
664 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
665 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
666 args
->n_scsi_disks
++;
669 static void add_virtio_disk(TestArgs
*args
,
670 int drive_idx
, const char *bus
, int addr
,
676 ret
= snprintf(part
, sizeof(part
),
677 "-device virtio-blk-pci,id=virtio-disk%d,"
678 "drive=disk%d,bus=%s,addr=%d,"
679 "lcyls=%d,lheads=%d,lsecs=%d",
680 args
->n_virtio_disks
, drive_idx
, bus
, addr
, c
, h
, s
);
681 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
682 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
683 args
->n_virtio_disks
++;
686 static void test_override(TestArgs
*args
, CHSResult expected
[])
693 joined_args
= g_strjoinv(" ", args
->argv
);
695 qts
= qtest_init(joined_args
);
696 fw_cfg
= pc_fw_cfg_init(qts
);
698 read_bootdevices(fw_cfg
, expected
);
705 for (i
= 0; i
< args
->n_drives
; i
++) {
706 unlink(args
->drives
[i
]);
707 free(args
->drives
[i
]);
709 g_free(args
->drives
);
710 g_strfreev(args
->argv
);
714 static void test_override_ide(void)
716 TestArgs
*args
= create_args();
717 CHSResult expected
[] = {
718 {"/pci@i0cf8/ide@1,1/drive@0/disk@0", {10000, 120, 30} },
719 {"/pci@i0cf8/ide@1,1/drive@0/disk@1", {9000, 120, 30} },
720 {"/pci@i0cf8/ide@1,1/drive@1/disk@0", {0, 1, 1} },
721 {"/pci@i0cf8/ide@1,1/drive@1/disk@1", {1, 0, 0} },
724 add_drive_with_mbr(args
, empty_mbr
, 1);
725 add_drive_with_mbr(args
, empty_mbr
, 1);
726 add_drive_with_mbr(args
, empty_mbr
, 1);
727 add_drive_with_mbr(args
, empty_mbr
, 1);
728 add_ide_disk(args
, 0, 0, 0, 10000, 120, 30);
729 add_ide_disk(args
, 1, 0, 1, 9000, 120, 30);
730 add_ide_disk(args
, 2, 1, 0, 0, 1, 1);
731 add_ide_disk(args
, 3, 1, 1, 1, 0, 0);
732 test_override(args
, expected
);
735 static void test_override_scsi(void)
737 TestArgs
*args
= create_args();
738 CHSResult expected
[] = {
739 {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
740 {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
741 {"/pci@i0cf8/scsi@3/channel@0/disk@2,0", {1, 0, 0} },
742 {"/pci@i0cf8/scsi@3/channel@0/disk@3,0", {0, 1, 0} },
745 add_drive_with_mbr(args
, empty_mbr
, 1);
746 add_drive_with_mbr(args
, empty_mbr
, 1);
747 add_drive_with_mbr(args
, empty_mbr
, 1);
748 add_drive_with_mbr(args
, empty_mbr
, 1);
749 add_scsi_controller(args
, "lsi53c895a", "pci.0", 3);
750 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
751 add_scsi_disk(args
, 1, 0, 0, 1, 0, 9000, 120, 30);
752 add_scsi_disk(args
, 2, 0, 0, 2, 0, 1, 0, 0);
753 add_scsi_disk(args
, 3, 0, 0, 3, 0, 0, 1, 0);
754 test_override(args
, expected
);
757 static void test_override_scsi_2_controllers(void)
759 TestArgs
*args
= create_args();
760 CHSResult expected
[] = {
761 {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
762 {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
763 {"/pci@i0cf8/scsi@4/channel@0/disk@0,1", {1, 0, 0} },
764 {"/pci@i0cf8/scsi@4/channel@0/disk@1,2", {0, 1, 0} },
767 add_drive_with_mbr(args
, empty_mbr
, 1);
768 add_drive_with_mbr(args
, empty_mbr
, 1);
769 add_drive_with_mbr(args
, empty_mbr
, 1);
770 add_drive_with_mbr(args
, empty_mbr
, 1);
771 add_scsi_controller(args
, "lsi53c895a", "pci.0", 3);
772 add_scsi_controller(args
, "virtio-scsi-pci", "pci.0", 4);
773 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
774 add_scsi_disk(args
, 1, 0, 0, 1, 0, 9000, 120, 30);
775 add_scsi_disk(args
, 2, 1, 0, 0, 1, 1, 0, 0);
776 add_scsi_disk(args
, 3, 1, 0, 1, 2, 0, 1, 0);
777 test_override(args
, expected
);
780 static void test_override_virtio_blk(void)
782 TestArgs
*args
= create_args();
783 CHSResult expected
[] = {
784 {"/pci@i0cf8/scsi@3/disk@0,0", {10000, 120, 30} },
785 {"/pci@i0cf8/scsi@4/disk@0,0", {9000, 120, 30} },
788 add_drive_with_mbr(args
, empty_mbr
, 1);
789 add_drive_with_mbr(args
, empty_mbr
, 1);
790 add_virtio_disk(args
, 0, "pci.0", 3, 10000, 120, 30);
791 add_virtio_disk(args
, 1, "pci.0", 4, 9000, 120, 30);
792 test_override(args
, expected
);
795 static void test_override_zero_chs(void)
797 TestArgs
*args
= create_args();
798 CHSResult expected
[] = {
801 add_drive_with_mbr(args
, empty_mbr
, 1);
802 add_ide_disk(args
, 0, 1, 1, 0, 0, 0);
803 test_override(args
, expected
);
806 static void test_override_scsi_hot_unplug(void)
813 TestArgs
*args
= create_args();
814 CHSResult expected
[] = {
815 {"/pci@i0cf8/scsi@2/channel@0/disk@0,0", {10000, 120, 30} },
816 {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
819 CHSResult expected2
[] = {
820 {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
823 add_drive_with_mbr(args
, empty_mbr
, 1);
824 add_drive_with_mbr(args
, empty_mbr
, 1);
825 add_scsi_controller(args
, "virtio-scsi-pci", "pci.0", 2);
826 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
827 add_scsi_disk(args
, 1, 0, 0, 1, 0, 20, 20, 20);
829 joined_args
= g_strjoinv(" ", args
->argv
);
831 qts
= qtest_init(joined_args
);
832 fw_cfg
= pc_fw_cfg_init(qts
);
834 read_bootdevices(fw_cfg
, expected
);
836 /* unplug device an restart */
837 response
= qtest_qmp(qts
,
838 "{ 'execute': 'device_del',"
839 " 'arguments': {'id': 'scsi-disk0' }}");
841 g_assert(!qdict_haskey(response
, "error"));
842 qobject_unref(response
);
843 response
= qtest_qmp(qts
,
844 "{ 'execute': 'system_reset', 'arguments': { }}");
846 g_assert(!qdict_haskey(response
, "error"));
847 qobject_unref(response
);
849 qtest_qmp_eventwait(qts
, "RESET");
851 read_bootdevices(fw_cfg
, expected2
);
858 for (i
= 0; i
< args
->n_drives
; i
++) {
859 unlink(args
->drives
[i
]);
860 free(args
->drives
[i
]);
862 g_free(args
->drives
);
863 g_strfreev(args
->argv
);
867 static void test_override_virtio_hot_unplug(void)
874 TestArgs
*args
= create_args();
875 CHSResult expected
[] = {
876 {"/pci@i0cf8/scsi@2/disk@0,0", {10000, 120, 30} },
877 {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
880 CHSResult expected2
[] = {
881 {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
884 add_drive_with_mbr(args
, empty_mbr
, 1);
885 add_drive_with_mbr(args
, empty_mbr
, 1);
886 add_virtio_disk(args
, 0, "pci.0", 2, 10000, 120, 30);
887 add_virtio_disk(args
, 1, "pci.0", 3, 20, 20, 20);
889 joined_args
= g_strjoinv(" ", args
->argv
);
891 qts
= qtest_init(joined_args
);
892 fw_cfg
= pc_fw_cfg_init(qts
);
894 read_bootdevices(fw_cfg
, expected
);
896 /* unplug device an restart */
897 response
= qtest_qmp(qts
,
898 "{ 'execute': 'device_del',"
899 " 'arguments': {'id': 'virtio-disk0' }}");
901 g_assert(!qdict_haskey(response
, "error"));
902 qobject_unref(response
);
903 response
= qtest_qmp(qts
,
904 "{ 'execute': 'system_reset', 'arguments': { }}");
906 g_assert(!qdict_haskey(response
, "error"));
907 qobject_unref(response
);
909 qtest_qmp_eventwait(qts
, "RESET");
911 read_bootdevices(fw_cfg
, expected2
);
918 for (i
= 0; i
< args
->n_drives
; i
++) {
919 unlink(args
->drives
[i
]);
920 free(args
->drives
[i
]);
922 g_free(args
->drives
);
923 g_strfreev(args
->argv
);
927 int main(int argc
, char **argv
)
932 g_test_init(&argc
, &argv
, NULL
);
934 for (i
= 0; i
< backend_last
; i
++) {
935 if (img_secs
[i
] >= 0) {
936 img_file_name
[i
] = create_test_img(img_secs
[i
]);
938 img_file_name
[i
] = NULL
;
942 qtest_add_func("hd-geo/ide/none", test_ide_none
);
943 qtest_add_func("hd-geo/ide/drive/mbr/blank", test_ide_drive_mbr_blank
);
944 qtest_add_func("hd-geo/ide/drive/mbr/lba", test_ide_drive_mbr_lba
);
945 qtest_add_func("hd-geo/ide/drive/mbr/chs", test_ide_drive_mbr_chs
);
946 qtest_add_func("hd-geo/ide/drive/cd_0", test_ide_drive_cd_0
);
947 qtest_add_func("hd-geo/ide/device/mbr/blank", test_ide_device_mbr_blank
);
948 qtest_add_func("hd-geo/ide/device/mbr/lba", test_ide_device_mbr_lba
);
949 qtest_add_func("hd-geo/ide/device/mbr/chs", test_ide_device_mbr_chs
);
950 qtest_add_func("hd-geo/ide/device/user/chs", test_ide_device_user_chs
);
951 qtest_add_func("hd-geo/ide/device/user/chst", test_ide_device_user_chst
);
952 if (have_qemu_img()) {
953 qtest_add_func("hd-geo/override/ide", test_override_ide
);
954 qtest_add_func("hd-geo/override/scsi", test_override_scsi
);
955 qtest_add_func("hd-geo/override/scsi_2_controllers",
956 test_override_scsi_2_controllers
);
957 qtest_add_func("hd-geo/override/virtio_blk", test_override_virtio_blk
);
958 qtest_add_func("hd-geo/override/zero_chs", test_override_zero_chs
);
959 qtest_add_func("hd-geo/override/scsi_hot_unplug",
960 test_override_scsi_hot_unplug
);
961 qtest_add_func("hd-geo/override/virtio_hot_unplug",
962 test_override_virtio_hot_unplug
);
964 g_test_message("QTEST_QEMU_IMG not set or qemu-img missing; "
965 "skipping hd-geo/override/* tests");
970 for (i
= 0; i
< backend_last
; i
++) {
971 if (img_file_name
[i
]) {
972 unlink(img_file_name
[i
]);
973 free(img_file_name
[i
]);