All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/8] ahci: add more IO tests
@ 2015-02-19 22:29 John Snow
  2015-02-19 22:29 ` [Qemu-devel] [PATCH 1/8] libqos/ahci: Zero-fill AHCI headers John Snow
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: John Snow @ 2015-02-19 22:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, John Snow, armbru, stefanha

This series is based on top of my ahci DMA test series, which is in
turn based on the ahci preliminary refactoring series. Both are currently
pending on stefanha/block.

This series adds many variations that expand on the existing trivial
DMA I/O case. These pathways check different PRDT configurations,
different I/O commands for PIO and DMA, different address scheme
combinations for LBA28 and LBA48, and different sector offsets.

John Snow (8):
  libqos/ahci: Zero-fill AHCI headers
  qtest/ahci: Add a macro bootup routine
  libqos/ahci: add ahci command helpers
  qtest/ahci: Add DMA test variants
  qtest/ahci: Add PIO and LBA48 tests
  qtest/ahci: add fragmented dma test
  qtest/ahci: add qcow2 support to ahci-test
  qtest/ahci: test different disk sectors

 tests/ahci-test.c     | 295 +++++++++++++++++++++++++++++++++++++++++++++-----
 tests/libqos/ahci.c   |  54 ++++++++-
 tests/libqos/ahci.h   |   9 +-
 tests/libqos/libqos.c |  30 +++++
 tests/libqos/libqos.h |   1 +
 5 files changed, 355 insertions(+), 34 deletions(-)

-- 
1.9.3

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 1/8] libqos/ahci: Zero-fill AHCI headers
  2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
@ 2015-02-19 22:29 ` John Snow
  2015-02-19 22:29 ` [Qemu-devel] [PATCH 2/8] qtest/ahci: Add a macro bootup routine John Snow
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: John Snow @ 2015-02-19 22:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, John Snow, armbru, stefanha

Even though it's just the reserved space, make sure they're zeroes.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/libqos/ahci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 170ec5a..6f6652c 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -487,7 +487,7 @@ void ahci_get_command_header(AHCIQState *ahci, uint8_t port,
 void ahci_set_command_header(AHCIQState *ahci, uint8_t port,
                              uint8_t slot, AHCICommandHeader *cmd)
 {
-    AHCICommandHeader tmp;
+    AHCICommandHeader tmp = { .flags = 0 };
     uint64_t ba = ahci->port[port].clb;
     ba += slot * sizeof(AHCICommandHeader);
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 2/8] qtest/ahci: Add a macro bootup routine
  2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
  2015-02-19 22:29 ` [Qemu-devel] [PATCH 1/8] libqos/ahci: Zero-fill AHCI headers John Snow
@ 2015-02-19 22:29 ` John Snow
  2015-02-19 22:29 ` [Qemu-devel] [PATCH 3/8] libqos/ahci: add ahci command helpers John Snow
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: John Snow @ 2015-02-19 22:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, John Snow, armbru, stefanha

Add a routine that can be used to engage the AHCI
device at a not-granular level so that bringing up
the functionality of the HBA is easy in future tests
that are not concerned with testing the bring-up process.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/ahci-test.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 53fd068..9fe9fb5 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -107,6 +107,21 @@ static void ahci_shutdown(AHCIQState *ahci)
     qtest_shutdown(qs);
 }
 
+/**
+ * Boot and fully enable the HBA device.
+ * @see ahci_boot, ahci_pci_enable and ahci_hba_enable.
+ */
+static AHCIQState *ahci_boot_and_enable(void)
+{
+    AHCIQState *ahci;
+    ahci = ahci_boot();
+
+    ahci_pci_enable(ahci);
+    ahci_hba_enable(ahci);
+
+    return ahci;
+}
+
 /*** Specification Adherence Tests ***/
 
 /**
@@ -831,9 +846,7 @@ static void test_identify(void)
 {
     AHCIQState *ahci;
 
-    ahci = ahci_boot();
-    ahci_pci_enable(ahci);
-    ahci_hba_enable(ahci);
+    ahci = ahci_boot_and_enable();
     ahci_test_identify(ahci);
     ahci_shutdown(ahci);
 }
@@ -845,9 +858,7 @@ static void test_dma_rw_simple(void)
 {
     AHCIQState *ahci;
 
-    ahci = ahci_boot();
-    ahci_pci_enable(ahci);
-    ahci_hba_enable(ahci);
+    ahci = ahci_boot_and_enable();
     ahci_test_dma_rw_simple(ahci);
     ahci_shutdown(ahci);
 }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 3/8] libqos/ahci: add ahci command helpers
  2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
  2015-02-19 22:29 ` [Qemu-devel] [PATCH 1/8] libqos/ahci: Zero-fill AHCI headers John Snow
  2015-02-19 22:29 ` [Qemu-devel] [PATCH 2/8] qtest/ahci: Add a macro bootup routine John Snow
@ 2015-02-19 22:29 ` John Snow
  2015-02-19 22:29 ` [Qemu-devel] [PATCH 4/8] qtest/ahci: Add DMA test variants John Snow
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: John Snow @ 2015-02-19 22:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, John Snow, armbru, stefanha

ahci_command_set_flags:  Set additional flags in the command header.
ahci_command_clr_flags:  Clear flags from the command header.
ahci_command_set_offset: Change the IO sector from 0.
ahci_command_adjust:     Adjust many values simultaneously.

To be used to adjust the command header if the default values/guesses
were incorrect or undesirable.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/libqos/ahci.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/ahci.h |  5 +++++
 2 files changed, 47 insertions(+)

diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 6f6652c..1d92438 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -713,6 +713,40 @@ void ahci_command_free(AHCICommand *cmd)
     g_free(cmd);
 }
 
+void ahci_command_set_flags(AHCICommand *cmd, uint16_t cmdh_flags)
+{
+    cmd->header.flags |= cmdh_flags;
+}
+
+void ahci_command_clr_flags(AHCICommand *cmd, uint16_t cmdh_flags)
+{
+    cmd->header.flags &= ~cmdh_flags;
+}
+
+void ahci_command_set_offset(AHCICommand *cmd, uint64_t lba_sect)
+{
+    RegH2DFIS *fis = &(cmd->fis);
+    if (cmd->props->lba28) {
+        g_assert_cmphex(lba_sect, <=, 0xFFFFFFF);
+    } else if (cmd->props->lba48) {
+        g_assert_cmphex(lba_sect, <=, 0xFFFFFFFFFFFF);
+    } else {
+        /* Can't set offset if we don't know the format. */
+        g_assert_not_reached();
+    }
+
+    /* LBA28 uses the low nibble of the device/control register for LBA24:27 */
+    fis->lba_lo[0] = (lba_sect & 0xFF);
+    fis->lba_lo[1] = (lba_sect >> 8) & 0xFF;
+    fis->lba_lo[2] = (lba_sect >> 16) & 0xFF;
+    if (cmd->props->lba28) {
+        fis->device = (fis->device & 0xF0) || (lba_sect >> 24) & 0x0F;
+    }
+    fis->lba_hi[0] = (lba_sect >> 24) & 0xFF;
+    fis->lba_hi[1] = (lba_sect >> 32) & 0xFF;
+    fis->lba_hi[2] = (lba_sect >> 40) & 0xFF;
+}
+
 void ahci_command_set_buffer(AHCICommand *cmd, uint64_t buffer)
 {
     cmd->buffer = buffer;
@@ -740,6 +774,14 @@ void ahci_command_set_prd_size(AHCICommand *cmd, unsigned prd_size)
     ahci_command_set_sizes(cmd, cmd->xbytes, prd_size);
 }
 
