From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46441) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XWlA9-00068j-0b for qemu-devel@nongnu.org; Wed, 24 Sep 2014 07:55:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XWlA1-0007n1-H4 for qemu-devel@nongnu.org; Wed, 24 Sep 2014 07:55:12 -0400 Received: from mx1.redhat.com ([209.132.183.28]:14668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XWlA1-0007dr-A5 for qemu-devel@nongnu.org; Wed, 24 Sep 2014 07:55:05 -0400 From: Igor Mammedov Date: Wed, 24 Sep 2014 11:47:54 +0000 Message-Id: <1411559299-19042-6-git-send-email-imammedo@redhat.com> In-Reply-To: <1411559299-19042-1-git-send-email-imammedo@redhat.com> References: <1411559299-19042-1-git-send-email-imammedo@redhat.com> Subject: [Qemu-devel] [PATCH 05/30] test: virtio-blk: check if hot-plug/unplug works List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: dmitry@daynix.com, borntraeger@de.ibm.com, mst@redhat.com, agraf@suse.de, cornelia.huck@de.ibm.com, kraxel@redhat.com, amit.shah@redhat.com, pbonzini@redhat.com, rth@twiddle.net since virtio-blk-pci is a PCI device, its unplug is async and handled by ACPI. So simultate device's ACPI _EJ0 method to trigger actual device removal. Signed-off-by: Igor Mammedov --- tests/virtio-blk-test.c | 75 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index 588666c..b42c10b 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -45,6 +45,10 @@ #define PCI_SLOT 0x04 #define PCI_FN 0x00 +#define PCI_SLOT_HP 0x06 +#define ACPI_PCIHP_ADDR 0xae00 +#define PCI_EJ_BASE 0x0008 + typedef struct QVirtioBlkReq { uint32_t type; uint32_t ioprio; @@ -55,7 +59,7 @@ typedef struct QVirtioBlkReq { static QPCIBus *test_start(void) { - char cmdline[100]; + char *cmdline; char tmp_path[] = "/tmp/qtest.XXXXXX"; int fd, ret; @@ -66,11 +70,14 @@ static QPCIBus *test_start(void) g_assert_cmpint(ret, ==, 0); close(fd); - snprintf(cmdline, 100, "-drive if=none,id=drive0,file=%s " - "-device virtio-blk-pci,drive=drive0,addr=%x.%x", - tmp_path, PCI_SLOT, PCI_FN); + cmdline = g_strdup_printf("-drive if=none,id=drive0,file=%s " + "-drive if=none,id=drive1,file=/dev/null " + "-device virtio-blk-pci,id=drv0,drive=drive0," + "addr=%x.%x", + tmp_path, PCI_SLOT, PCI_FN); qtest_start(cmdline); unlink(tmp_path); + g_free(cmdline); return qpci_init_pc(); } @@ -80,14 +87,14 @@ static void test_end(void) qtest_end(); } -static QVirtioPCIDevice *virtio_blk_init(QPCIBus *bus) +static QVirtioPCIDevice *virtio_blk_init(QPCIBus *bus, int slot) { QVirtioPCIDevice *dev; dev = qvirtio_pci_device_find(bus, QVIRTIO_BLK_DEVICE_ID); g_assert(dev != NULL); g_assert_cmphex(dev->vdev.device_type, ==, QVIRTIO_BLK_DEVICE_ID); - g_assert_cmphex(dev->pdev->devfn, ==, ((PCI_SLOT << 3) | PCI_FN)); + g_assert_cmphex(dev->pdev->devfn, ==, ((slot << 3) | PCI_FN)); qvirtio_pci_device_enable(dev); qvirtio_reset(&qvirtio_pci, &dev->vdev); @@ -147,7 +154,7 @@ static void pci_basic(void) bus = test_start(); - dev = virtio_blk_init(bus); + dev = virtio_blk_init(bus, PCI_SLOT); /* MSI-X is not enabled */ addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX; @@ -293,7 +300,7 @@ static void pci_indirect(void) bus = test_start(); - dev = virtio_blk_init(bus); + dev = virtio_blk_init(bus, PCI_SLOT); /* MSI-X is not enabled */ addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX; @@ -384,7 +391,7 @@ static void pci_config(void) bus = test_start(); - dev = virtio_blk_init(bus); + dev = virtio_blk_init(bus, PCI_SLOT); /* MSI-X is not enabled */ addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX; @@ -426,7 +433,7 @@ static void pci_msix(void) bus = test_start(); alloc = pc_alloc_init(); - dev = virtio_blk_init(bus); + dev = virtio_blk_init(bus, PCI_SLOT); qpci_msix_enable(dev->pdev); qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0); @@ -536,7 +543,7 @@ static void pci_idx(void) bus = test_start(); alloc = pc_alloc_init(); - dev = virtio_blk_init(bus); + dev = virtio_blk_init(bus, PCI_SLOT); qpci_msix_enable(dev->pdev); qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0); @@ -640,6 +647,51 @@ static void pci_idx(void) test_end(); } +static void hotplug(void) +{ + QDict *response; + QPCIBus *bus; + QVirtioPCIDevice *dev; + bus = test_start(); + + /* plug secondary disk */ + response = qmp("{\"execute\": \"device_add\"," + " \"arguments\": {" + " \"driver\": \"virtio-blk-pci\"," + " \"drive\": \"drive1\"," + " \"addr\": \"" stringify(PCI_SLOT_HP) "\"," + " \"id\": \"drv1\"" + "}}"); + + g_assert(response); + g_assert(!qdict_haskey(response, "error")); + QDECREF(response); + + dev = virtio_blk_init(bus, PCI_SLOT_HP); + g_assert(dev); + qvirtio_pci_device_disable(dev); + g_free(dev); + + /* unplug secondary disk */ + response = qmp("{\"execute\": \"device_del\"," + " \"arguments\": {" + " \"id\": \"drv1\"" + "}}"); + + g_assert(response); + g_assert(!qdict_haskey(response, "error")); + QDECREF(response); + + outb(ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << PCI_SLOT_HP); + + /* check DEVICE_DELETED event */ + response = qmp(""); + g_assert(qdict_haskey(response, "event")); + g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED")); + + test_end(); +} + int main(int argc, char **argv) { int ret; @@ -651,6 +703,7 @@ int main(int argc, char **argv) g_test_add_func("/virtio/blk/pci/config", pci_config); g_test_add_func("/virtio/blk/pci/msix", pci_msix); g_test_add_func("/virtio/blk/pci/idx", pci_idx); + g_test_add_func("/virtio/blk/pci/hotplug", hotplug); ret = g_test_run(); -- 1.8.3.1