qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject
@ 2016-11-07 21:13 John Snow
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 1/6] " John Snow
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: John Snow @ 2016-11-07 21:13 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pbonzini, pkrempa, qemu-devel, mreitz, John Snow

Requires patches in my IDE branch, for context.

This series changes blk_eject (used for a software-initiated eject request)
to always trigger a QMP tray event, in contrast to the current behavior where
a tray event only occurs if a medium is already in the tray.

V2: Now with tests. (Kevin)

________________________________________________________________________________

For convenience, this branch is available at:
https://github.com/jnsnow/qemu.git branch tray-always-notify
https://github.com/jnsnow/qemu/tree/tray-always-notify

This version is tagged tray-always-notify-v2:
https://github.com/jnsnow/qemu/releases/tag/tray-always-notify-v2

John Snow (6):
  block-backend: Always notify on blk_eject
  libqtest: add qmp_eventwait_ref
  libqos/ahci: Support expected errors
  libqos/ahci: Add ATAPI tray macros
  libqos/ahci: Add get_sense and test_ready
  ahci-test: add QMP tray test for ATAPI

 block/block-backend.c | 13 +++----
 tests/ahci-test.c     | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/ahci.c   | 96 ++++++++++++++++++++++++++++++++++++++++++++++---
 tests/libqos/ahci.h   | 26 ++++++++++++--
 tests/libqtest.c      | 13 +++++--
 tests/libqtest.h      | 22 ++++++++++++
 6 files changed, 252 insertions(+), 16 deletions(-)

-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 1/6] block-backend: Always notify on blk_eject
  2016-11-07 21:13 [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
@ 2016-11-07 21:13 ` John Snow
  2016-11-07 22:01   ` Eric Blake
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 2/6] libqtest: add qmp_eventwait_ref John Snow
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: John Snow @ 2016-11-07 21:13 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pbonzini, pkrempa, qemu-devel, mreitz, John Snow

blk_eject is only used by scsi-disk and atapi, and in both cases we
only attempt to invoke blk_eject if we have a bona-fide change in
tray state.

The "issue" here is that the tray state does not generate a QMP event
unless there is a medium/BDS attached to the device, so if libvirt et al
are waiting for a tray event to occur from an empty-but-closed drive,
software opening that drive will not emit an event and libvirt will
wait forever.

Change this by modifying blk_eject to always emit an event, instead of
conditionally on a "real" backend eject.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1373264

Reported-by: Peter Krempa <pkrempa@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
---
 block/block-backend.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 27a7f6f..efbf398 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1393,13 +1393,14 @@ void blk_eject(BlockBackend *blk, bool eject_flag)
 
     if (bs) {
         bdrv_eject(bs, eject_flag);
-
-        id = blk_get_attached_dev_id(blk);
-        qapi_event_send_device_tray_moved(blk_name(blk), id,
-                                          eject_flag, &error_abort);
-        g_free(id);
-
     }
+
+    /* Whether or not we ejected on the backend,
+     * the frontend experienced a tray event. */
+    id = blk_get_attached_dev_id(blk);
+    qapi_event_send_device_tray_moved(blk_name(blk), id,
+                                      eject_flag, &error_abort);
+    g_free(id);
 }
 
 int blk_get_flags(BlockBackend *blk)
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 2/6] libqtest: add qmp_eventwait_ref
  2016-11-07 21:13 [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 1/6] " John Snow
@ 2016-11-07 21:13 ` John Snow
  2016-11-07 22:25   ` Eric Blake
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 3/6] libqos/ahci: Support expected errors John Snow
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: John Snow @ 2016-11-07 21:13 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pbonzini, pkrempa, qemu-devel, mreitz, John Snow

Wait for an event, but return a copy so we can investigate parameters.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 tests/libqtest.c | 13 ++++++++++---
 tests/libqtest.h | 22 ++++++++++++++++++++++
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index d4e6bff..6f69752 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -533,7 +533,7 @@ void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...)
     QDECREF(response);
 }
 