+void ahci_command_adjust(AHCICommand *cmd, uint64_t offset, uint64_t buffer,
+                         size_t xbytes, unsigned prd_size)
+{
+    ahci_command_set_sizes(cmd, xbytes, prd_size);
+    ahci_command_set_buffer(cmd, buffer);
+    ahci_command_set_offset(cmd, offset);
+}
+
 void ahci_command_commit(AHCIQState *ahci, AHCICommand *cmd, uint8_t port)
 {
     uint16_t i, prdtl;
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index 39b99d3..888545d 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -537,11 +537,16 @@ void ahci_command_verify(AHCIQState *ahci, AHCICommand *cmd);
 void ahci_command_free(AHCICommand *cmd);
 
 /* Command adjustments */
+void ahci_command_set_flags(AHCICommand *cmd, uint16_t cmdh_flags);
+void ahci_command_clr_flags(AHCICommand *cmd, uint16_t cmdh_flags);
+void ahci_command_set_offset(AHCICommand *cmd, uint64_t lba_sect);
 void ahci_command_set_buffer(AHCICommand *cmd, uint64_t buffer);
 void ahci_command_set_size(AHCICommand *cmd, uint64_t xbytes);
 void ahci_command_set_prd_size(AHCICommand *cmd, unsigned prd_size);
 void ahci_command_set_sizes(AHCICommand *cmd, uint64_t xbytes,
                             unsigned prd_size);
+void ahci_command_adjust(AHCICommand *cmd, uint64_t lba_sect, uint64_t gbuffer,
+                         uint64_t xbytes, unsigned prd_size);
 
 /* Command Misc */
 uint8_t ahci_command_slot(AHCICommand *cmd);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 4/8] qtest/ahci: Add DMA test variants
  2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
                   ` (2 preceding siblings ...)
  2015-02-19 22:29 ` [Qemu-devel] [PATCH 3/8] libqos/ahci: add ahci command helpers John Snow
@ 2015-02-19 22:29 ` John Snow
  2015-02-19 22:30 ` [Qemu-devel] [PATCH 5/8] qtest/ahci: Add PIO and LBA48 tests John Snow
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: John Snow @ 2015-02-19 22:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, John Snow, armbru, stefanha

These test a few different pathways in the AHCI code.

short:  Test the minimum transfer size, exactly one sector.
simple: Test a transfer using a single PRD, in this case, 4K.
double: Test transferring 8K, which we will split up as two PRDs.
long:   Test transferring a lot of data using many PRDs, 256K.
Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/ahci-test.c | 38 ++++++++++++++++++++++++++++++--------
 1 file changed, 30 insertions(+), 8 deletions(-)

diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 9fe9fb5..9394d85 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -731,12 +731,11 @@ static void ahci_test_identify(AHCIQState *ahci)
     g_assert_cmphex(sect_size, ==, 0x200);
 }
 
-static void ahci_test_dma_rw_simple(AHCIQState *ahci)
+static void ahci_test_dma_rw_simple(AHCIQState *ahci, unsigned bufsize)
 {
     uint64_t ptr;
     uint8_t port;
     unsigned i;
-    const unsigned bufsize = 4096;
     unsigned char *tx = g_malloc(bufsize);
     unsigned char *rx = g_malloc0(bufsize);
 
@@ -751,7 +750,7 @@ static void ahci_test_dma_rw_simple(AHCIQState *ahci)
     ptr = ahci_alloc(ahci, bufsize);
     g_assert(ptr);
 
-    /* Write some indicative pattern to our 4K buffer. */
+    /* Write some indicative pattern to our buffer. */
     for (i = 0; i < bufsize; i++) {
         tx[i] = (bufsize - i);
     }
@@ -852,15 +851,35 @@ static void test_identify(void)
 }
 
 /**
- * Perform a simple DMA R/W test, using a single PRD and non-NCQ commands.
+ * Perform a simple DMA R/W test using non-NCQ commands.
  */
+static void test_dma_rw_interface(unsigned bufsize)
+{
+    AHCIQState *ahci;
+
+    ahci = ahci_boot_and_enable();
+    ahci_test_dma_rw_simple(ahci, bufsize);
+    ahci_shutdown(ahci);
+}
+
 static void test_dma_rw_simple(void)
 {
-    AHCIQState *ahci;
+    test_dma_rw_interface(4096);
+}
 
-    ahci = ahci_boot_and_enable();
-    ahci_test_dma_rw_simple(ahci);
-    ahci_shutdown(ahci);
+static void test_dma_rw_double(void)
+{
+    test_dma_rw_interface(8192);
+}
+
+static void test_dma_rw_long(void)
+{
+    test_dma_rw_interface(4096 * 64);
+}
+
+static void test_dma_rw_short(void)
+{
+    test_dma_rw_interface(512);
 }
 
 /******************************************************************************/
@@ -919,6 +938,9 @@ int main(int argc, char **argv)
     qtest_add_func("/ahci/hba_enable", test_hba_enable);
     qtest_add_func("/ahci/identify",   test_identify);
     qtest_add_func("/ahci/dma/simple", test_dma_rw_simple);
+    qtest_add_func("/ahci/dma/double", test_dma_rw_double);
+    qtest_add_func("/ahci/dma/long",   test_dma_rw_long);
+    qtest_add_func("/ahci/dma/short",  test_dma_rw_short);
 
     ret = g_test_run();
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 5/8] qtest/ahci: Add PIO and LBA48 tests
  2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
                   ` (3 preceding siblings ...)
  2015-02-19 22:29 ` [Qemu-devel] [PATCH 4/8] qtest/ahci: Add DMA test variants John Snow
@ 2015-02-19 22:30 ` John Snow
  2015-02-19 22:30 ` [Qemu-devel] [PATCH 6/8] qtest/ahci: add fragmented dma test John Snow
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: John Snow @ 2015-02-19 22:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, John Snow, armbru, stefanha

