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