-void qtest_qmp_eventwait(QTestState *s, const char *event)
+QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event)
 {
     QDict *response;
 
@@ -541,13 +541,20 @@ void qtest_qmp_eventwait(QTestState *s, const char *event)
         response = qtest_qmp_receive(s);
         if ((qdict_haskey(response, "event")) &&
             (strcmp(qdict_get_str(response, "event"), event) == 0)) {
-            QDECREF(response);
-            break;
+            return response;
         }
         QDECREF(response);
     }
 }
 
+void qtest_qmp_eventwait(QTestState *s, const char *event)
+{
+    QDict *response;
+
+    response = qtest_qmp_eventwait_ref(s, event);
+    QDECREF(response);
+}
+
 char *qtest_hmpv(QTestState *s, const char *fmt, va_list ap)
 {
     char *cmd;
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 0224f06..90f182e 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -114,6 +114,16 @@ QDict *qtest_qmp_receive(QTestState *s);
 void qtest_qmp_eventwait(QTestState *s, const char *event);
 
 /**
+ * qtest_qmp_eventwait_ref:
+ * @s: #QTestState instance to operate on.
+ * @s: #event event to wait for.
+ *
+ * Continuosly polls for QMP responses until it receives the desired event.
+ * Returns a copy of the event for further investigation.
+ */
+QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event);
+
+/**
  * qtest_hmpv:
  * @s: #QTestState instance to operate on.
  * @fmt...: HMP command to send to QEMU
@@ -559,6 +569,18 @@ static inline void qmp_eventwait(const char *event)
 }
 
 /**
+ * qmp_eventwait_ref:
+ * @s: #event event to wait for.
+ *
+ * Continuosly polls for QMP responses until it receives the desired event.
+ * Returns a copy of the event for further investigation.
+ */
+static inline QDict *qmp_eventwait_ref(const char *event)
+{
+    return qtest_qmp_eventwait_ref(global_qtest, event);
+}
+
+/**
  * hmp:
  * @fmt...: HMP command to send to QEMU
  *
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 3/6] libqos/ahci: Support expected errors
  2016-11-07 21:13 [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 1/6] " John Snow
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 2/6] libqtest: add qmp_eventwait_ref John Snow
@ 2016-11-07 21:13 ` John Snow
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 4/6] libqos/ahci: Add ATAPI tray macros John Snow
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: John Snow @ 2016-11-07 21:13 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pbonzini, pkrempa, qemu-devel, mreitz, John Snow

Sometimes we know we'll get back an error, so let's have the
test framework understand that.

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

diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 15fa888..77f9bed 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -86,6 +86,7 @@ struct AHCICommand {
     uint8_t name;
     uint8_t port;
     uint8_t slot;
+    uint8_t errors;
     uint32_t interrupts;
     uint64_t xbytes;
     uint32_t prd_size;
@@ -402,12 +403,14 @@ void ahci_port_clear(AHCIQState *ahci, uint8_t port)
 /**
  * Check a port for errors.
  */