In addition to DMA tests, test PIO and LBA48 command pathways in AHCI.
To accomplish this, a primitive multiplexer for gtest is added.

Though guests may prefer not to issue PIO commands directly except
for single sector cases during early boot and shutdown, these pathways
are still used for the transfer of ATAPI commands as well, and should
be behaving well.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/ahci-test.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 133 insertions(+), 22 deletions(-)

diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 9394d85..cef8e2f 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -731,7 +731,8 @@ static void ahci_test_identify(AHCIQState *ahci)
     g_assert_cmphex(sect_size, ==, 0x200);
 }
 
-static void ahci_test_dma_rw_simple(AHCIQState *ahci, unsigned bufsize)
+static void ahci_test_io_rw_simple(AHCIQState *ahci, unsigned bufsize,
+                                   uint8_t read_cmd, uint8_t write_cmd)
 {
     uint64_t ptr;
     uint8_t port;
@@ -757,9 +758,9 @@ static void ahci_test_dma_rw_simple(AHCIQState *ahci, unsigned bufsize)
     memwrite(ptr, tx, bufsize);
 
     /* Write this buffer to disk, then read it back to the DMA buffer. */
-    ahci_guest_io(ahci, port, CMD_WRITE_DMA, ptr, bufsize);
+    ahci_guest_io(ahci, port, write_cmd, ptr, bufsize);
     qmemset(ptr, 0x00, bufsize);
-    ahci_guest_io(ahci, port, CMD_READ_DMA, ptr, bufsize);
+    ahci_guest_io(ahci, port, read_cmd, ptr, bufsize);
 
     /*** Read back the Data ***/
     memread(ptr, rx, bufsize);
@@ -850,36 +851,141 @@ static void test_identify(void)
     ahci_shutdown(ahci);
 }
 
+/******************************************************************************/
+/* AHCI I/O Test Matrix Definitions                                           */
+
+enum BuffLen {
+    LEN_BEGIN = 0,
+    LEN_SIMPLE = LEN_BEGIN,
+    LEN_DOUBLE,
+    LEN_LONG,
+    LEN_SHORT,
+    NUM_LENGTHS
+};
+
+static const char *buff_len_str[NUM_LENGTHS] = { "simple", "double",
+                                                 "long", "short" };
+
+enum AddrMode {
+    ADDR_MODE_BEGIN = 0,
+    ADDR_MODE_LBA28 = ADDR_MODE_BEGIN,
+    ADDR_MODE_LBA48,
+    NUM_ADDR_MODES
+};
+
+static const char *addr_mode_str[NUM_ADDR_MODES] = { "lba28", "lba48" };
+
+enum IOMode {
+    MODE_BEGIN = 0,
+    MODE_PIO = MODE_BEGIN,
+    MODE_DMA,
+    NUM_MODES
+};
+
+static const char *io_mode_str[NUM_MODES] = { "pio", "dma" };
+
+enum IOOps {
+    IO_BEGIN = 0,
+    IO_READ = IO_BEGIN,
+    IO_WRITE,
+    NUM_IO_OPS
+};
+
+typedef struct AHCIIOTestOptions {
+    enum BuffLen length;
+    enum AddrMode address_type;
+    enum IOMode io_type;
+} AHCIIOTestOptions;
+
 /**
- * Perform a simple DMA R/W test using non-NCQ commands.
+ * Table of possible I/O ATA commands given a set of enumerations.
  */
-static void test_dma_rw_interface(unsigned bufsize)
+static const uint8_t io_cmds[NUM_MODES][NUM_ADDR_MODES][NUM_IO_OPS] = {
+    [MODE_PIO] = {
+        [ADDR_MODE_LBA28] = {
+            [IO_READ] = CMD_READ_PIO,
+            [IO_WRITE] = CMD_WRITE_PIO },
+        [ADDR_MODE_LBA48] = {
+            [IO_READ] = CMD_READ_PIO_EXT,
+            [IO_WRITE] = CMD_WRITE_PIO_EXT }
+    },
+    [MODE_DMA] = {
+        [ADDR_MODE_LBA28] = {
+            [IO_READ] = CMD_READ_DMA,
+            [IO_WRITE] = CMD_WRITE_DMA },
+        [ADDR_MODE_LBA48] = {
+            [IO_READ] = CMD_READ_DMA_EXT,
+            [IO_WRITE] = CMD_WRITE_DMA_EXT }
+    }
+};
+
+/**
+ * Test a Read/Write pattern using various commands, addressing modes,
+ * transfer modes, and buffer sizes.
+ */
+static void test_io_rw_interface(enum AddrMode lba48, enum IOMode dma,
+                                 unsigned bufsize)
 {
     AHCIQState *ahci;
 
     ahci = ahci_boot_and_enable();
-    ahci_test_dma_rw_simple(ahci, bufsize);
+    ahci_test_io_rw_simple(ahci, bufsize,
+                           io_cmds[dma][lba48][IO_READ],
+                           io_cmds[dma][lba48][IO_WRITE]);
     ahci_shutdown(ahci);
 }
 
-static void test_dma_rw_simple(void)
+/**
+ * Demultiplex the test data and invoke the actual test routine.
+ */
+static void test_io_interface(gconstpointer opaque)
 {
-    test_dma_rw_interface(4096);
-}
+    AHCIIOTestOptions *opts = (AHCIIOTestOptions *)opaque;
+    unsigned bufsize;
 
-static void test_dma_rw_double(void)
-{
-    test_dma_rw_interface(8192);
-}
+    switch (opts->length) {
+    case LEN_SIMPLE:
+        bufsize = 4096;
+        break;
+    case LEN_DOUBLE:
+        bufsize = 8192;
+        break;
+    case LEN_LONG:
+        bufsize = 4096 * 64;
+        break;
+    case LEN_SHORT:
+        bufsize = 512;
+        break;
+    default:
+        g_assert_not_reached();
+    }
 
-static void test_dma_rw_long(void)
-{
-    test_dma_rw_interface(4096 * 64);
+    test_io_rw_interface(opts->address_type, opts->io_type, bufsize);
+    g_free(opts);
+    return;
 }
 
-static void test_dma_rw_short(void)
+static void create_ahci_io_test(enum IOMode type, enum AddrMode addr,
+                                enum BuffLen len)
 {
-    test_dma_rw_interface(512);
+    static const char *arch;
+    char *name;
+    AHCIIOTestOptions *opts = g_malloc(sizeof(AHCIIOTestOptions));
+
+    opts->length = len;
+    opts->address_type = addr;
+    opts->io_type = type;
+
+    if (!arch) {
+        arch = qtest_get_arch();
+    }
+
+    name = g_strdup_printf("/%s/ahci/io/%s/%s/%s", arch,
+                           io_mode_str[type],
+                           addr_mode_str[addr],
+                           buff_len_str[len]);
+
+    g_test_add_data_func(name, opts, test_io_interface);
 }
 
 /******************************************************************************/
