-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1 iQIcBAABAgAGBQJWRkUVAAoJEH3vgQaq/DkOfywP/RacpMoAorAX15K/t5RF1Df2 hATfCH8Rxf4uJZ2OBk7q7gRaLGoluwJvUHgykKpfByHwe+nK0vt/O8/bkSvKSBfw FvgkywsJibBcd0zDWsqSeSrbIfQ87o+5ZdNFUsyw7w/FxNjn0RYPuvuyyk0kEQq5 GObTbX8s7bT3APWBVZS3WGi9rnWbTrXz3SXLhwf3r9gFtVgBKiL3dmrgT0U7FzwO 7Ua31LhDx8oXzb3MRvBqcnwmUEvrtAzpdazYIFq+Xt6lUFzXO1/h/Ue0glmcP6Yi ddML9J4WbFxWuVkZPKppR+s6/RkUYIB3Npo1e8/0THGrHsEdpAKh+o5Y6TtxeqYt F8PpdG+kfleKKnTGZCN6x3vzpHqTawH2/ltavSmEbBG2aV1MFV0NK4CcCvc3UGtB PxRIJDfAQCztPyrprvdIMC5gAwZZr2clSowfoYK5luTTIgtLTtYKRRAtHjr5YXjY IWG7xurJGI43Iw09B/IUlG+Uvc59g9NiufPcXIVN0aj7Ss8lf+oeaJV/JVYQEJKz 7s52SR98pZZeNKoKDS1PLhx4LWjCEFRpCW++dYVbsEDje5wrPlF24IEqz5K779Kp CRxHl46feH/NAmd6aOvu8TvpTTOaEgFZF1MGUaRkWpBRTKgnnpYQkiJLAGN6GDoi N7FcguurxYL9pI5XZni5 =dYlR -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging # gpg: Signature made Fri 13 Nov 2015 20:16:21 GMT using RSA key ID AAFC390E # gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>" * remotes/jnsnow/tags/ide-pull-request: qtest/ahci: use raw format when qemu-img is absent libqos: add qemu-img presence check qtest/ahci: always specify image format ahci/qtest: don't use tcp sockets for migration tests atapi: Prioritize unknown cmd error over BCL error atapi: add byte_count_limit helper Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
bc7c6c1fec
@ -170,6 +170,17 @@ void ide_atapi_io_error(IDEState *s, int ret)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t atapi_byte_count_limit(IDEState *s)
|
||||||
|
{
|
||||||
|
uint16_t bcl;
|
||||||
|
|
||||||
|
bcl = s->lcyl | (s->hcyl << 8);
|
||||||
|
if (bcl == 0xffff) {
|
||||||
|
return 0xfffe;
|
||||||
|
}
|
||||||
|
return bcl;
|
||||||
|
}
|
||||||
|
|
||||||
/* The whole ATAPI transfer logic is handled in this function */
|
/* The whole ATAPI transfer logic is handled in this function */
|
||||||
void ide_atapi_cmd_reply_end(IDEState *s)
|
void ide_atapi_cmd_reply_end(IDEState *s)
|
||||||
{
|
{
|
||||||
@ -212,12 +223,10 @@ void ide_atapi_cmd_reply_end(IDEState *s)
|
|||||||
} else {
|
} else {
|
||||||
/* a new transfer is needed */
|
/* a new transfer is needed */
|
||||||
s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
|
s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
|
||||||
byte_count_limit = s->lcyl | (s->hcyl << 8);
|
byte_count_limit = atapi_byte_count_limit(s);
|
||||||
#ifdef DEBUG_IDE_ATAPI
|
#ifdef DEBUG_IDE_ATAPI
|
||||||
printf("byte_count_limit=%d\n", byte_count_limit);
|
printf("byte_count_limit=%d\n", byte_count_limit);
|
||||||
#endif
|
#endif
|
||||||
if (byte_count_limit == 0xffff)
|
|
||||||
byte_count_limit--;
|
|
||||||
size = s->packet_transfer_size;
|
size = s->packet_transfer_size;
|
||||||
if (size > byte_count_limit) {
|
if (size > byte_count_limit) {
|
||||||
/* byte count limit must be even if this case */
|
/* byte count limit must be even if this case */
|
||||||
@ -1186,7 +1195,7 @@ enum {
|
|||||||
NONDATA = 0x04,
|
NONDATA = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct {
|
static const struct AtapiCmd {
|
||||||
void (*handler)(IDEState *s, uint8_t *buf);
|
void (*handler)(IDEState *s, uint8_t *buf);
|
||||||
int flags;
|
int flags;
|
||||||
} atapi_cmd_table[0x100] = {
|
} atapi_cmd_table[0x100] = {
|
||||||
@ -1213,9 +1222,9 @@ static const struct {
|
|||||||
|
|
||||||
void ide_atapi_cmd(IDEState *s)
|
void ide_atapi_cmd(IDEState *s)
|
||||||
{
|
{
|
||||||
uint8_t *buf;
|
uint8_t *buf = s->io_buffer;
|
||||||
|
const struct AtapiCmd *cmd = &atapi_cmd_table[s->io_buffer[0]];
|
||||||
|
|
||||||
buf = s->io_buffer;
|
|
||||||
#ifdef DEBUG_IDE_ATAPI
|
#ifdef DEBUG_IDE_ATAPI
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -1226,14 +1235,14 @@ void ide_atapi_cmd(IDEState *s)
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's a UNIT_ATTENTION condition pending, only command flagged with
|
* If there's a UNIT_ATTENTION condition pending, only command flagged with
|
||||||
* ALLOW_UA are allowed to complete. with other commands getting a CHECK
|
* ALLOW_UA are allowed to complete. with other commands getting a CHECK
|
||||||
* condition response unless a higher priority status, defined by the drive
|
* condition response unless a higher priority status, defined by the drive
|
||||||
* here, is pending.
|
* here, is pending.
|
||||||
*/
|
*/
|
||||||
if (s->sense_key == UNIT_ATTENTION &&
|
if (s->sense_key == UNIT_ATTENTION && !(cmd->flags & ALLOW_UA)) {
|
||||||
!(atapi_cmd_table[s->io_buffer[0]].flags & ALLOW_UA)) {
|
|
||||||
ide_atapi_cmd_check_status(s);
|
ide_atapi_cmd_check_status(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1244,7 +1253,7 @@ void ide_atapi_cmd(IDEState *s)
|
|||||||
* GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close
|
* GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close
|
||||||
* states rely on this behavior.
|
* states rely on this behavior.
|
||||||
*/
|
*/
|
||||||
if (!(atapi_cmd_table[s->io_buffer[0]].flags & ALLOW_UA) &&
|
if (!(cmd->flags & ALLOW_UA) &&
|
||||||
!s->tray_open && blk_is_inserted(s->blk) && s->cdrom_changed) {
|
!s->tray_open && blk_is_inserted(s->blk) && s->cdrom_changed) {
|
||||||
|
|
||||||
if (s->cdrom_changed == 1) {
|
if (s->cdrom_changed == 1) {
|
||||||
@ -1259,7 +1268,7 @@ void ide_atapi_cmd(IDEState *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Report a Not Ready condition if appropriate for the command */
|
/* Report a Not Ready condition if appropriate for the command */
|
||||||
if ((atapi_cmd_table[s->io_buffer[0]].flags & CHECK_READY) &&
|
if ((cmd->flags & CHECK_READY) &&
|
||||||
(!media_present(s) || !blk_is_inserted(s->blk)))
|
(!media_present(s) || !blk_is_inserted(s->blk)))
|
||||||
{
|
{
|
||||||
ide_atapi_cmd_error(s, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
ide_atapi_cmd_error(s, NOT_READY, ASC_MEDIUM_NOT_PRESENT);
|
||||||
@ -1270,10 +1279,9 @@ void ide_atapi_cmd(IDEState *s)
|
|||||||
* If this is a data-transferring PIO command and BCL is 0,
|
* If this is a data-transferring PIO command and BCL is 0,
|
||||||
* we abort at the /ATA/ level, not the ATAPI level.
|
* we abort at the /ATA/ level, not the ATAPI level.
|
||||||
* See ATA8 ACS3 section 7.17.6.49 and 7.21.5 */
|
* See ATA8 ACS3 section 7.17.6.49 and 7.21.5 */
|
||||||
if (!(atapi_cmd_table[s->io_buffer[0]].flags & NONDATA)) {
|
if (cmd->handler && !(cmd->flags & NONDATA)) {
|
||||||
/* TODO: Check IDENTIFY data word 125 for default BCL (currently 0) */
|
/* TODO: Check IDENTIFY data word 125 for default BCL (currently 0) */
|
||||||
uint16_t byte_count_limit = s->lcyl | (s->hcyl << 8);
|
if (!(atapi_byte_count_limit(s) || s->atapi_dma)) {
|
||||||
if (!(byte_count_limit || s->atapi_dma)) {
|
|
||||||
/* TODO: Move abort back into core.c and make static inline again */
|
/* TODO: Move abort back into core.c and make static inline again */
|
||||||
ide_abort_command(s);
|
ide_abort_command(s);
|
||||||
return;
|
return;
|
||||||
@ -1281,8 +1289,8 @@ void ide_atapi_cmd(IDEState *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Execute the command */
|
/* Execute the command */
|
||||||
if (atapi_cmd_table[s->io_buffer[0]].handler) {
|
if (cmd->handler) {
|
||||||
atapi_cmd_table[s->io_buffer[0]].handler(s, buf);
|
cmd->handler(s, buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,15 +39,17 @@
|
|||||||
#include "hw/pci/pci_ids.h"
|
#include "hw/pci/pci_ids.h"
|
||||||
#include "hw/pci/pci_regs.h"
|
#include "hw/pci/pci_regs.h"
|
||||||
|
|
||||||
/* Test-specific defines -- in MiB */
|
/* Test images sizes in MB */
|
||||||
#define TEST_IMAGE_SIZE_MB (200 * 1024)
|
#define TEST_IMAGE_SIZE_MB_LARGE (200 * 1024)
|
||||||
#define TEST_IMAGE_SECTORS ((TEST_IMAGE_SIZE_MB / AHCI_SECTOR_SIZE) \
|
#define TEST_IMAGE_SIZE_MB_SMALL 64
|
||||||
* 1024 * 1024)
|
|
||||||
|
|
||||||
/*** Globals ***/
|
/*** Globals ***/
|
||||||
static char tmp_path[] = "/tmp/qtest.XXXXXX";
|
static char tmp_path[] = "/tmp/qtest.XXXXXX";
|
||||||
static char debug_path[] = "/tmp/qtest-blkdebug.XXXXXX";
|
static char debug_path[] = "/tmp/qtest-blkdebug.XXXXXX";
|
||||||
|
static char mig_socket[] = "/tmp/qtest-migration.XXXXXX";
|
||||||
static bool ahci_pedantic;
|
static bool ahci_pedantic;
|
||||||
|
static const char *imgfmt;
|
||||||
|
static unsigned test_image_size_mb;
|
||||||
|
|
||||||
/*** Function Declarations ***/
|
/*** Function Declarations ***/
|
||||||
static void ahci_test_port_spec(AHCIQState *ahci, uint8_t port);
|
static void ahci_test_port_spec(AHCIQState *ahci, uint8_t port);
|
||||||
@ -60,6 +62,11 @@ static void ahci_test_pmcap(AHCIQState *ahci, uint8_t offset);
|
|||||||
|
|
||||||
/*** Utilities ***/
|
/*** Utilities ***/
|
||||||
|
|
||||||
|
static uint64_t mb_to_sectors(uint64_t image_size_mb)
|
||||||
|
{
|
||||||
|
return (image_size_mb * 1024 * 1024) / AHCI_SECTOR_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
static void string_bswap16(uint16_t *s, size_t bytes)
|
static void string_bswap16(uint16_t *s, size_t bytes)
|
||||||
{
|
{
|
||||||
g_assert_cmphex((bytes & 1), ==, 0);
|
g_assert_cmphex((bytes & 1), ==, 0);
|
||||||
@ -114,8 +121,11 @@ static void ahci_migrate(AHCIQState *from, AHCIQState *to, const char *uri)
|
|||||||
{
|
{
|
||||||
QOSState *tmp = to->parent;
|
QOSState *tmp = to->parent;
|
||||||
QPCIDevice *dev = to->dev;
|
QPCIDevice *dev = to->dev;
|
||||||
|
char *uri_local = NULL;
|
||||||
|
|
||||||
if (uri == NULL) {
|
if (uri == NULL) {
|
||||||
uri = "tcp:127.0.0.1:1234";
|
uri_local = g_strdup_printf("%s%s", "unix:", mig_socket);
|
||||||
|
uri = uri_local;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* context will be 'to' after completion. */
|
/* context will be 'to' after completion. */
|
||||||
@ -135,6 +145,7 @@ static void ahci_migrate(AHCIQState *from, AHCIQState *to, const char *uri)
|
|||||||
from->dev = dev;
|
from->dev = dev;
|
||||||
|
|
||||||
verify_state(to);
|
verify_state(to);
|
||||||
|
g_free(uri_local);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Test Setup & Teardown ***/
|
/*** Test Setup & Teardown ***/
|
||||||
@ -170,11 +181,11 @@ static AHCIQState *ahci_boot(const char *cli, ...)
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
} else {
|
} else {
|
||||||
cli = "-drive if=none,id=drive0,file=%s,cache=writeback,serial=%s"
|
cli = "-drive if=none,id=drive0,file=%s,cache=writeback,serial=%s"
|
||||||
",format=qcow2"
|
",format=%s"
|
||||||
" -M q35 "
|
" -M q35 "
|
||||||
"-device ide-hd,drive=drive0 "
|
"-device ide-hd,drive=drive0 "
|
||||||
"-global ide-hd.ver=%s";
|
"-global ide-hd.ver=%s";
|
||||||
s = ahci_boot(cli, tmp_path, "testdisk", "version");
|
s = ahci_boot(cli, tmp_path, "testdisk", imgfmt, "version");
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
@ -900,7 +911,7 @@ static void ahci_test_max(AHCIQState *ahci)
|
|||||||
uint64_t nsect;
|
uint64_t nsect;
|
||||||
uint8_t port;
|
uint8_t port;
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
uint64_t config_sect = TEST_IMAGE_SECTORS - 1;
|
uint64_t config_sect = mb_to_sectors(test_image_size_mb) - 1;
|
||||||
|
|
||||||
if (config_sect > 0xFFFFFF) {
|
if (config_sect > 0xFFFFFF) {
|
||||||
cmd = CMD_READ_MAX_EXT;
|
cmd = CMD_READ_MAX_EXT;
|
||||||
@ -1073,12 +1084,12 @@ static void test_flush_retry(void)
|
|||||||
|
|
||||||
prepare_blkdebug_script(debug_path, "flush_to_disk");
|
prepare_blkdebug_script(debug_path, "flush_to_disk");
|
||||||
ahci = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
|
ahci = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
|
||||||
"format=qcow2,cache=writeback,"
|
"format=%s,cache=writeback,"
|
||||||
"rerror=stop,werror=stop "
|
"rerror=stop,werror=stop "
|
||||||
"-M q35 "
|
"-M q35 "
|
||||||
"-device ide-hd,drive=drive0 ",
|
"-device ide-hd,drive=drive0 ",
|
||||||
debug_path,
|
debug_path,
|
||||||
tmp_path);
|
tmp_path, imgfmt);
|
||||||
|
|
||||||
/* Issue Flush Command and wait for error */
|
/* Issue Flush Command and wait for error */
|
||||||
port = ahci_port_select(ahci);
|
port = ahci_port_select(ahci);
|
||||||
@ -1105,18 +1116,19 @@ static void test_flush_retry(void)
|
|||||||
static void test_migrate_sanity(void)
|
static void test_migrate_sanity(void)
|
||||||
{
|
{
|
||||||
AHCIQState *src, *dst;
|
AHCIQState *src, *dst;
|
||||||
const char *uri = "tcp:127.0.0.1:1234";
|
char *uri = g_strdup_printf("unix:%s", mig_socket);
|
||||||
|
|
||||||
src = ahci_boot("-m 1024 -M q35 "
|
src = ahci_boot("-m 1024 -M q35 "
|
||||||
"-hda %s ", tmp_path);
|
"-drive if=ide,file=%s,format=%s ", tmp_path, imgfmt);
|
||||||
dst = ahci_boot("-m 1024 -M q35 "
|
dst = ahci_boot("-m 1024 -M q35 "
|
||||||
"-hda %s "
|
"-drive if=ide,file=%s,format=%s "
|
||||||
"-incoming %s", tmp_path, uri);
|
"-incoming %s", tmp_path, imgfmt, uri);
|
||||||
|
|
||||||
ahci_migrate(src, dst, uri);
|
ahci_migrate(src, dst, uri);
|
||||||
|
|
||||||
ahci_shutdown(src);
|
ahci_shutdown(src);
|
||||||
ahci_shutdown(dst);
|
ahci_shutdown(dst);
|
||||||
|
g_free(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1129,13 +1141,14 @@ static void ahci_migrate_simple(uint8_t cmd_read, uint8_t cmd_write)
|
|||||||
size_t bufsize = 4096;
|
size_t bufsize = 4096;
|
||||||
unsigned char *tx = g_malloc(bufsize);
|
unsigned char *tx = g_malloc(bufsize);
|
||||||
unsigned char *rx = g_malloc0(bufsize);
|
unsigned char *rx = g_malloc0(bufsize);
|
||||||
const char *uri = "tcp:127.0.0.1:1234";
|
char *uri = g_strdup_printf("unix:%s", mig_socket);
|
||||||
|
|
||||||
src = ahci_boot_and_enable("-m 1024 -M q35 "
|
src = ahci_boot_and_enable("-m 1024 -M q35 "
|
||||||
"-hda %s ", tmp_path);
|
"-drive if=ide,format=%s,file=%s ",
|
||||||
|
imgfmt, tmp_path);
|
||||||
dst = ahci_boot("-m 1024 -M q35 "
|
dst = ahci_boot("-m 1024 -M q35 "
|
||||||
"-hda %s "
|
"-drive if=ide,format=%s,file=%s "
|
||||||
"-incoming %s", tmp_path, uri);
|
"-incoming %s", imgfmt, tmp_path, uri);
|
||||||
|
|
||||||
set_context(src->parent);
|
set_context(src->parent);
|
||||||
|
|
||||||
@ -1158,6 +1171,7 @@ static void ahci_migrate_simple(uint8_t cmd_read, uint8_t cmd_write)
|
|||||||
ahci_shutdown(dst);
|
ahci_shutdown(dst);
|
||||||
g_free(rx);
|
g_free(rx);
|
||||||
g_free(tx);
|
g_free(tx);
|
||||||
|
g_free(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_migrate_dma(void)
|
static void test_migrate_dma(void)
|
||||||
@ -1190,12 +1204,12 @@ static void ahci_halted_io_test(uint8_t cmd_read, uint8_t cmd_write)
|
|||||||
prepare_blkdebug_script(debug_path, "write_aio");
|
prepare_blkdebug_script(debug_path, "write_aio");
|
||||||
|
|
||||||
ahci = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
|
ahci = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
|
||||||
"format=qcow2,cache=writeback,"
|
"format=%s,cache=writeback,"
|
||||||
"rerror=stop,werror=stop "
|
"rerror=stop,werror=stop "
|
||||||
"-M q35 "
|
"-M q35 "
|
||||||
"-device ide-hd,drive=drive0 ",
|
"-device ide-hd,drive=drive0 ",
|
||||||
debug_path,
|
debug_path,
|
||||||
tmp_path);
|
tmp_path, imgfmt);
|
||||||
|
|
||||||
/* Initialize and prepare */
|
/* Initialize and prepare */
|
||||||
port = ahci_port_select(ahci);
|
port = ahci_port_select(ahci);
|
||||||
@ -1251,25 +1265,25 @@ static void ahci_migrate_halted_io(uint8_t cmd_read, uint8_t cmd_write)
|
|||||||
unsigned char *rx = g_malloc0(bufsize);
|
unsigned char *rx = g_malloc0(bufsize);
|
||||||
uint64_t ptr;
|
uint64_t ptr;
|
||||||
AHCICommand *cmd;
|
AHCICommand *cmd;
|
||||||
const char *uri = "tcp:127.0.0.1:1234";
|
char *uri = g_strdup_printf("unix:%s", mig_socket);
|
||||||
|
|
||||||
prepare_blkdebug_script(debug_path, "write_aio");
|
prepare_blkdebug_script(debug_path, "write_aio");
|
||||||
|
|
||||||
src = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
|
src = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
|
||||||
"format=qcow2,cache=writeback,"
|
"format=%s,cache=writeback,"
|
||||||
"rerror=stop,werror=stop "
|
"rerror=stop,werror=stop "
|
||||||
"-M q35 "
|
"-M q35 "
|
||||||
"-device ide-hd,drive=drive0 ",
|
"-device ide-hd,drive=drive0 ",
|
||||||
debug_path,
|
debug_path,
|
||||||
tmp_path);
|
tmp_path, imgfmt);
|
||||||
|
|
||||||
dst = ahci_boot("-drive file=%s,if=none,id=drive0,"
|
dst = ahci_boot("-drive file=%s,if=none,id=drive0,"
|
||||||
"format=qcow2,cache=writeback,"
|
"format=%s,cache=writeback,"
|
||||||
"rerror=stop,werror=stop "
|
"rerror=stop,werror=stop "
|
||||||
"-M q35 "
|
"-M q35 "
|
||||||
"-device ide-hd,drive=drive0 "
|
"-device ide-hd,drive=drive0 "
|
||||||
"-incoming %s",
|
"-incoming %s",
|
||||||
tmp_path, uri);
|
tmp_path, imgfmt, uri);
|
||||||
|
|
||||||
set_context(src->parent);
|
set_context(src->parent);
|
||||||
|
|
||||||
@ -1301,6 +1315,7 @@ static void ahci_migrate_halted_io(uint8_t cmd_read, uint8_t cmd_write)
|
|||||||
ahci_shutdown(dst);
|
ahci_shutdown(dst);
|
||||||
g_free(rx);
|
g_free(rx);
|
||||||
g_free(tx);
|
g_free(tx);
|
||||||
|
g_free(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_migrate_halted_dma(void)
|
static void test_migrate_halted_dma(void)
|
||||||
@ -1322,20 +1337,22 @@ static void test_flush_migrate(void)
|
|||||||
AHCICommand *cmd;
|
AHCICommand *cmd;
|
||||||
uint8_t px;
|
uint8_t px;
|
||||||
const char *s;
|
const char *s;
|
||||||
const char *uri = "tcp:127.0.0.1:1234";
|
char *uri = g_strdup_printf("unix:%s", mig_socket);
|
||||||
|
|
||||||
prepare_blkdebug_script(debug_path, "flush_to_disk");
|
prepare_blkdebug_script(debug_path, "flush_to_disk");
|
||||||
|
|
||||||
src = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
|
src = ahci_boot_and_enable("-drive file=blkdebug:%s:%s,if=none,id=drive0,"
|
||||||
"cache=writeback,rerror=stop,werror=stop "
|
"cache=writeback,rerror=stop,werror=stop,"
|
||||||
|
"format=%s "
|
||||||
"-M q35 "
|
"-M q35 "
|
||||||
"-device ide-hd,drive=drive0 ",
|
"-device ide-hd,drive=drive0 ",
|
||||||
debug_path, tmp_path);
|
debug_path, tmp_path, imgfmt);
|
||||||
dst = ahci_boot("-drive file=%s,if=none,id=drive0,"
|
dst = ahci_boot("-drive file=%s,if=none,id=drive0,"
|
||||||
"cache=writeback,rerror=stop,werror=stop "
|
"cache=writeback,rerror=stop,werror=stop,"
|
||||||
|
"format=%s "
|
||||||
"-M q35 "
|
"-M q35 "
|
||||||
"-device ide-hd,drive=drive0 "
|
"-device ide-hd,drive=drive0 "
|
||||||
"-incoming %s", tmp_path, uri);
|
"-incoming %s", tmp_path, imgfmt, uri);
|
||||||
|
|
||||||
set_context(src->parent);
|
set_context(src->parent);
|
||||||
|
|
||||||
@ -1360,6 +1377,7 @@ static void test_flush_migrate(void)
|
|||||||
ahci_command_free(cmd);
|
ahci_command_free(cmd);
|
||||||
ahci_shutdown(src);
|
ahci_shutdown(src);
|
||||||
ahci_shutdown(dst);
|
ahci_shutdown(dst);
|
||||||
|
g_free(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_max(void)
|
static void test_max(void)
|
||||||
@ -1476,7 +1494,7 @@ static uint64_t offset_sector(enum OffsetType ofst,
|
|||||||
return 1;
|
return 1;
|
||||||
case OFFSET_HIGH:
|
case OFFSET_HIGH:
|
||||||
ceil = (addr_type == ADDR_MODE_LBA28) ? 0xfffffff : 0xffffffffffff;
|
ceil = (addr_type == ADDR_MODE_LBA28) ? 0xfffffff : 0xffffffffffff;
|
||||||
ceil = MIN(ceil, TEST_IMAGE_SECTORS - 1);
|
ceil = MIN(ceil, mb_to_sectors(test_image_size_mb) - 1);
|
||||||
nsectors = buffsize / AHCI_SECTOR_SIZE;
|
nsectors = buffsize / AHCI_SECTOR_SIZE;
|
||||||
return ceil - nsectors + 1;
|
return ceil - nsectors + 1;
|
||||||
default:
|
default:
|
||||||
@ -1558,8 +1576,9 @@ static void create_ahci_io_test(enum IOMode type, enum AddrMode addr,
|
|||||||
enum BuffLen len, enum OffsetType offset)
|
enum BuffLen len, enum OffsetType offset)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
AHCIIOTestOptions *opts = g_malloc(sizeof(AHCIIOTestOptions));
|
AHCIIOTestOptions *opts;
|
||||||
|
|
||||||
|
opts = g_malloc(sizeof(AHCIIOTestOptions));
|
||||||
opts->length = len;
|
opts->length = len;
|
||||||
opts->address_type = addr;
|
opts->address_type = addr;
|
||||||
opts->io_type = type;
|
opts->io_type = type;
|
||||||
@ -1571,6 +1590,13 @@ static void create_ahci_io_test(enum IOMode type, enum AddrMode addr,
|
|||||||
buff_len_str[len],
|
buff_len_str[len],
|
||||||
offset_str[offset]);
|
offset_str[offset]);
|
||||||
|
|
||||||
|
if ((addr == ADDR_MODE_LBA48) && (offset == OFFSET_HIGH) &&
|
||||||
|
(mb_to_sectors(test_image_size_mb) <= 0xFFFFFFF)) {
|
||||||
|
g_test_message("%s: skipped; test image too small", name);
|
||||||
|
g_free(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
qtest_add_data_func(name, opts, test_io_interface);
|
qtest_add_data_func(name, opts, test_io_interface);
|
||||||
g_free(name);
|
g_free(name);
|
||||||
}
|
}
|
||||||
@ -1617,15 +1643,33 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a temporary qcow2 image */
|
/* Create a temporary image */
|
||||||
close(mkstemp(tmp_path));
|
fd = mkstemp(tmp_path);
|
||||||
mkqcow2(tmp_path, TEST_IMAGE_SIZE_MB);
|
g_assert(fd >= 0);
|
||||||
|
if (have_qemu_img()) {
|
||||||
|
imgfmt = "qcow2";
|
||||||
|
test_image_size_mb = TEST_IMAGE_SIZE_MB_LARGE;
|
||||||
|
mkqcow2(tmp_path, TEST_IMAGE_SIZE_MB_LARGE);
|
||||||
|
} else {
|
||||||
|
g_test_message("QTEST_QEMU_IMG not set or qemu-img missing; "
|
||||||
|
"skipping LBA48 high-sector tests");
|
||||||
|
imgfmt = "raw";
|
||||||
|
test_image_size_mb = TEST_IMAGE_SIZE_MB_SMALL;
|
||||||
|
ret = ftruncate(fd, test_image_size_mb * 1024 * 1024);
|
||||||
|
g_assert(ret == 0);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
/* Create temporary blkdebug instructions */
|
/* Create temporary blkdebug instructions */
|
||||||
fd = mkstemp(debug_path);
|
fd = mkstemp(debug_path);
|
||||||
g_assert(fd >= 0);
|
g_assert(fd >= 0);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
/* Reserve a hollow file to use as a socket for migration tests */
|
||||||
|
fd = mkstemp(mig_socket);
|
||||||
|
g_assert(fd >= 0);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
/* Run the tests */
|
/* Run the tests */
|
||||||
qtest_add_func("/ahci/sanity", test_sanity);
|
qtest_add_func("/ahci/sanity", test_sanity);
|
||||||
qtest_add_func("/ahci/pci_spec", test_pci_spec);
|
qtest_add_func("/ahci/pci_spec", test_pci_spec);
|
||||||
@ -1668,6 +1712,7 @@ int main(int argc, char **argv)
|
|||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
unlink(tmp_path);
|
unlink(tmp_path);
|
||||||
unlink(debug_path);
|
unlink(debug_path);
|
||||||
|
unlink(mig_socket);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,23 @@ void migrate(QOSState *from, QOSState *to, const char *uri)
|
|||||||
set_context(to);
|
set_context(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool have_qemu_img(void)
|
||||||
|
{
|
||||||
|
char *rpath;
|
||||||
|
const char *path = getenv("QTEST_QEMU_IMG");
|
||||||
|
if (!path) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpath = realpath(path, NULL);
|
||||||
|
if (!rpath) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
free(rpath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mkimg(const char *file, const char *fmt, unsigned size_mb)
|
void mkimg(const char *file, const char *fmt, unsigned size_mb)
|
||||||
{
|
{
|
||||||
gchar *cli;
|
gchar *cli;
|
||||||
@ -155,13 +172,14 @@ void mkimg(const char *file, const char *fmt, unsigned size_mb)
|
|||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
char *qemu_img_path;
|
char *qemu_img_path;
|
||||||
gchar *out, *out2;
|
gchar *out, *out2;
|
||||||
char *abs_path;
|
char *qemu_img_abs_path;
|
||||||
|
|
||||||
qemu_img_path = getenv("QTEST_QEMU_IMG");
|
qemu_img_path = getenv("QTEST_QEMU_IMG");
|
||||||
abs_path = realpath(qemu_img_path, NULL);
|
g_assert(qemu_img_path);
|
||||||
assert(qemu_img_path);
|
qemu_img_abs_path = realpath(qemu_img_path, NULL);
|
||||||
|
g_assert(qemu_img_abs_path);
|
||||||
|
|
||||||
cli = g_strdup_printf("%s create -f %s %s %uM", abs_path,
|
cli = g_strdup_printf("%s create -f %s %s %uM", qemu_img_abs_path,
|
||||||
fmt, file, size_mb);
|
fmt, file, size_mb);
|
||||||
ret = g_spawn_command_line_sync(cli, &out, &out2, &rc, &err);
|
ret = g_spawn_command_line_sync(cli, &out, &out2, &rc, &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -183,7 +201,7 @@ void mkimg(const char *file, const char *fmt, unsigned size_mb)
|
|||||||
g_free(out);
|
g_free(out);
|
||||||
g_free(out2);
|
g_free(out2);
|
||||||
g_free(cli);
|
g_free(cli);
|
||||||
free(abs_path);
|
free(qemu_img_abs_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mkqcow2(const char *file, unsigned size_mb)
|
void mkqcow2(const char *file, unsigned size_mb)
|
||||||
|
@ -19,6 +19,7 @@ typedef struct QOSState {
|
|||||||
QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap);
|
QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap);
|
||||||
QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...);
|
QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...);
|
||||||
void qtest_shutdown(QOSState *qs);
|
void qtest_shutdown(QOSState *qs);
|
||||||
|
bool have_qemu_img(void);
|
||||||
void mkimg(const char *file, const char *fmt, unsigned size_mb);
|
void mkimg(const char *file, const char *fmt, unsigned size_mb);
|
||||||
void mkqcow2(const char *file, unsigned size_mb);
|
void mkqcow2(const char *file, unsigned size_mb);
|
||||||
void set_context(QOSState *s);
|
void set_context(QOSState *s);
|
||||||
|
Loading…
Reference in New Issue
Block a user