yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
0a122b
From e1cfab2e4723088d7fb011c1deda763c03682f81 Mon Sep 17 00:00:00 2001
0a122b
Message-Id: <e1cfab2e4723088d7fb011c1deda763c03682f81.1387288155.git.minovotn@redhat.com>
0a122b
In-Reply-To: <527da6c2ce2c09d0183aa8595fc95f136f61b6df.1387288155.git.minovotn@redhat.com>
0a122b
References: <527da6c2ce2c09d0183aa8595fc95f136f61b6df.1387288155.git.minovotn@redhat.com>
0a122b
From: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
Date: Thu, 12 Dec 2013 16:21:27 +0100
0a122b
Subject: [PATCH 7/8] qdev-monitor-test: add device_add leak test cases
0a122b
0a122b
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
Message-id: <1386865288-1575-8-git-send-email-stefanha@redhat.com>
0a122b
Patchwork-id: 56261
0a122b
O-Subject: [RHEL7 qemu-kvm PATCH 7/8] qdev-monitor-test: add device_add leak test cases
0a122b
Bugzilla: 1003773
0a122b
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
0a122b
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
0a122b
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
0a122b
0a122b
Ensure that the device_add error code path deletes device objects.
0a122b
Failure to do so not only leaks the objects but can also keep other
0a122b
objects (like drive or netdev) alive due to qdev properties holding
0a122b
references.
0a122b
0a122b
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
Reviewed-by: Eric Blake <eblake@redhat.com>
0a122b
(cherry picked from commit 43cd209803d6cffb1e1a028c9ff2fd0ff4fce954)
0a122b
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
0a122b
Conflicts:
0a122b
	tests/Makefile
0a122b
0a122b
Makefile diff context conflict.
0a122b
---
0a122b
 tests/Makefile            |  2 ++
0a122b
 tests/qdev-monitor-test.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++
0a122b
 2 files changed, 83 insertions(+)
0a122b
 create mode 100644 tests/qdev-monitor-test.c
0a122b
0a122b
Signed-off-by: Michal Novotny <minovotn@redhat.com>
0a122b
---
0a122b
 tests/Makefile            |  2 ++
0a122b
 tests/qdev-monitor-test.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++
0a122b
 2 files changed, 83 insertions(+)
0a122b
 create mode 100644 tests/qdev-monitor-test.c
0a122b
0a122b
diff --git a/tests/Makefile b/tests/Makefile
0a122b
index 91231e8..2e9093e 100644
0a122b
--- a/tests/Makefile
0a122b
+++ b/tests/Makefile
0a122b
@@ -59,6 +59,7 @@ check-qtest-i386-y += tests/rtc-test$(EXESUF)
0a122b
 check-qtest-i386-y += tests/i440fx-test$(EXESUF)
0a122b
 check-qtest-i386-y += tests/fw_cfg-test$(EXESUF)
0a122b
 check-qtest-i386-y += tests/blockdev-test$(EXESUF)
0a122b
+check-qtest-i386-y += tests/qdev-monitor-test$(EXESUF)
0a122b
 check-qtest-x86_64-y = $(check-qtest-i386-y)
0a122b
 gcov-files-i386-y += i386-softmmu/hw/mc146818rtc.c
0a122b
 gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
0a122b
@@ -137,6 +138,7 @@ tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
0a122b
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
0a122b
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
0a122b
 tests/blockdev-test$(EXESUF): tests/blockdev-test.o $(libqos-pc-obj-y)
0a122b
+tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y)
0a122b
 
0a122b
 # QTest rules
0a122b
 
0a122b
diff --git a/tests/qdev-monitor-test.c b/tests/qdev-monitor-test.c
0a122b
new file mode 100644
0a122b
index 0000000..33a8ea4
0a122b
--- /dev/null
0a122b
+++ b/tests/qdev-monitor-test.c
0a122b
@@ -0,0 +1,81 @@
0a122b
+/*
0a122b
+ * qdev-monitor.c test cases
0a122b
+ *
0a122b
+ * Copyright (C) 2013 Red Hat Inc.
0a122b
+ *
0a122b
+ * Authors:
0a122b
+ *  Stefan Hajnoczi <stefanha@redhat.com>
0a122b
+ *
0a122b
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
0a122b
+ * See the COPYING.LIB file in the top-level directory.
0a122b
+ */
0a122b
+
0a122b
+#include <string.h>
0a122b
+#include <glib.h>
0a122b
+#include "libqtest.h"
0a122b
+#include "qapi/qmp/qjson.h"
0a122b
+
0a122b
+static void test_device_add(void)
0a122b
+{
0a122b
+    QDict *response;
0a122b
+    QDict *error;
0a122b
+
0a122b
+    qtest_start("-drive if=none,id=drive0");
0a122b
+
0a122b
+    /* Make device_add fail.  If this leaks the virtio-blk-pci device then a
0a122b
+     * reference to drive0 will also be held (via qdev properties).
0a122b
+     */
0a122b
+    response = qmp("{\"execute\": \"device_add\","
0a122b
+                   " \"arguments\": {"
0a122b
+                   "   \"driver\": \"virtio-blk-pci\","
0a122b
+                   "   \"drive\": \"drive0\""
0a122b
+                   "}}");
0a122b
+    g_assert(response);
0a122b
+    error = qdict_get_qdict(response, "error");
0a122b
+    g_assert(!strcmp(qdict_get_try_str(error, "class") ?: "",
0a122b
+                     "GenericError"));
0a122b
+    g_assert(!strcmp(qdict_get_try_str(error, "desc") ?: "",
0a122b
+                     "Device initialization failed."));
0a122b
+    QDECREF(response);
0a122b
+
0a122b
+    /* Delete the drive */
0a122b
+    response = qmp("{\"execute\": \"human-monitor-command\","
0a122b
+                   " \"arguments\": {"
0a122b
+                   "   \"command-line\": \"drive_del drive0\""
0a122b
+                   "}}");
0a122b
+    g_assert(response);
0a122b
+    g_assert(!strcmp(qdict_get_try_str(response, "return") ?: "(null)", ""));
0a122b
+    QDECREF(response);
0a122b
+
0a122b
+    /* Try to re-add the drive.  This fails with duplicate IDs if a leaked
0a122b
+     * virtio-blk-pci exists that holds a reference to the old drive0.
0a122b
+     */
0a122b
+    response = qmp("{\"execute\": \"human-monitor-command\","
0a122b
+                   " \"arguments\": {"
0a122b
+                   "   \"command-line\": \"drive_add pci-addr=auto if=none,id=drive0\""
0a122b
+                   "}}");
0a122b
+    g_assert(response);
0a122b
+    g_assert(!strcmp(qdict_get_try_str(response, "return") ?: "",
0a122b
+                     "OK\r\n"));
0a122b
+    QDECREF(response);
0a122b
+
0a122b
+    qtest_end();
0a122b
+}
0a122b
+
0a122b
+int main(int argc, char **argv)
0a122b
+{
0a122b
+    const char *arch = qtest_get_arch();
0a122b
+
0a122b
+    /* Check architecture */
0a122b
+    if (strcmp(arch, "i386") && strcmp(arch, "x86_64")) {
0a122b
+        g_test_message("Skipping test for non-x86\n");
0a122b
+        return 0;
0a122b
+    }
0a122b
+
0a122b
+    /* Run the tests */
0a122b
+    g_test_init(&argc, &argv, NULL);
0a122b
+
0a122b
+    qtest_add_func("/qmp/device_add", test_device_add);
0a122b
+
0a122b
+    return g_test_run();
0a122b
+}
0a122b
-- 
0a122b
1.7.11.7
0a122b