@@ -890,6 +996,7 @@ int main(int argc, char **argv)
     int fd;
     int ret;
     int c;
+    int i, j, k;
 
     static struct option long_options[] = {
         {"pedantic", no_argument, 0, 'p' },
@@ -937,10 +1044,14 @@ int main(int argc, char **argv)
     qtest_add_func("/ahci/hba_spec",   test_hba_spec);
     qtest_add_func("/ahci/hba_enable", test_hba_enable);
     qtest_add_func("/ahci/identify",   test_identify);
-    qtest_add_func("/ahci/dma/simple", test_dma_rw_simple);
-    qtest_add_func("/ahci/dma/double", test_dma_rw_double);
-    qtest_add_func("/ahci/dma/long",   test_dma_rw_long);
-    qtest_add_func("/ahci/dma/short",  test_dma_rw_short);
+
+    for (i = MODE_BEGIN; i < NUM_MODES; i++) {
+        for (j = ADDR_MODE_BEGIN; j < NUM_ADDR_MODES; j++) {
+            for (k = LEN_BEGIN; k < NUM_LENGTHS; k++) {
+                create_ahci_io_test(i, j, k);
+            }
+        }
+    }
 
     ret = g_test_run();
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 6/8] qtest/ahci: add fragmented dma test
  2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
                   ` (4 preceding siblings ...)
  2015-02-19 22:30 ` [Qemu-devel] [PATCH 5/8] qtest/ahci: Add PIO and LBA48 tests John Snow
@ 2015-02-19 22:30 ` John Snow
  2015-02-19 22:30 ` [Qemu-devel] [PATCH 7/8] qtest/ahci: add qcow2 support to ahci-test John Snow
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: John Snow @ 2015-02-19 22:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, John Snow, armbru, stefanha

Test what happens when we try to use extremely short PRDTs
to accomplish a small data transfer.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/ahci-test.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index cef8e2f..0d4a3df 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -851,6 +851,63 @@ static void test_identify(void)
     ahci_shutdown(ahci);
 }
 
+/**
+ * Fragmented DMA test: Perform a standard 4K DMA read/write
+ * test, but make sure the physical regions are fragmented to
+ * be very small, each just 32 bytes, to see how AHCI performs
+ * with chunks defined to be much less than a sector.
+ */
+static void test_dma_fragmented(void)
+{
+    AHCIQState *ahci;
+    AHCICommand *cmd;
+    uint8_t px;
+    size_t bufsize = 4096;
+    unsigned char *tx = g_malloc(bufsize);
+    unsigned char *rx = g_malloc0(bufsize);
+    unsigned i;
+    uint64_t ptr;
+
+    ahci = ahci_boot_and_enable();
+    px = ahci_port_select(ahci);
+    ahci_port_clear(ahci, px);
+
+    /* create pattern */
+    for (i = 0; i < bufsize; i++) {
+        tx[i] = (bufsize - i);
+    }
+
+    /* Create a DMA buffer in guest memory, and write our pattern to it. */
+    ptr = guest_alloc(ahci->parent->alloc, bufsize);
+    g_assert(ptr);
+    memwrite(ptr, tx, bufsize);
+
+    cmd = ahci_command_create(CMD_WRITE_DMA);
+    ahci_command_adjust(cmd, 0, ptr, bufsize, 32);
+    ahci_command_commit(ahci, cmd, px);
+    ahci_command_issue(ahci, cmd);
+    ahci_command_verify(ahci, cmd);
+    g_free(cmd);
+
+    cmd = ahci_command_create(CMD_READ_DMA);
+    ahci_command_adjust(cmd, 0, ptr, bufsize, 32);
+    ahci_command_commit(ahci, cmd, px);
+    ahci_command_issue(ahci, cmd);
+    ahci_command_verify(ahci, cmd);
+    g_free(cmd);
+
+    /* Read back the guest's receive buffer into local memory */
+    memread(ptr, rx, bufsize);
+    guest_free(ahci->parent->alloc, ptr);
+
+    g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0);
+
+    ahci_shutdown(ahci);
+
+    g_free(rx);
+    g_free(tx);
+}
+
 /******************************************************************************/
 /* AHCI I/O Test Matrix Definitions                                           */
 
@@ -1053,6 +1110,8 @@ int main(int argc, char **argv)
         }
     }
 
+    qtest_add_func("/ahci/io/dma/lba28/fragmented", test_dma_fragmented);
+
     ret = g_test_run();
 
     /* Cleanup */
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 7/8] qtest/ahci: add qcow2 support to ahci-test
  2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
                   ` (5 preceding siblings ...)
  2015-02-19 22:30 ` [Qemu-devel] [PATCH 6/8] qtest/ahci: add fragmented dma test John Snow
