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);
48 int cyls
, heads
, secs
, trans
;
52 mbr_blank
, mbr_lba
, mbr_chs
,
57 /* order is relevant */
58 backend_small
, backend_large
, backend_empty
,
62 static const int img_secs
[backend_last
] = {
63 [backend_small
] = 61440,
64 [backend_large
] = 8388608,
68 static const CHST hd_chst
[backend_last
][mbr_last
] = {
70 [mbr_blank
] = { 60, 16, 63, 0 },
71 [mbr_lba
] = { 60, 16, 63, 2 },
72 [mbr_chs
] = { 60, 16, 63, 0 }
75 [mbr_blank
] = { 8322, 16, 63, 1 },
76 [mbr_lba
] = { 8322, 16, 63, 1 },
77 [mbr_chs
] = { 8322, 16, 63, 0 }
81 static char *img_file_name
[backend_last
];
83 static const CHST
*cur_ide
[4];
85 static bool is_hd(const CHST
*expected_chst
)
87 return expected_chst
&& expected_chst
->cyls
;
90 static void test_cmos_byte(QTestState
*qts
, int reg
, int expected
)
92 enum { cmos_base
= 0x70 };
95 qtest_outb(qts
, cmos_base
+ 0, reg
);
96 actual
= qtest_inb(qts
, cmos_base
+ 1);
97 g_assert(actual
== expected
);
100 static void test_cmos_bytes(QTestState
*qts
, int reg0
, int n
,
105 for (i
= 0; i
< 9; i
++) {
106 test_cmos_byte(qts
, reg0
+ i
, expected
[i
]);
110 static void test_cmos_disk_data(QTestState
*qts
)
112 test_cmos_byte(qts
, 0x12,
113 (is_hd(cur_ide
[0]) ? 0xf0 : 0) |
114 (is_hd(cur_ide
[1]) ? 0x0f : 0));
117 static void test_cmos_drive_cyl(QTestState
*qts
, int reg0
,
118 const CHST
*expected_chst
)
120 if (is_hd(expected_chst
)) {
121 int c
= expected_chst
->cyls
;
122 int h
= expected_chst
->heads
;
123 int s
= expected_chst
->secs
;
124 uint8_t expected_bytes
[9] = {
125 c
& 0xff, c
>> 8, h
, 0xff, 0xff, 0xc0 | ((h
> 8) << 3),
128 test_cmos_bytes(qts
, reg0
, 9, expected_bytes
);
132 for (i
= 0; i
< 9; i
++) {
133 test_cmos_byte(qts
, reg0
+ i
, 0);
138 static void test_cmos_drive1(QTestState
*qts
)
140 test_cmos_byte(qts
, 0x19, is_hd(cur_ide
[0]) ? 47 : 0);
141 test_cmos_drive_cyl(qts
, 0x1b, cur_ide
[0]);
144 static void test_cmos_drive2(QTestState
*qts
)
146 test_cmos_byte(qts
, 0x1a, is_hd(cur_ide
[1]) ? 47 : 0);
147 test_cmos_drive_cyl(qts
, 0x24, cur_ide
[1]);
150 static void test_cmos_disktransflag(QTestState
*qts
)
155 for (i
= 0; i
< ARRAY_SIZE(cur_ide
); i
++) {
156 if (is_hd(cur_ide
[i
])) {
157 val
|= cur_ide
[i
]->trans
<< (2 * i
);
160 test_cmos_byte(qts
, 0x39, val
);
163 static void test_cmos(QTestState
*qts
)
165 test_cmos_disk_data(qts
);
166 test_cmos_drive1(qts
);
167 test_cmos_drive2(qts
);
168 test_cmos_disktransflag(qts
);
171 static int append_arg(int argc
, char *argv
[], int argv_sz
, char *arg
)
173 g_assert(argc
+ 1 < argv_sz
);
179 static int setup_common(char *argv
[], int argv_sz
)
181 memset(cur_ide
, 0, sizeof(cur_ide
));
182 return append_arg(0, argv
, argv_sz
,
183 g_strdup("-nodefaults"));
186 static void setup_mbr(int img_idx
, MBRcontents mbr
)
188 static const uint8_t part_lba
[16] = {
189 /* chs 0,1,1 (lba 63) to chs 0,127,63 (8001 sectors) */
190 0x80, 1, 1, 0, 6, 127, 63, 0, 63, 0, 0, 0, 0x41, 0x1F, 0, 0,
192 static const uint8_t part_chs
[16] = {
193 /* chs 0,1,1 (lba 63) to chs 7,15,63 (8001 sectors) */
194 0x80, 1, 1, 0, 6, 15, 63, 7, 63, 0, 0, 0, 0x41, 0x1F, 0, 0,
199 memset(buf
, 0, sizeof(buf
));
201 if (mbr
!= mbr_blank
) {
204 memcpy(buf
+ 0x1BE, mbr
== mbr_lba
? part_lba
: part_chs
, 16);
207 fd
= open(img_file_name
[img_idx
], O_WRONLY
);
209 ret
= write(fd
, buf
, sizeof(buf
));
210 g_assert(ret
== sizeof(buf
));
214 static int setup_ide(int argc
, char *argv
[], int argv_sz
,
215 int ide_idx
, const char *dev
, int img_idx
,
220 s1
= g_strdup_printf("-drive id=drive%d,if=%s",
221 ide_idx
, dev
? "none" : "ide");
222 s2
= dev
? g_strdup("") : g_strdup_printf(",index=%d", ide_idx
);
224 if (img_secs
[img_idx
] >= 0) {
225 setup_mbr(img_idx
, mbr
);
226 s3
= g_strdup_printf(",format=raw,file=%s", img_file_name
[img_idx
]);
228 s3
= g_strdup(",media=cdrom");
230 argc
= append_arg(argc
, argv
, argv_sz
,
231 g_strdup_printf("%s%s%s", s1
, s2
, s3
));
237 argc
= append_arg(argc
, argv
, argv_sz
,
238 g_strdup_printf("-device %s,drive=drive%d,"
239 "bus=ide.%d,unit=%d",
241 ide_idx
/ 2, ide_idx
% 2));
247 * Test case: no IDE devices
249 static void test_ide_none(void)
251 char **argv
= g_new0(char *, ARGV_SIZE
);
255 setup_common(argv
, ARGV_SIZE
);
256 args
= g_strjoinv(" ", argv
);
257 qts
= qtest_init(args
);
264 static void test_ide_mbr(bool use_device
, MBRcontents mbr
)
266 char **argv
= g_new0(char *, ARGV_SIZE
);
273 argc
= setup_common(argv
, ARGV_SIZE
);
274 for (i
= 0; i
< backend_last
; i
++) {
275 cur_ide
[i
] = &hd_chst
[i
][mbr
];
276 dev
= use_device
? (is_hd(cur_ide
[i
]) ? "ide-hd" : "ide-cd") : NULL
;
277 argc
= setup_ide(argc
, argv
, ARGV_SIZE
, i
, dev
, i
, mbr
);
279 args
= g_strjoinv(" ", argv
);
280 qts
= qtest_init(args
);
288 * Test case: IDE devices (if=ide) with blank MBRs
290 static void test_ide_drive_mbr_blank(void)
292 test_ide_mbr(false, mbr_blank
);
296 * Test case: IDE devices (if=ide) with MBRs indicating LBA is in use
298 static void test_ide_drive_mbr_lba(void)
300 test_ide_mbr(false, mbr_lba
);
304 * Test case: IDE devices (if=ide) with MBRs indicating CHS is in use
306 static void test_ide_drive_mbr_chs(void)
308 test_ide_mbr(false, mbr_chs
);
312 * Test case: IDE devices (if=none) with blank MBRs
314 static void test_ide_device_mbr_blank(void)
316 test_ide_mbr(true, mbr_blank
);
320 * Test case: IDE devices (if=none) with MBRs indicating LBA is in use
322 static void test_ide_device_mbr_lba(void)
324 test_ide_mbr(true, mbr_lba
);
328 * Test case: IDE devices (if=none) with MBRs indicating CHS is in use
330 static void test_ide_device_mbr_chs(void)
332 test_ide_mbr(true, mbr_chs
);
335 static void test_ide_drive_user(const char *dev
, bool trans
)
337 char **argv
= g_new0(char *, ARGV_SIZE
);
340 int secs
= img_secs
[backend_small
];
341 const CHST expected_chst
= { secs
/ (4 * 32) , 4, 32, trans
};
344 argc
= setup_common(argv
, ARGV_SIZE
);
345 opts
= g_strdup_printf("%s,%scyls=%d,heads=%d,secs=%d",
346 dev
, trans
? "bios-chs-trans=lba," : "",
347 expected_chst
.cyls
, expected_chst
.heads
,
349 cur_ide
[0] = &expected_chst
;
350 argc
= setup_ide(argc
, argv
, ARGV_SIZE
, 0, opts
, backend_small
, mbr_chs
);
352 args
= g_strjoinv(" ", argv
);
353 qts
= qtest_init(args
);
361 * Test case: IDE device (if=none) with explicit CHS
363 static void test_ide_device_user_chs(void)
365 test_ide_drive_user("ide-hd", false);
369 * Test case: IDE device (if=none) with explicit CHS and translation
371 static void test_ide_device_user_chst(void)
373 test_ide_drive_user("ide-hd", true);
377 * Test case: IDE devices (if=ide), but use index=0 for CD-ROM
379 static void test_ide_drive_cd_0(void)
381 char **argv
= g_new0(char *, ARGV_SIZE
);
387 argc
= setup_common(argv
, ARGV_SIZE
);
388 for (i
= 0; i
<= backend_empty
; i
++) {
389 ide_idx
= backend_empty
- i
;
390 cur_ide
[ide_idx
] = &hd_chst
[i
][mbr_blank
];
391 argc
= setup_ide(argc
, argv
, ARGV_SIZE
, ide_idx
, NULL
, i
, mbr_blank
);
393 args
= g_strjoinv(" ", argv
);
394 qts
= qtest_init(args
);
413 static MBRpartitions empty_mbr
= { {false, 0, 0, 0, 0, 0, 0, 0, 0},
414 {false, 0, 0, 0, 0, 0, 0, 0, 0},
415 {false, 0, 0, 0, 0, 0, 0, 0, 0},
416 {false, 0, 0, 0, 0, 0, 0, 0, 0} };
418 static char *create_qcow2_with_mbr(MBRpartitions mbr
, uint64_t sectors
)
420 const char *template = "/tmp/qtest.XXXXXX";
421 char *raw_path
= strdup(template);
422 char *qcow2_path
= strdup(template);
423 char cmd
[100 + 2 * PATH_MAX
];
424 uint8_t buf
[512] = {};
425 int i
, ret
, fd
, offset
;
426 uint64_t qcow2_size
= sectors
* 512;
427 uint8_t status
, parttype
, head
, sector
, cyl
;
429 char *qemu_img_abs_path
;
433 for (i
= 0; i
< 4; i
++) {
434 status
= mbr
[i
].active
? 0x80 : 0x00;
435 g_assert(mbr
[i
].head
< 256);
436 g_assert(mbr
[i
].sector
< 64);
437 g_assert(mbr
[i
].cyl
< 1024);
439 sector
= mbr
[i
].sector
+ ((mbr
[i
].cyl
& 0x300) >> 2);
440 cyl
= mbr
[i
].cyl
& 0xff;
442 buf
[offset
+ 0x0] = status
;
443 buf
[offset
+ 0x1] = head
;
444 buf
[offset
+ 0x2] = sector
;
445 buf
[offset
+ 0x3] = cyl
;
448 g_assert(mbr
[i
].end_head
< 256);
449 g_assert(mbr
[i
].end_sector
< 64);
450 g_assert(mbr
[i
].end_cyl
< 1024);
451 head
= mbr
[i
].end_head
;
452 sector
= mbr
[i
].end_sector
+ ((mbr
[i
].end_cyl
& 0x300) >> 2);
453 cyl
= mbr
[i
].end_cyl
& 0xff;
455 buf
[offset
+ 0x4] = parttype
;
456 buf
[offset
+ 0x5] = head
;
457 buf
[offset
+ 0x6] = sector
;
458 buf
[offset
+ 0x7] = cyl
;
460 stl_le_p(&buf
[offset
+ 0x8], mbr
[i
].start_sect
);
461 stl_le_p(&buf
[offset
+ 0xc], mbr
[i
].nr_sects
);
466 fd
= mkstemp(raw_path
);
470 fd
= open(raw_path
, O_WRONLY
);
472 ret
= write(fd
, buf
, sizeof(buf
));
473 g_assert(ret
== sizeof(buf
));
476 fd
= mkstemp(qcow2_path
);
480 qemu_img_path
= getenv("QTEST_QEMU_IMG");
481 g_assert(qemu_img_path
);
482 qemu_img_abs_path
= realpath(qemu_img_path
, NULL
);
483 g_assert(qemu_img_abs_path
);
485 ret
= snprintf(cmd
, sizeof(cmd
),
486 "%s convert -f raw -O qcow2 %s %s > /dev/null",
488 raw_path
, qcow2_path
);
489 g_assert((0 < ret
) && (ret
<= sizeof(cmd
)));
493 ret
= snprintf(cmd
, sizeof(cmd
),
494 "%s resize %s %" PRIu64
" > /dev/null",
496 qcow2_path
, qcow2_size
);
497 g_assert((0 < ret
) && (ret
<= sizeof(cmd
)));
501 free(qemu_img_abs_path
);
509 #define BIOS_GEOMETRY_MAX_SIZE 10000
518 const char *dev_path
;
522 static void read_bootdevices(QFWCFG
*fw_cfg
, CHSResult expected
[])
524 char *buf
= g_malloc0(BIOS_GEOMETRY_MAX_SIZE
);
526 GList
*results
= NULL
, *cur_result
;
532 qfw_cfg_get_file(fw_cfg
, "bios-geometry", buf
, BIOS_GEOMETRY_MAX_SIZE
);
534 for (cur
= buf
; *cur
; cur
++) {
541 while (strlen(cur
)) {
543 r
= g_malloc0(sizeof(*r
));
544 r
->dev_path
= g_malloc0(strlen(cur
) + 1);
545 res
= sscanf(cur
, "%s %" PRIu32
" %" PRIu32
" %" PRIu32
,
547 &(r
->chs
.c
), &(r
->chs
.h
), &(r
->chs
.s
));
551 results
= g_list_prepend(results
, r
);
553 cur
+= strlen(cur
) + 1;
558 while (expected
[i
].dev_path
) {
560 cur_result
= results
;
562 r
= cur_result
->data
;
563 if (!strcmp(r
->dev_path
, expected
[i
].dev_path
) &&
564 !memcmp(&(r
->chs
), &(expected
[i
].chs
), sizeof(r
->chs
))) {
568 cur_result
= g_list_next(cur_result
);
571 g_free((char *)((CHSResult
*)cur_result
->data
)->dev_path
);
572 g_free(cur_result
->data
);
573 results
= g_list_delete_link(results
, cur_result
);
577 g_assert(results
== NULL
);
582 #define MAX_DRIVES 30
590 int n_scsi_controllers
;
594 static TestArgs
*create_args(void)
596 TestArgs
*args
= g_malloc0(sizeof(*args
));
597 args
->argv
= g_new0(char *, ARGV_SIZE
);
598 args
->argc
= append_arg(args
->argc
, args
->argv
,
599 ARGV_SIZE
, g_strdup("-nodefaults"));
600 args
->drives
= g_new0(char *, MAX_DRIVES
);
604 static void add_drive_with_mbr(TestArgs
*args
,
605 MBRpartitions mbr
, uint64_t sectors
)
611 g_assert(args
->n_drives
< MAX_DRIVES
);
613 img_file_name
= create_qcow2_with_mbr(mbr
, sectors
);
615 args
->drives
[args
->n_drives
] = img_file_name
;
616 ret
= snprintf(part
, sizeof(part
),
617 "-drive file=%s,if=none,format=qcow2,id=disk%d",
618 img_file_name
, args
->n_drives
);
619 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
620 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
624 static void add_ide_disk(TestArgs
*args
,
625 int drive_idx
, int bus
, int unit
, int c
, int h
, int s
)
630 ret
= snprintf(part
, sizeof(part
),
631 "-device ide-hd,drive=disk%d,bus=ide.%d,unit=%d,"
632 "lcyls=%d,lheads=%d,lsecs=%d",
633 drive_idx
, bus
, unit
, c
, h
, s
);
634 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
635 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
638 static void add_scsi_controller(TestArgs
*args
,
646 ret
= snprintf(part
, sizeof(part
),
647 "-device %s,id=scsi%d,bus=%s,addr=%d",
648 type
, args
->n_scsi_controllers
, bus
, addr
);
649 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
650 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
651 args
->n_scsi_controllers
++;
654 static void add_scsi_disk(TestArgs
*args
,
655 int drive_idx
, int bus
,
656 int channel
, int scsi_id
, int lun
,
662 ret
= snprintf(part
, sizeof(part
),
663 "-device scsi-hd,id=scsi-disk%d,drive=disk%d,"
665 "channel=%d,scsi-id=%d,lun=%d,"
666 "lcyls=%d,lheads=%d,lsecs=%d",
667 args
->n_scsi_disks
, drive_idx
, bus
, channel
, scsi_id
, lun
,
669 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
670 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
671 args
->n_scsi_disks
++;
674 static void add_virtio_disk(TestArgs
*args
,
675 int drive_idx
, const char *bus
, int addr
,
681 ret
= snprintf(part
, sizeof(part
),
682 "-device virtio-blk-pci,id=virtio-disk%d,"
683 "drive=disk%d,bus=%s,addr=%d,"
684 "lcyls=%d,lheads=%d,lsecs=%d",
685 args
->n_virtio_disks
, drive_idx
, bus
, addr
, c
, h
, s
);
686 g_assert((0 < ret
) && (ret
<= sizeof(part
)));
687 args
->argc
= append_arg(args
->argc
, args
->argv
, ARGV_SIZE
, g_strdup(part
));
688 args
->n_virtio_disks
++;
691 static void test_override(TestArgs
*args
, CHSResult expected
[])
698 joined_args
= g_strjoinv(" ", args
->argv
);
700 qts
= qtest_init(joined_args
);
701 fw_cfg
= pc_fw_cfg_init(qts
);
703 read_bootdevices(fw_cfg
, expected
);
710 for (i
= 0; i
< args
->n_drives
; i
++) {
711 unlink(args
->drives
[i
]);
712 free(args
->drives
[i
]);
714 g_free(args
->drives
);
715 g_strfreev(args
->argv
);
719 static void test_override_ide(void)
721 TestArgs
*args
= create_args();
722 CHSResult expected
[] = {
723 {"/pci@i0cf8/ide@1,1/drive@0/disk@0", {10000, 120, 30} },
724 {"/pci@i0cf8/ide@1,1/drive@0/disk@1", {9000, 120, 30} },
725 {"/pci@i0cf8/ide@1,1/drive@1/disk@0", {0, 1, 1} },
726 {"/pci@i0cf8/ide@1,1/drive@1/disk@1", {1, 0, 0} },
729 add_drive_with_mbr(args
, empty_mbr
, 1);
730 add_drive_with_mbr(args
, empty_mbr
, 1);
731 add_drive_with_mbr(args
, empty_mbr
, 1);
732 add_drive_with_mbr(args
, empty_mbr
, 1);
733 add_ide_disk(args
, 0, 0, 0, 10000, 120, 30);
734 add_ide_disk(args
, 1, 0, 1, 9000, 120, 30);
735 add_ide_disk(args
, 2, 1, 0, 0, 1, 1);
736 add_ide_disk(args
, 3, 1, 1, 1, 0, 0);
737 test_override(args
, expected
);
740 static void test_override_scsi(void)
742 TestArgs
*args
= create_args();
743 CHSResult expected
[] = {
744 {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
745 {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
746 {"/pci@i0cf8/scsi@3/channel@0/disk@2,0", {1, 0, 0} },
747 {"/pci@i0cf8/scsi@3/channel@0/disk@3,0", {0, 1, 0} },
750 add_drive_with_mbr(args
, empty_mbr
, 1);
751 add_drive_with_mbr(args
, empty_mbr
, 1);
752 add_drive_with_mbr(args
, empty_mbr
, 1);
753 add_drive_with_mbr(args
, empty_mbr
, 1);
754 add_scsi_controller(args
, "lsi53c895a", "pci.0", 3);
755 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
756 add_scsi_disk(args
, 1, 0, 0, 1, 0, 9000, 120, 30);
757 add_scsi_disk(args
, 2, 0, 0, 2, 0, 1, 0, 0);
758 add_scsi_disk(args
, 3, 0, 0, 3, 0, 0, 1, 0);
759 test_override(args
, expected
);
762 static void test_override_scsi_2_controllers(void)
764 TestArgs
*args
= create_args();
765 CHSResult expected
[] = {
766 {"/pci@i0cf8/scsi@3/channel@0/disk@0,0", {10000, 120, 30} },
767 {"/pci@i0cf8/scsi@3/channel@0/disk@1,0", {9000, 120, 30} },
768 {"/pci@i0cf8/scsi@4/channel@0/disk@0,1", {1, 0, 0} },
769 {"/pci@i0cf8/scsi@4/channel@0/disk@1,2", {0, 1, 0} },
772 add_drive_with_mbr(args
, empty_mbr
, 1);
773 add_drive_with_mbr(args
, empty_mbr
, 1);
774 add_drive_with_mbr(args
, empty_mbr
, 1);
775 add_drive_with_mbr(args
, empty_mbr
, 1);
776 add_scsi_controller(args
, "lsi53c895a", "pci.0", 3);
777 add_scsi_controller(args
, "virtio-scsi-pci", "pci.0", 4);
778 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
779 add_scsi_disk(args
, 1, 0, 0, 1, 0, 9000, 120, 30);
780 add_scsi_disk(args
, 2, 1, 0, 0, 1, 1, 0, 0);
781 add_scsi_disk(args
, 3, 1, 0, 1, 2, 0, 1, 0);
782 test_override(args
, expected
);
785 static void test_override_virtio_blk(void)
787 TestArgs
*args
= create_args();
788 CHSResult expected
[] = {
789 {"/pci@i0cf8/scsi@3/disk@0,0", {10000, 120, 30} },
790 {"/pci@i0cf8/scsi@4/disk@0,0", {9000, 120, 30} },
793 add_drive_with_mbr(args
, empty_mbr
, 1);
794 add_drive_with_mbr(args
, empty_mbr
, 1);
795 add_virtio_disk(args
, 0, "pci.0", 3, 10000, 120, 30);
796 add_virtio_disk(args
, 1, "pci.0", 4, 9000, 120, 30);
797 test_override(args
, expected
);
800 static void test_override_zero_chs(void)
802 TestArgs
*args
= create_args();
803 CHSResult expected
[] = {
806 add_drive_with_mbr(args
, empty_mbr
, 1);
807 add_ide_disk(args
, 0, 1, 1, 0, 0, 0);
808 test_override(args
, expected
);
811 static void test_override_scsi_hot_unplug(void)
818 TestArgs
*args
= create_args();
819 CHSResult expected
[] = {
820 {"/pci@i0cf8/scsi@2/channel@0/disk@0,0", {10000, 120, 30} },
821 {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
824 CHSResult expected2
[] = {
825 {"/pci@i0cf8/scsi@2/channel@0/disk@1,0", {20, 20, 20} },
828 add_drive_with_mbr(args
, empty_mbr
, 1);
829 add_drive_with_mbr(args
, empty_mbr
, 1);
830 add_scsi_controller(args
, "virtio-scsi-pci", "pci.0", 2);
831 add_scsi_disk(args
, 0, 0, 0, 0, 0, 10000, 120, 30);
832 add_scsi_disk(args
, 1, 0, 0, 1, 0, 20, 20, 20);
834 joined_args
= g_strjoinv(" ", args
->argv
);
836 qts
= qtest_init(joined_args
);
837 fw_cfg
= pc_fw_cfg_init(qts
);
839 read_bootdevices(fw_cfg
, expected
);
841 /* unplug device an restart */
842 response
= qtest_qmp(qts
,
843 "{ 'execute': 'device_del',"
844 " 'arguments': {'id': 'scsi-disk0' }}");
846 g_assert(!qdict_haskey(response
, "error"));
847 qobject_unref(response
);
848 response
= qtest_qmp(qts
,
849 "{ 'execute': 'system_reset', 'arguments': { }}");
851 g_assert(!qdict_haskey(response
, "error"));
852 qobject_unref(response
);
854 qtest_qmp_eventwait(qts
, "RESET");
856 read_bootdevices(fw_cfg
, expected2
);
863 for (i
= 0; i
< args
->n_drives
; i
++) {
864 unlink(args
->drives
[i
]);
865 free(args
->drives
[i
]);
867 g_free(args
->drives
);
868 g_strfreev(args
->argv
);
872 static void test_override_virtio_hot_unplug(void)
879 TestArgs
*args
= create_args();
880 CHSResult expected
[] = {
881 {"/pci@i0cf8/scsi@2/disk@0,0", {10000, 120, 30} },
882 {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
885 CHSResult expected2
[] = {
886 {"/pci@i0cf8/scsi@3/disk@0,0", {20, 20, 20} },
889 add_drive_with_mbr(args
, empty_mbr
, 1);
890 add_drive_with_mbr(args
, empty_mbr
, 1);
891 add_virtio_disk(args
, 0, "pci.0", 2, 10000, 120, 30);
892 add_virtio_disk(args
, 1, "pci.0", 3, 20, 20, 20);
894 joined_args
= g_strjoinv(" ", args
->argv
);
896 qts
= qtest_init(joined_args
);
897 fw_cfg
= pc_fw_cfg_init(qts
);
899 read_bootdevices(fw_cfg
, expected
);
901 /* unplug device an restart */
902 response
= qtest_qmp(qts
,
903 "{ 'execute': 'device_del',"
904 " 'arguments': {'id': 'virtio-disk0' }}");
906 g_assert(!qdict_haskey(response
, "error"));
907 qobject_unref(response
);
908 response
= qtest_qmp(qts
,
909 "{ 'execute': 'system_reset', 'arguments': { }}");
911 g_assert(!qdict_haskey(response
, "error"));
912 qobject_unref(response
);
914 qtest_qmp_eventwait(qts
, "RESET");
916 read_bootdevices(fw_cfg
, expected2
);
923 for (i
= 0; i
< args
->n_drives
; i
++) {
924 unlink(args
->drives
[i
]);
925 free(args
->drives
[i
]);
927 g_free(args
->drives
);
928 g_strfreev(args
->argv
);
932 int main(int argc
, char **argv
)
937 g_test_init(&argc
, &argv
, NULL
);
939 for (i
= 0; i
< backend_last
; i
++) {
940 if (img_secs
[i
] >= 0) {
941 img_file_name
[i
] = create_test_img(img_secs
[i
]);
942 if (!img_file_name
[i
]) {
943 g_test_message("Could not create test images.");
947 img_file_name
[i
] = NULL
;
951 qtest_add_func("hd-geo/ide/none", test_ide_none
);
952 qtest_add_func("hd-geo/ide/drive/mbr/blank", test_ide_drive_mbr_blank
);
953 qtest_add_func("hd-geo/ide/drive/mbr/lba", test_ide_drive_mbr_lba
);
954 qtest_add_func("hd-geo/ide/drive/mbr/chs", test_ide_drive_mbr_chs
);
955 qtest_add_func("hd-geo/ide/drive/cd_0", test_ide_drive_cd_0
);
956 qtest_add_func("hd-geo/ide/device/mbr/blank", test_ide_device_mbr_blank
);
957 qtest_add_func("hd-geo/ide/device/mbr/lba", test_ide_device_mbr_lba
);
958 qtest_add_func("hd-geo/ide/device/mbr/chs", test_ide_device_mbr_chs
);
959 qtest_add_func("hd-geo/ide/device/user/chs", test_ide_device_user_chs
);
960 qtest_add_func("hd-geo/ide/device/user/chst", test_ide_device_user_chst
);
961 if (have_qemu_img()) {
962 qtest_add_func("hd-geo/override/ide", test_override_ide
);
963 qtest_add_func("hd-geo/override/scsi", test_override_scsi
);
964 qtest_add_func("hd-geo/override/scsi_2_controllers",
965 test_override_scsi_2_controllers
);
966 qtest_add_func("hd-geo/override/virtio_blk", test_override_virtio_blk
);
967 qtest_add_func("hd-geo/override/zero_chs", test_override_zero_chs
);
968 qtest_add_func("hd-geo/override/scsi_hot_unplug",
969 test_override_scsi_hot_unplug
);
970 qtest_add_func("hd-geo/override/virtio_hot_unplug",
971 test_override_virtio_hot_unplug
);
973 g_test_message("QTEST_QEMU_IMG not set or qemu-img missing; "
974 "skipping hd-geo/override/* tests");
980 for (i
= 0; i
< backend_last
; i
++) {
981 if (img_file_name
[i
]) {
982 unlink(img_file_name
[i
]);
983 free(img_file_name
[i
]);