-void ahci_port_check_error(AHCIQState *ahci, uint8_t port)
+void ahci_port_check_error(AHCIQState *ahci, uint8_t port,
+                           uint32_t imask, uint8_t emask)
 {
     uint32_t reg;
 
     /* The upper 9 bits of the IS register all indicate errors. */
     reg = ahci_px_rreg(ahci, port, AHCI_PX_IS);
+    reg &= ~imask;
     reg >>= 23;
     g_assert_cmphex(reg, ==, 0);
 
@@ -417,8 +420,13 @@ void ahci_port_check_error(AHCIQState *ahci, uint8_t port)
 
     /* The TFD also has two error sections. */
     reg = ahci_px_rreg(ahci, port, AHCI_PX_TFD);
-    ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_STS_ERR);
-    ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_ERR);
+    if (!emask) {
+        ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_STS_ERR);
+    } else {
+        ASSERT_BIT_SET(reg, AHCI_PX_TFD_STS_ERR);
+    }
+    ASSERT_BIT_CLEAR(reg, AHCI_PX_TFD_ERR & (~emask << 8));
+    ASSERT_BIT_SET(reg, AHCI_PX_TFD_ERR & (emask << 8));
 }
 
 void ahci_port_check_interrupts(AHCIQState *ahci, uint8_t port,
@@ -1118,7 +1126,7 @@ void ahci_command_verify(AHCIQState *ahci, AHCICommand *cmd)
     uint8_t slot = cmd->slot;
     uint8_t port = cmd->port;
 
-    ahci_port_check_error(ahci, port);
+    ahci_port_check_error(ahci, port, cmd->interrupts, cmd->errors);
     ahci_port_check_interrupts(ahci, port, cmd->interrupts);
     ahci_port_check_nonbusy(ahci, port, slot);
     ahci_port_check_cmd_sanity(ahci, cmd);
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index f144fab..bbe04f8 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -576,7 +576,8 @@ void ahci_set_command_header(AHCIQState *ahci, uint8_t port,
 void ahci_destroy_command(AHCIQState *ahci, uint8_t port, uint8_t slot);
 
 /* AHCI sanity check routines */
-void ahci_port_check_error(AHCIQState *ahci, uint8_t port);
+void ahci_port_check_error(AHCIQState *ahci, uint8_t port,
+                           uint32_t imask, uint8_t emask);
 void ahci_port_check_interrupts(AHCIQState *ahci, uint8_t port,
                                 uint32_t intr_mask);
 void ahci_port_check_nonbusy(AHCIQState *ahci, uint8_t port, uint8_t slot);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 4/6] libqos/ahci: Add ATAPI tray macros
  2016-11-07 21:13 [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
                   ` (2 preceding siblings ...)
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 3/6] libqos/ahci: Support expected errors John Snow
@ 2016-11-07 21:13 ` John Snow
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 5/6] libqos/ahci: Add get_sense and test_ready John Snow
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: John Snow @ 2016-11-07 21:13 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pbonzini, pkrempa, qemu-devel, mreitz, John Snow

(1) Add START_STOP_UNIT command to ahci-test suite
(2) Add eject/start macro commands; this is not a data transfer
    command so it is not well-served by the existing generic pipeline.

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

diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 77f9bed..603ecb6 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -882,6 +882,30 @@ AHCICommand *ahci_atapi_command_create(uint8_t scsi_cmd, uint16_t bcl)
     return cmd;
 }
 