@ 2015-02-19 22:30 ` John Snow
  2015-02-25 15:27   ` Stefan Hajnoczi
  2015-02-19 22:30 ` [Qemu-devel] [PATCH 8/8] qtest/ahci: test different disk sectors John Snow
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: John Snow @ 2015-02-19 22:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, John Snow, armbru, stefanha

This will enable the testing of high offsets without
wasting a lot of disk space, and does not impact the
previous tests.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/ahci-test.c     | 15 +++++----------
 tests/libqos/libqos.c | 30 ++++++++++++++++++++++++++++++
 tests/libqos/libqos.h |  1 +
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 0d4a3df..38550c6 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -39,8 +39,8 @@
 #include "hw/pci/pci_ids.h"
 #include "hw/pci/pci_regs.h"
 
-/* Test-specific defines. */
-#define TEST_IMAGE_SIZE    (64 * 1024 * 1024)
+/* Test-specific defines -- in MiB */
+#define TEST_IMAGE_SIZE_MB (200 * 1024)
 
 /*** Globals ***/
 static char tmp_path[] = "/tmp/qtest.XXXXXX";
@@ -81,7 +81,7 @@ static AHCIQState *ahci_boot(void)
     s = g_malloc0(sizeof(AHCIQState));
 
     cli = "-drive if=none,id=drive0,file=%s,cache=writeback,serial=%s"
-        ",format=raw"
+        ",format=qcow2"
         " -M q35 "
         "-device ide-hd,drive=drive0 "
         "-global ide-hd.ver=%s";
@@ -1050,7 +1050,6 @@ static void create_ahci_io_test(enum IOMode type, enum AddrMode addr,
 int main(int argc, char **argv)
 {
     const char *arch;
-    int fd;
     int ret;
     int c;
     int i, j, k;
@@ -1087,12 +1086,8 @@ int main(int argc, char **argv)
         return 0;
     }
 
-    /* Create a temporary raw image */
-    fd = mkstemp(tmp_path);
-    g_assert(fd >= 0);
-    ret = ftruncate(fd, TEST_IMAGE_SIZE);
-    g_assert(ret == 0);
-    close(fd);
+    /* Create a temporary qcow2 image */
+    mkqcow2(tmp_path, TEST_IMAGE_SIZE_MB);
 
     /* Run the tests */
     qtest_add_func("/ahci/sanity",     test_sanity);
diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index bc8beb2..3577401 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -61,3 +61,33 @@ void qtest_shutdown(QOSState *qs)
     qtest_quit(qs->qts);
     g_free(qs);
 }
+
+int mkqcow2(const char *file, unsigned size_mb)
+{
+    pid_t pid;
+    int rc;
+    char buff[32];
+
+    snprintf(buff, 32, "%uM", size_mb);
+
+    pid = fork();
+    switch (pid) {
+    case -1:
+        perror("fork failed");
+        return -1;
+    case 0:
+        close(fileno(stdout));
+        rc = open("/dev/null", O_WRONLY);
+        g_assert_cmpint(rc, ==, fileno(stdout));
+        execl("./qemu-img", "qemu-img", "create", "-f", "qcow2",
+              file, buff, NULL);
+        perror("execl failed");
+        exit(-1);
+    default:
+        wait(&rc);
+        g_assert_cmpint(rc, ==, 0);
+        return rc;
+    }
+
+    g_assert_not_reached();
+}
diff --git a/tests/libqos/libqos.h b/tests/libqos/libqos.h
index 612d41e..5abd2bd 100644
--- a/tests/libqos/libqos.h
+++ b/tests/libqos/libqos.h
@@ -19,6 +19,7 @@ typedef struct QOSState {
 QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap);
 QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...);
 void qtest_shutdown(QOSState *qs);
+int mkqcow2(const char *file, unsigned size_mb);
 
 static inline uint64_t qmalloc(QOSState *q, size_t bytes)
 {
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 8/8] qtest/ahci: test different disk sectors
  2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
                   ` (6 preceding siblings ...)
  2015-02-19 22:30 ` [Qemu-devel] [PATCH 7/8] qtest/ahci: add qcow2 support to ahci-test John Snow
@ 2015-02-19 22:30 ` John Snow
  2015-02-24 17:58 ` [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
  2015-02-25 15:29 ` Stefan Hajnoczi
  9 siblings, 0 replies; 14+ messages in thread
From: John Snow @ 2015-02-19 22:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, John Snow, armbru, stefanha

Test sector offset 0, 1, and the last sector(s)
in LBA28 and LBA48 modes.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/ahci-test.c   | 69 +++++++++++++++++++++++++++++++++++++++++++----------
 tests/libqos/ahci.c | 10 ++++----
 tests/libqos/ahci.h |  4 ++--
 3 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 38550c6..f536b19 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -41,6 +41,8 @@
 
 /* Test-specific defines -- in MiB */
 #define TEST_IMAGE_SIZE_MB (200 * 1024)
+#define TEST_IMAGE_SECTORS ((TEST_IMAGE_SIZE_MB / AHCI_SECTOR_SIZE)     \
+                            * 1024 * 1024)
 
 /*** Globals ***/
 static char tmp_path[] = "/tmp/qtest.XXXXXX";
@@ -712,7 +714,7 @@ static void ahci_test_identify(AHCIQState *ahci)
     ahci_port_clear(ahci, px);
 
     /* "Read" 512 bytes using CMD_IDENTIFY into the host buffer. */
-    ahci_io(ahci, px, CMD_IDENTIFY, &buff, buffsize);
+    ahci_io(ahci, px, CMD_IDENTIFY, &buff, buffsize, 0);
 
     /* Check serial number/version in the buffer */
     /* NB: IDENTIFY strings are packed in 16bit little endian chunks.
@@ -728,11 +730,12 @@ static void ahci_test_identify(AHCIQState *ahci)
     g_assert_cmphex(rc, ==, 0);
 
     sect_size = le16_to_cpu(*((uint16_t *)(&buff[5])));
-    g_assert_cmphex(sect_size, ==, 0x200);
+    g_assert_cmphex(sect_size, ==, AHCI_SECTOR_SIZE);
 }
 
 static void ahci_test_io_rw_simple(AHCIQState *ahci, unsigned bufsize,
-                                   uint8_t read_cmd, uint8_t write_cmd)
+                                   uint64_t sector, uint8_t read_cmd,
+                                   uint8_t write_cmd)
 {
     uint64_t ptr;
     uint8_t port;
@@ -758,9 +761,9 @@ static void ahci_test_io_rw_simple(AHCIQState *ahci, unsigned bufsize,
     memwrite(ptr, tx, bufsize);
 
     /* Write this buffer to disk, then read it back to the DMA buffer. */
-    ahci_guest_io(ahci, port, write_cmd, ptr, bufsize);
+    ahci_guest_io(ahci, port, write_cmd, ptr, bufsize, sector);
     qmemset(ptr, 0x00, bufsize);
-    ahci_guest_io(ahci, port, read_cmd, ptr, bufsize);
+    ahci_guest_io(ahci, port, read_cmd, ptr, bufsize, sector);
 
     /*** Read back the Data ***/
     memread(ptr, rx, bufsize);
@@ -948,12 +951,45 @@ enum IOOps {
     NUM_IO_OPS
 };
 
+enum OffsetType {
+    OFFSET_BEGIN = 0,
+    OFFSET_ZERO = OFFSET_BEGIN,
+    OFFSET_LOW,
+    OFFSET_HIGH,
+    NUM_OFFSETS
+};
+
+static const char *offset_str[NUM_OFFSETS] = { "zero", "low", "high" };
+
 typedef struct AHCIIOTestOptions {
     enum BuffLen length;
     enum AddrMode address_type;
     enum IOMode io_type;
+    enum OffsetType offset;
 } AHCIIOTestOptions;
 
+static uint64_t offset_sector(enum OffsetType ofst,
+                              enum AddrMode addr_type,
+                              uint64_t buffsize)
+{
+    uint64_t ceil;
+    uint64_t nsectors;
+
+    switch (ofst) {
+    case OFFSET_ZERO:
+        return 0;
+    case OFFSET_LOW:
+        return 1;
+    case OFFSET_HIGH:
+        ceil = (addr_type == ADDR_MODE_LBA28) ? 0xfffffff : 0xffffffffffff;
+        ceil = MIN(ceil, TEST_IMAGE_SECTORS - 1);
+        nsectors = buffsize / AHCI_SECTOR_SIZE;
+        return ceil - nsectors + 1;
+    default:
+        g_assert_not_reached();
+    }
+}
+
 /**
  * Table of possible I/O ATA commands given a set of enumerations.
  */
@@ -981,12 +1017,12 @@ static const uint8_t io_cmds[NUM_MODES][NUM_ADDR_MODES][NUM_IO_OPS] = {
  * transfer modes, and buffer sizes.
  */
 static void test_io_rw_interface(enum AddrMode lba48, enum IOMode dma,
-                                 unsigned bufsize)
+                                 unsigned bufsize, uint64_t sector)
 {
     AHCIQState *ahci;
 
     ahci = ahci_boot_and_enable();
-    ahci_test_io_rw_simple(ahci, bufsize,
+    ahci_test_io_rw_simple(ahci, bufsize, sector,
                            io_cmds[dma][lba48][IO_READ],
                            io_cmds[dma][lba48][IO_WRITE]);
     ahci_shutdown(ahci);
@@ -999,6 +1035,7 @@ static void test_io_interface(gconstpointer opaque)
 {
     AHCIIOTestOptions *opts = (AHCIIOTestOptions *)opaque;
     unsigned bufsize;
+    uint64_t sector;
 
     switch (opts->length) {
     case LEN_SIMPLE:
@@ -1017,13 +1054,14 @@ static void test_io_interface(gconstpointer opaque)
         g_assert_not_reached();
     }
 
-    test_io_rw_interface(opts->address_type, opts->io_type, bufsize);
+    sector = offset_sector(opts->offset, opts->address_type, bufsize);
+    test_io_rw_interface(opts->address_type, opts->io_type, bufsize, sector);
     g_free(opts);
     return;
 }
 
 static void create_ahci_io_test(enum IOMode type, enum AddrMode addr,
-                                enum BuffLen len)
+                                enum BuffLen len, enum OffsetType offset)
 {
     static const char *arch;
     char *name;
@@ -1032,17 +1070,20 @@ static void create_ahci_io_test(enum IOMode type, enum AddrMode addr,
     opts->length = len;
     opts->address_type = addr;
     opts->io_type = type;
+    opts->offset = offset;
 
     if (!arch) {
         arch = qtest_get_arch();
     }
 
-    name = g_strdup_printf("/%s/ahci/io/%s/%s/%s", arch,
+    name = g_strdup_printf("/%s/ahci/io/%s/%s/%s/%s", arch,
                            io_mode_str[type],
                            addr_mode_str[addr],
-                           buff_len_str[len]);
+                           buff_len_str[len],
+                           offset_str[offset]);
 
     g_test_add_data_func(name, opts, test_io_interface);
+    g_free(name);
 }
 
 /******************************************************************************/
@@ -1052,7 +1093,7 @@ int main(int argc, char **argv)
     const char *arch;
     int ret;
     int c;
-    int i, j, k;
+    int i, j, k, m;
 
     static struct option long_options[] = {
         {"pedantic", no_argument, 0, 'p' },
@@ -1100,7 +1141,9 @@ int main(int argc, char **argv)
     for (i = MODE_BEGIN; i < NUM_MODES; i++) {
         for (j = ADDR_MODE_BEGIN; j < NUM_ADDR_MODES; j++) {
             for (k = LEN_BEGIN; k < NUM_LENGTHS; k++) {
-                create_ahci_io_test(i, j, k);
+                for (m = OFFSET_BEGIN; m < NUM_OFFSETS; m++) {
+                    create_ahci_io_test(i, j, k, m);
+                }
             }
         }
     }
diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 1d92438..8bb9e3e 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -568,13 +568,15 @@ inline unsigned size_to_prdtl(unsigned bytes, unsigned bytes_per_prd)
 
 /* Given a guest buffer address, perform an IO operation */
 void ahci_guest_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
-                   uint64_t buffer, size_t bufsize)
+                   uint64_t buffer, size_t bufsize, uint64_t sector)
 {
     AHCICommand *cmd;
-
     cmd = ahci_command_create(ide_cmd);
     ahci_command_set_buffer(cmd, buffer);
     ahci_command_set_size(cmd, bufsize);
+    if (sector) {
+        ahci_command_set_offset(cmd, sector);
+    }
     ahci_command_commit(ahci, cmd, port);
     ahci_command_issue(ahci, cmd);
     ahci_command_verify(ahci, cmd);
@@ -612,7 +614,7 @@ static AHCICommandProp *ahci_command_find(uint8_t command_name)
 
 /* Given a HOST buffer, create a buffer address and perform an IO operation. */
 void ahci_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
-             void *buffer, size_t bufsize)
+             void *buffer, size_t bufsize, uint64_t sector)
 {
     uint64_t ptr;
     AHCICommandProp *props;
@@ -626,7 +628,7 @@ void ahci_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
         memwrite(ptr, buffer, bufsize);
     }
 
-    ahci_guest_io(ahci, port, ide_cmd, ptr, bufsize);
+    ahci_guest_io(ahci, port, ide_cmd, ptr, bufsize, sector);
 
     if (props->read) {
         memread(ptr, buffer, bufsize);
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index 888545d..40e8ca4 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -523,9 +523,9 @@ void ahci_write_fis(AHCIQState *ahci, RegH2DFIS *fis, uint64_t addr);
 unsigned ahci_pick_cmd(AHCIQState *ahci, uint8_t port);
 unsigned size_to_prdtl(unsigned bytes, unsigned bytes_per_prd);
 void ahci_guest_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
-                   uint64_t gbuffer, size_t size);
+                   uint64_t gbuffer, size_t size, uint64_t sector);
 void ahci_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
-             void *buffer, size_t bufsize);
+             void *buffer, size_t bufsize, uint64_t sector);
 
 /* Command Lifecycle */
 AHCICommand *ahci_command_create(uint8_t command_name);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 0/8] ahci: add more IO tests
  2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
                   ` (7 preceding siblings ...)
  2015-02-19 22:30 ` [Qemu-devel] [PATCH 8/8] qtest/ahci: test different disk sectors John Snow
@ 2015-02-24 17:58 ` John Snow
  2015-02-25 15:29 ` Stefan Hajnoczi
  9 siblings, 0 replies; 14+ messages in thread
From: John Snow @ 2015-02-24 17:58 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, armbru, stefanha



On 02/19/2015 05:29 PM, John Snow wrote:
> This series is based on top of my ahci DMA test series, which is in
> turn based on the ahci preliminary refactoring series. Both are currently
> pending on stefanha/block.
>

prerequisites are now upstream.
--js