+void ahci_atapi_eject(AHCIQState *ahci, uint8_t port)
+{
+    AHCICommand *cmd = ahci_atapi_command_create(CMD_ATAPI_START_STOP_UNIT, 0);
+    ahci_command_set_size(cmd, 0);
+
+    cmd->atapi_cmd[4] = 0x02; /* loej = true */
+    ahci_command_commit(ahci, cmd, port);
+    ahci_command_issue(ahci, cmd);
+    ahci_command_verify(ahci, cmd);
+    ahci_command_free(cmd);
+}
+
+void ahci_atapi_load(AHCIQState *ahci, uint8_t port)
+{
+    AHCICommand *cmd = ahci_atapi_command_create(CMD_ATAPI_START_STOP_UNIT, 0);
+    ahci_command_set_size(cmd, 0);
+
+    cmd->atapi_cmd[4] = 0x03; /* loej,start = true */
+    ahci_command_commit(ahci, cmd, port);
+    ahci_command_issue(ahci, cmd);
+    ahci_command_verify(ahci, cmd);
+    ahci_command_free(cmd);
+}
+
 void ahci_command_free(AHCICommand *cmd)
 {
     g_free(cmd->atapi_cmd);
@@ -910,6 +934,9 @@ static void ahci_atapi_command_set_offset(AHCICommand *cmd, uint64_t lba)
         g_assert_cmpuint(lba, <=, UINT32_MAX);
         stl_be_p(&cbd[2], lba);
         break;
+    case CMD_ATAPI_START_STOP_UNIT:
+        g_assert_cmpuint(lba, ==, 0x00);
+        break;
     default:
         /* SCSI doesn't have uniform packet formats,
          * so you have to add support for it manually. Sorry! */
@@ -976,6 +1003,9 @@ static void ahci_atapi_set_size(AHCICommand *cmd, uint64_t xbytes)
         cbd[7] = (tmp & 0xFF00) >> 8;
         cbd[8] = (tmp & 0xFF);
         break;
+    case CMD_ATAPI_START_STOP_UNIT:
+        g_assert_cmpuint(xbytes, ==, 0);
+        break;
     default:
         /* SCSI doesn't have uniform packet formats,
          * so you have to add support for it manually. Sorry! */
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index bbe04f8..05ce3de 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -287,8 +287,9 @@ enum {
 
 /* ATAPI Commands */
 enum {
-    CMD_ATAPI_READ_10 = 0x28,
-    CMD_ATAPI_READ_CD = 0xbe,
+    CMD_ATAPI_START_STOP_UNIT = 0x1b,
+    CMD_ATAPI_READ_10         = 0x28,
+    CMD_ATAPI_READ_CD         = 0xbe,
 };
 
 /* AHCI Command Header Flags & Masks*/
@@ -600,6 +601,8 @@ void ahci_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
              void *buffer, size_t bufsize, uint64_t sector);
 void ahci_exec(AHCIQState *ahci, uint8_t port,
                uint8_t op, const AHCIOpts *opts);
+void ahci_atapi_eject(AHCIQState *ahci, uint8_t port);
+void ahci_atapi_load(AHCIQState *ahci, uint8_t port);
 
 /* Command: Fine-grained lifecycle */
 AHCICommand *ahci_command_create(uint8_t command_name);
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 5/6] libqos/ahci: Add get_sense and test_ready
  2016-11-07 21:13 [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
                   ` (3 preceding siblings ...)
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 4/6] libqos/ahci: Add ATAPI tray macros John Snow
@ 2016-11-07 21:13 ` John Snow
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 6/6] ahci-test: add QMP tray test for ATAPI John Snow
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: John Snow @ 2016-11-07 21:13 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pbonzini, pkrempa, qemu-devel, mreitz, John Snow

Required for tray tests once a medium may have changed.

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

diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 603ecb6..924c6a8 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -882,6 +882,49 @@ AHCICommand *ahci_atapi_command_create(uint8_t scsi_cmd, uint16_t bcl)
     return cmd;
 }
 