> This series adds many variations that expand on the existing trivial
> DMA I/O case. These pathways check different PRDT configurations,
> different I/O commands for PIO and DMA, different address scheme
> combinations for LBA28 and LBA48, and different sector offsets.
>
> John Snow (8):
>    libqos/ahci: Zero-fill AHCI headers
>    qtest/ahci: Add a macro bootup routine
>    libqos/ahci: add ahci command helpers
>    qtest/ahci: Add DMA test variants
>    qtest/ahci: Add PIO and LBA48 tests
>    qtest/ahci: add fragmented dma test
>    qtest/ahci: add qcow2 support to ahci-test
>    qtest/ahci: test different disk sectors
>
>   tests/ahci-test.c     | 295 +++++++++++++++++++++++++++++++++++++++++++++-----
>   tests/libqos/ahci.c   |  54 ++++++++-
>   tests/libqos/ahci.h   |   9 +-
>   tests/libqos/libqos.c |  30 +++++
>   tests/libqos/libqos.h |   1 +
>   5 files changed, 355 insertions(+), 34 deletions(-)
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 7/8] qtest/ahci: add qcow2 support to ahci-test
  2015-02-19 22:30 ` [Qemu-devel] [PATCH 7/8] qtest/ahci: add qcow2 support to ahci-test John Snow
@ 2015-02-25 15:27   ` Stefan Hajnoczi
  2015-02-25 22:40     ` John Snow
  0 siblings, 1 reply; 14+ messages in thread
From: Stefan Hajnoczi @ 2015-02-25 15:27 UTC (permalink / raw)
  To: John Snow; +Cc: kwolf, qemu-devel, stefanha, armbru

[-- Attachment #1: Type: text/plain, Size: 2064 bytes --]

On Thu, Feb 19, 2015 at 05:30:02PM -0500, John Snow wrote:
> diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
> index bc8beb2..3577401 100644
> --- a/tests/libqos/libqos.c
> +++ b/tests/libqos/libqos.c
> @@ -61,3 +61,33 @@ void qtest_shutdown(QOSState *qs)
>      qtest_quit(qs->qts);
>      g_free(qs);
>  }
> +
> +int mkqcow2(const char *file, unsigned size_mb)
> +{
> +    pid_t pid;
> +    int rc;
> +    char buff[32];
> +
> +    snprintf(buff, 32, "%uM", size_mb);
> +
> +    pid = fork();
> +    switch (pid) {
> +    case -1:
> +        perror("fork failed");
> +        return -1;
> +    case 0:
> +        close(fileno(stdout));
> +        rc = open("/dev/null", O_WRONLY);
> +        g_assert_cmpint(rc, ==, fileno(stdout));
> +        execl("./qemu-img", "qemu-img", "create", "-f", "qcow2",
> +              file, buff, NULL);

Where is the current working directory set?

Will this work for both in-tree and out-of-tree builds?

BTW, glib abstracts process spawning, maybe all this can be done in a
single function call:
https://developer.gnome.org/glib/stable/glib-Spawning-Processes.html#g-spawn-sync

> +        perror("execl failed");
> +        exit(-1);

EXIT_FAILURE is provided by the C standard for returning failure.  (-1
is confusing because the shell exit code value cannot be negative.)

> +    default:
> +        wait(&rc);
> +        g_assert_cmpint(rc, ==, 0);
> +        return rc;
> +    }
> +
> +    g_assert_not_reached();
> +}
> diff --git a/tests/libqos/libqos.h b/tests/libqos/libqos.h
> index 612d41e..5abd2bd 100644
> --- a/tests/libqos/libqos.h
> +++ b/tests/libqos/libqos.h
> @@ -19,6 +19,7 @@ typedef struct QOSState {
>  QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap);
>  QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...);
>  void qtest_shutdown(QOSState *qs);
> +int mkqcow2(const char *file, unsigned size_mb);
>  
>  static inline uint64_t qmalloc(QOSState *q, size_t bytes)
>  {
> -- 
> 1.9.3
> 
> 

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 0/8] ahci: add more IO tests
  2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
                   ` (8 preceding siblings ...)
  2015-02-24 17:58 ` [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
@ 2015-02-25 15:29 ` Stefan Hajnoczi
  9 siblings, 0 replies; 14+ messages in thread
From: Stefan Hajnoczi @ 2015-02-25 15:29 UTC (permalink / raw)
  To: John Snow; +Cc: kwolf, qemu-devel, stefanha, armbru

[-- Attachment #1: Type: text/plain, Size: 1234 bytes --]

On Thu, Feb 19, 2015 at 05:29:55PM -0500, John Snow wrote:
> This series is based on top of my ahci DMA test series, which is in
> turn based on the ahci preliminary refactoring series. Both are currently
> pending on stefanha/block.
> 
> This series adds many variations that expand on the existing trivial
> DMA I/O case. These pathways check different PRDT configurations,
> different I/O commands for PIO and DMA, different address scheme
> combinations for LBA28 and LBA48, and different sector offsets.
> 
> John Snow (8):
>   libqos/ahci: Zero-fill AHCI headers
>   qtest/ahci: Add a macro bootup routine
>   libqos/ahci: add ahci command helpers
>   qtest/ahci: Add DMA test variants
>   qtest/ahci: Add PIO and LBA48 tests
>   qtest/ahci: add fragmented dma test
>   qtest/ahci: add qcow2 support to ahci-test
>   qtest/ahci: test different disk sectors
> 
>  tests/ahci-test.c     | 295 +++++++++++++++++++++++++++++++++++++++++++++-----
>  tests/libqos/ahci.c   |  54 ++++++++-
>  tests/libqos/ahci.h   |   9 +-
>  tests/libqos/libqos.c |  30 +++++
>  tests/libqos/libqos.h |   1 +
>  5 files changed, 355 insertions(+), 34 deletions(-)

I'm happy with all patches except the qemu-img spawning.

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 7/8] qtest/ahci: add qcow2 support to ahci-test
  2015-02-25 15:27   ` Stefan Hajnoczi
@ 2015-02-25 22:40     ` John Snow
  2015-02-26 11:01       ` Stefan Hajnoczi
  0 siblings, 1 reply; 14+ messages in thread
From: John Snow @ 2015-02-25 22:40 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: kwolf, qemu-devel, stefanha, armbru



On 02/25/2015 10:27 AM, Stefan Hajnoczi wrote:
> On Thu, Feb 19, 2015 at 05:30:02PM -0500, John Snow wrote:
>> diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
>> index bc8beb2..3577401 100644
>> --- a/tests/libqos/libqos.c
>> +++ b/tests/libqos/libqos.c
>> @@ -61,3 +61,33 @@ void qtest_shutdown(QOSState *qs)
>>       qtest_quit(qs->qts);
>>       g_free(qs);
>>   }
>> +
>> +int mkqcow2(const char *file, unsigned size_mb)
>> +{
>> +    pid_t pid;
>> +    int rc;
>> +    char buff[32];
>> +
>> +    snprintf(buff, 32, "%uM", size_mb);
>> +
>> +    pid = fork();
>> +    switch (pid) {
>> +    case -1:
>> +        perror("fork failed");
>> +        return -1;
>> +    case 0:
>> +        close(fileno(stdout));
>> +        rc = open("/dev/null", O_WRONLY);
>> +        g_assert_cmpint(rc, ==, fileno(stdout));
>> +        execl("./qemu-img", "qemu-img", "create", "-f", "qcow2",
>> +              file, buff, NULL);
>
> Where is the current working directory set?
>

Nowhere in-program. We assume you are running this via `make check` 
which further assumes that qemu-img is in your build tree. We actually 
never set an explicit path for where the QEMU binary is either: it's set 
to e.g.:

QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64
and then executed via execlp("exec QTEST_QEMU_BINARY", ...)

This patch pulls a similar shortcut.

The Makefile blob doesn't actually appear to really ever explicitly set 
a path for where the binaries should be; qemu-img is not defined to be 
in any sort of path, so we can assume that all paths are relative to the 
Makefile.

What I will do is set QTEST_QEMU_IMG to at least match the direct name 
of the QEMU_IMG we generated, so it will have $(EXESUF) attached to it, 
for instance.

> Will this work for both in-tree and out-of-tree builds?
>

Yes. I usually run out of tree, but it works fine in-tree too. As long 
as relative to the Makefile ./qemu-img$(EXESUF) exists, you will be fine.

If you decide to run this outside of make check, you can always set 
QTEST_QEMU_IMG yourself.

> BTW, glib abstracts process spawning, maybe all this can be done in a
> single function call:
> https://developer.gnome.org/glib/stable/glib-Spawning-Processes.html#g-spawn-sync
>

OK, I've implemented it with this call instead. Will send a V2.

>> +        perror("execl failed");
>> +        exit(-1);
>
> EXIT_FAILURE is provided by the C standard for returning failure.  (-1
> is confusing because the shell exit code value cannot be negative.)
>
>> +    default:
>> +        wait(&rc);
>> +        g_assert_cmpint(rc, ==, 0);
>> +        return rc;
>> +    }
>> +
>> +    g_assert_not_reached();
>> +}
>> diff --git a/tests/libqos/libqos.h b/tests/libqos/libqos.h
>> index 612d41e..5abd2bd 100644
>> --- a/tests/libqos/libqos.h
>> +++ b/tests/libqos/libqos.h
>> @@ -19,6 +19,7 @@ typedef struct QOSState {
>>   QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap);
>>   QOSState *qtest_boot(QOSOps *ops, const char *cmdline_fmt, ...);
>>   void qtest_shutdown(QOSState *qs);
>> +int mkqcow2(const char *file, unsigned size_mb);
>>
>>   static inline uint64_t qmalloc(QOSState *q, size_t bytes)
>>   {
>> --
>> 1.9.3
>>
>>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 7/8] qtest/ahci: add qcow2 support to ahci-test
  2015-02-25 22:40     ` John Snow
@ 2015-02-26 11:01       ` Stefan Hajnoczi
  0 siblings, 0 replies; 14+ messages in thread
From: Stefan Hajnoczi @ 2015-02-26 11:01 UTC (permalink / raw)
  To: John Snow; +Cc: kwolf, Stefan Hajnoczi, qemu-devel, armbru

[-- Attachment #1: Type: text/plain, Size: 1601 bytes --]

On Wed, Feb 25, 2015 at 05:40:00PM -0500, John Snow wrote:
> 
> 
> On 02/25/2015 10:27 AM, Stefan Hajnoczi wrote:
> >On Thu, Feb 19, 2015 at 05:30:02PM -0500, John Snow wrote:
> >>diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
> >>index bc8beb2..3577401 100644
> >>--- a/tests/libqos/libqos.c
> >>+++ b/tests/libqos/libqos.c
> >>@@ -61,3 +61,33 @@ void qtest_shutdown(QOSState *qs)
> >>      qtest_quit(qs->qts);
> >>      g_free(qs);
> >>  }
> >>+
> >>+int mkqcow2(const char *file, unsigned size_mb)
> >>+{
> >>+    pid_t pid;
> >>+    int rc;
> >>+    char buff[32];
> >>+
> >>+    snprintf(buff, 32, "%uM", size_mb);
> >>+
> >>+    pid = fork();
> >>+    switch (pid) {
> >>+    case -1:
> >>+        perror("fork failed");
> >>+        return -1;
> >>+    case 0:
> >>+        close(fileno(stdout));
> >>+        rc = open("/dev/null", O_WRONLY);
> >>+        g_assert_cmpint(rc, ==, fileno(stdout));
> >>+        execl("./qemu-img", "qemu-img", "create", "-f", "qcow2",
> >>+              file, buff, NULL);
> >
> >Where is the current working directory set?
> >
> 
> Nowhere in-program. We assume you are running this via `make check` which
> further assumes that qemu-img is in your build tree. We actually never set
> an explicit path for where the QEMU binary is either: it's set to e.g.:
> 
> QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64
> and then executed via execlp("exec QTEST_QEMU_BINARY", ...)
> 
> This patch pulls a similar shortcut.

Okay, if the QEMU binary itself is invoked that way then this is fine.

Stefan

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2015-02-26 11:01 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-19 22:29 [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
2015-02-19 22:29 ` [Qemu-devel] [PATCH 1/8] libqos/ahci: Zero-fill AHCI headers John Snow
2015-02-19 22:29 ` [Qemu-devel] [PATCH 2/8] qtest/ahci: Add a macro bootup routine John Snow
2015-02-19 22:29 ` [Qemu-devel] [PATCH 3/8] libqos/ahci: add ahci command helpers John Snow
2015-02-19 22:29 ` [Qemu-devel] [PATCH 4/8] qtest/ahci: Add DMA test variants John Snow
2015-02-19 22:30 ` [Qemu-devel] [PATCH 5/8] qtest/ahci: Add PIO and LBA48 tests John Snow
2015-02-19 22:30 ` [Qemu-devel] [PATCH 6/8] qtest/ahci: add fragmented dma test John Snow
2015-02-19 22:30 ` [Qemu-devel] [PATCH 7/8] qtest/ahci: add qcow2 support to ahci-test John Snow
2015-02-25 15:27   ` Stefan Hajnoczi
2015-02-25 22:40     ` John Snow
2015-02-26 11:01       ` Stefan Hajnoczi
2015-02-19 22:30 ` [Qemu-devel] [PATCH 8/8] qtest/ahci: test different disk sectors John Snow
2015-02-24 17:58 ` [Qemu-devel] [PATCH 0/8] ahci: add more IO tests John Snow
2015-02-25 15:29 ` Stefan Hajnoczi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.