+void ahci_atapi_test_ready(AHCIQState *ahci, uint8_t port,
+                           bool ready, uint8_t expected_sense)
+{
+    AHCICommand *cmd = ahci_atapi_command_create(CMD_ATAPI_TEST_UNIT_READY, 0);
+    ahci_command_set_size(cmd, 0);
+    if (!ready) {
+        cmd->interrupts |= AHCI_PX_IS_TFES;
+        cmd->errors |= expected_sense << 4;
+    }
+    ahci_command_commit(ahci, cmd, port);
+    ahci_command_issue(ahci, cmd);
+    ahci_command_verify(ahci, cmd);
+    ahci_command_free(cmd);
+}
+
+static int copy_buffer(AHCIQState *ahci, AHCICommand *cmd,
+                        const AHCIOpts *opts)
+{
+    unsigned char *rx = opts->opaque;
+    bufread(opts->buffer, rx, opts->size);
+    return 0;
+}
+
+void ahci_atapi_get_sense(AHCIQState *ahci, uint8_t port,
+                          uint8_t *sense, uint8_t *asc)
+{
+    unsigned char *rx;
+    AHCIOpts opts = {
+        .size = 18,
+        .atapi = true,
+        .post_cb = copy_buffer,
+    };
+    rx = g_malloc(18);
+    opts.opaque = rx;
+
+    ahci_exec(ahci, port, CMD_ATAPI_REQUEST_SENSE, &opts);
+
+    *sense = rx[2];
+    *asc = rx[12];
+
+    g_free(rx);
+}
+
 void ahci_atapi_eject(AHCIQState *ahci, uint8_t port)
 {
     AHCICommand *cmd = ahci_atapi_command_create(CMD_ATAPI_START_STOP_UNIT, 0);
@@ -934,6 +977,8 @@ static void ahci_atapi_command_set_offset(AHCICommand *cmd, uint64_t lba)
         g_assert_cmpuint(lba, <=, UINT32_MAX);
         stl_be_p(&cbd[2], lba);
         break;
+    case CMD_ATAPI_REQUEST_SENSE:
+    case CMD_ATAPI_TEST_UNIT_READY:
     case CMD_ATAPI_START_STOP_UNIT:
         g_assert_cmpuint(lba, ==, 0x00);
         break;
@@ -1003,6 +1048,11 @@ static void ahci_atapi_set_size(AHCICommand *cmd, uint64_t xbytes)
         cbd[7] = (tmp & 0xFF00) >> 8;
         cbd[8] = (tmp & 0xFF);
         break;
+    case CMD_ATAPI_REQUEST_SENSE:
+        g_assert_cmpuint(xbytes, <=, UINT8_MAX);
+        cbd[4] = (uint8_t)xbytes;
+        break;
+    case CMD_ATAPI_TEST_UNIT_READY:
     case CMD_ATAPI_START_STOP_UNIT:
         g_assert_cmpuint(xbytes, ==, 0);
         break;
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index 05ce3de..ca83afc 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -287,11 +287,24 @@ enum {
 
 /* ATAPI Commands */
 enum {
+    CMD_ATAPI_TEST_UNIT_READY = 0x00,
+    CMD_ATAPI_REQUEST_SENSE   = 0x03,
     CMD_ATAPI_START_STOP_UNIT = 0x1b,
     CMD_ATAPI_READ_10         = 0x28,
     CMD_ATAPI_READ_CD         = 0xbe,
 };
 
+enum {
+    SENSE_NO_SENSE       = 0x00,
+    SENSE_NOT_READY      = 0x02,
+    SENSE_UNIT_ATTENTION = 0x06,
+};
+
+enum {
+    ASC_MEDIUM_MAY_HAVE_CHANGED = 0x28,
+    ASC_MEDIUM_NOT_PRESENT      = 0x3a,
+};
+
 /* AHCI Command Header Flags & Masks*/
 #define CMDH_CFL        (0x1F)
 #define CMDH_ATAPI      (0x20)
@@ -601,6 +614,9 @@ void ahci_io(AHCIQState *ahci, uint8_t port, uint8_t ide_cmd,
              void *buffer, size_t bufsize, uint64_t sector);
 void ahci_exec(AHCIQState *ahci, uint8_t port,
                uint8_t op, const AHCIOpts *opts);
+void ahci_atapi_test_ready(AHCIQState *ahci, uint8_t port, bool ready, uint8_t expected_sense);
+void ahci_atapi_get_sense(AHCIQState *ahci, uint8_t port,
+                          uint8_t *sense, uint8_t *asc);
 void ahci_atapi_eject(AHCIQState *ahci, uint8_t port);
 void ahci_atapi_load(AHCIQState *ahci, uint8_t port);
 
-- 
2.7.4

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

* [Qemu-devel] [PATCH v2 6/6] ahci-test: add QMP tray test for ATAPI
  2016-11-07 21:13 [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
                   ` (4 preceding siblings ...)
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 5/6] libqos/ahci: Add get_sense and test_ready John Snow
@ 2016-11-07 21:13 ` John Snow
  2016-11-10 16:34 ` [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
  2016-11-11 14:01 ` Kevin Wolf
  7 siblings, 0 replies; 12+ messages in thread
From: John Snow @ 2016-11-07 21:13 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pbonzini, pkrempa, qemu-devel, mreitz, John Snow

Test QMP events for a CDROM device with or without a media inserted,
including both guest-initiated and hw-initiated eject/load requests.

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

diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 0b1b6f7..ef17629 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -1554,6 +1554,103 @@ static void test_atapi_bcl(void)
     ahci_test_cdrom(0, false, CMD_ATAPI_READ_CD, true, 0);
 }
 
+
+static void atapi_wait_tray(bool open)
+{
+    QDict *rsp = qmp_eventwait_ref("DEVICE_TRAY_MOVED");
+    QDict *data = qdict_get_qdict(rsp, "data");
+    if (open) {
+        g_assert(qdict_get_bool(data, "tray-open"));
+    } else {
+        g_assert(!qdict_get_bool(data, "tray-open"));
+    }
+    QDECREF(rsp);
+}
+
+static void test_atapi_tray(void)
+{
+    AHCIQState *ahci;
+    unsigned char *tx;
+    char *iso;
+    int fd;
+    uint8_t port, sense, asc;
+    uint64_t iso_size = ATAPI_SECTOR_SIZE;
+    QDict *rsp;
+
+    fd = prepare_iso(iso_size, &tx, &iso);
+    ahci = ahci_boot_and_enable("-drive if=none,id=drive0,file=%s,format=raw "
+                                "-M q35 "
+                                "-device ide-cd,drive=drive0 ", iso);
+    port = ahci_port_select(ahci);
+
+    ahci_atapi_eject(ahci, port);
+    atapi_wait_tray(true);
+
+    ahci_atapi_load(ahci, port);
+    atapi_wait_tray(false);
+
+    /* Remove media */
+    qmp_async("{'execute': 'blockdev-open-tray', "
+               "'arguments': {'device': 'drive0'}}");
+    atapi_wait_tray(true);
+    rsp = qmp_receive();
+    QDECREF(rsp);
+
+    qmp_discard_response("{'execute': 'x-blockdev-remove-medium', "
+                         "'arguments': {'device': 'drive0'}}");
+
+    /* Test the tray without a medium */
+    ahci_atapi_load(ahci, port);
+    atapi_wait_tray(false);
+
+    ahci_atapi_eject(ahci, port);
+    atapi_wait_tray(true);
+
+    /* Re-insert media */
+    qmp_discard_response("{'execute': 'blockdev-add', "
+                          "'arguments': {'node-name': 'node0', "
+                                        "'driver': 'raw', "
+                                        "'file': { 'driver': 'file', "
+                                                  "'filename': %s }}}", iso);
+    qmp_discard_response("{'execute': 'x-blockdev-insert-medium',"
+                          "'arguments': { 'device': 'drive0', "
+                                         "'node-name': 'node0' }}");
+
+    /* Again, the event shows up first */
+    qmp_async("{'execute': 'blockdev-close-tray', "
+               "'arguments': {'device': 'drive0'}}");
+    atapi_wait_tray(false);
+    rsp = qmp_receive();
+    QDECREF(rsp);
+
+    /* Now, to convince ATAPI we understand the media has changed... */
+    ahci_atapi_test_ready(ahci, port, false, SENSE_NOT_READY);
+    ahci_atapi_get_sense(ahci, port, &sense, &asc);
+    g_assert_cmpuint(sense, ==, SENSE_NOT_READY);
+    g_assert_cmpuint(asc, ==, ASC_MEDIUM_NOT_PRESENT);
+
+    ahci_atapi_test_ready(ahci, port, false, SENSE_UNIT_ATTENTION);
+    ahci_atapi_get_sense(ahci, port, &sense, &asc);
+    g_assert_cmpuint(sense, ==, SENSE_UNIT_ATTENTION);
+    g_assert_cmpuint(asc, ==, ASC_MEDIUM_MAY_HAVE_CHANGED);
+
+    ahci_atapi_test_ready(ahci, port, true, SENSE_NO_SENSE);
+    ahci_atapi_get_sense(ahci, port, &sense, &asc);
+    g_assert_cmpuint(sense, ==, SENSE_NO_SENSE);
+
+    /* Final tray test. */
+    ahci_atapi_eject(ahci, port);
+    atapi_wait_tray(true);
+
+    ahci_atapi_load(ahci, port);
+    atapi_wait_tray(false);
+
+    /* Cleanup */
+    g_free(tx);
+    ahci_shutdown(ahci);
+    remove_iso(fd, iso);
+}
+
 /******************************************************************************/
 /* AHCI I/O Test Matrix Definitions                                           */
 
@@ -1844,6 +1941,7 @@ int main(int argc, char **argv)
     qtest_add_func("/ahci/cdrom/pio/multi", test_cdrom_pio_multi);
 
     qtest_add_func("/ahci/cdrom/pio/bcl", test_atapi_bcl);
+    qtest_add_func("/ahci/cdrom/eject", test_atapi_tray);
 
     ret = g_test_run();
 
-- 
2.7.4

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

* Re: [Qemu-devel] [PATCH v2 1/6] block-backend: Always notify on blk_eject
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 1/6] " John Snow
@ 2016-11-07 22:01   ` Eric Blake
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Blake @ 2016-11-07 22:01 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, qemu-devel, mreitz, pbonzini

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

On 11/07/2016 03:13 PM, John Snow wrote:
> blk_eject is only used by scsi-disk and atapi, and in both cases we
> only attempt to invoke blk_eject if we have a bona-fide change in
> tray state.
> 
> The "issue" here is that the tray state does not generate a QMP event
> unless there is a medium/BDS attached to the device, so if libvirt et al
> are waiting for a tray event to occur from an empty-but-closed drive,
> software opening that drive will not emit an event and libvirt will
> wait forever.
> 
> Change this by modifying blk_eject to always emit an event, instead of
> conditionally on a "real" backend eject.
> 
> Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1373264
> 
> Reported-by: Peter Krempa <pkrempa@redhat.com>
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  block/block-backend.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 2/6] libqtest: add qmp_eventwait_ref
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 2/6] libqtest: add qmp_eventwait_ref John Snow
@ 2016-11-07 22:25   ` Eric Blake
  0 siblings, 0 replies; 12+ messages in thread
From: Eric Blake @ 2016-11-07 22:25 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: kwolf, pkrempa, qemu-devel, mreitz, pbonzini

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

On 11/07/2016 03:13 PM, John Snow wrote:
> Wait for an event, but return a copy so we can investigate parameters.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  tests/libqtest.c | 13 ++++++++++---
>  tests/libqtest.h | 22 ++++++++++++++++++++++
>  2 files changed, 32 insertions(+), 3 deletions(-)

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

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

* Re: [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject
  2016-11-07 21:13 [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
                   ` (5 preceding siblings ...)
  2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 6/6] ahci-test: add QMP tray test for ATAPI John Snow
@ 2016-11-10 16:34 ` John Snow
  2016-11-11 14:01 ` Kevin Wolf
  7 siblings, 0 replies; 12+ messages in thread
From: John Snow @ 2016-11-10 16:34 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, pkrempa, qemu-devel, mreitz, pbonzini

Ping,

Kevin: Look ok?

--js

On 11/07/2016 04:13 PM, John Snow wrote:
> Requires patches in my IDE branch, for context.
>
> This series changes blk_eject (used for a software-initiated eject request)
> to always trigger a QMP tray event, in contrast to the current behavior where
> a tray event only occurs if a medium is already in the tray.
>
> V2: Now with tests. (Kevin)
>
> ________________________________________________________________________________
>
> For convenience, this branch is available at:
> https://github.com/jnsnow/qemu.git branch tray-always-notify
> https://github.com/jnsnow/qemu/tree/tray-always-notify
>
> This version is tagged tray-always-notify-v2:
> https://github.com/jnsnow/qemu/releases/tag/tray-always-notify-v2
>
> John Snow (6):
>   block-backend: Always notify on blk_eject
>   libqtest: add qmp_eventwait_ref
>   libqos/ahci: Support expected errors
>   libqos/ahci: Add ATAPI tray macros
>   libqos/ahci: Add get_sense and test_ready
>   ahci-test: add QMP tray test for ATAPI
>
>  block/block-backend.c | 13 +++----
>  tests/ahci-test.c     | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  tests/libqos/ahci.c   | 96 ++++++++++++++++++++++++++++++++++++++++++++++---
>  tests/libqos/ahci.h   | 26 ++++++++++++--
>  tests/libqtest.c      | 13 +++++--
>  tests/libqtest.h      | 22 ++++++++++++
>  6 files changed, 252 insertions(+), 16 deletions(-)
>

-- 
—js

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

* Re: [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject
  2016-11-07 21:13 [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
                   ` (6 preceding siblings ...)
  2016-11-10 16:34 ` [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
@ 2016-11-11 14:01 ` Kevin Wolf
  2016-11-11 15:12   ` John Snow
  7 siblings, 1 reply; 12+ messages in thread
From: Kevin Wolf @ 2016-11-11 14:01 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, pbonzini, pkrempa, qemu-devel, mreitz

Am 07.11.2016 um 22:13 hat John Snow geschrieben:
> Requires patches in my IDE branch, for context.
> 
> This series changes blk_eject (used for a software-initiated eject request)
> to always trigger a QMP tray event, in contrast to the current behavior where
> a tray event only occurs if a medium is already in the tray.
> 
> V2: Now with tests. (Kevin)

Reviewed-by: Kevin Wolf <kwolf@redhat.com>

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

* Re: [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject
  2016-11-11 14:01 ` Kevin Wolf
@ 2016-11-11 15:12   ` John Snow
  0 siblings, 0 replies; 12+ messages in thread
From: John Snow @ 2016-11-11 15:12 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: pbonzini, pkrempa, qemu-devel, qemu-block, mreitz



On 11/11/2016 09:01 AM, Kevin Wolf wrote:
> Am 07.11.2016 um 22:13 hat John Snow geschrieben:
>> Requires patches in my IDE branch, for context.
>>
>> This series changes blk_eject (used for a software-initiated eject request)
>> to always trigger a QMP tray event, in contrast to the current behavior where
>> a tray event only occurs if a medium is already in the tray.
>>
>> V2: Now with tests. (Kevin)
>
> Reviewed-by: Kevin Wolf <kwolf@redhat.com>
>

Thanks!

Thanks, applied to my IDE tree:

https://github.com/jnsnow/qemu/commits/ide
https://github.com/jnsnow/qemu.git

--js

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

end of thread, other threads:[~2016-11-11 15:12 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-07 21:13 [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 1/6] " John Snow
2016-11-07 22:01   ` Eric Blake
2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 2/6] libqtest: add qmp_eventwait_ref John Snow
2016-11-07 22:25   ` Eric Blake
2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 3/6] libqos/ahci: Support expected errors John Snow
2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 4/6] libqos/ahci: Add ATAPI tray macros John Snow
2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 5/6] libqos/ahci: Add get_sense and test_ready John Snow
2016-11-07 21:13 ` [Qemu-devel] [PATCH v2 6/6] ahci-test: add QMP tray test for ATAPI John Snow
2016-11-10 16:34 ` [Qemu-devel] [PATCH v2 0/6] block-backend: Always notify on blk_eject John Snow
2016-11-11 14:01 ` Kevin Wolf
2016-11-11 15:12   ` John Snow

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).