From patchwork Fri Nov 8 10:12:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 289793 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 5145D2C00A6 for ; Fri, 8 Nov 2013 22:23:13 +1100 (EST) Received: from localhost ([::1]:44687 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VejF6-0002Zd-9u for incoming@patchwork.ozlabs.org; Fri, 08 Nov 2013 05:24:44 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38461) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vej50-0005oO-4G for qemu-devel@nongnu.org; Fri, 08 Nov 2013 05:14:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Vej4u-0005x7-56 for qemu-devel@nongnu.org; Fri, 08 Nov 2013 05:14:18 -0500 Received: from mx1.redhat.com ([209.132.183.28]:19315) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vej4t-0005wy-Tl for qemu-devel@nongnu.org; Fri, 08 Nov 2013 05:14:12 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id rA8AD9N3024808 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 8 Nov 2013 05:13:09 -0500 Received: from localhost (ovpn-112-38.ams2.redhat.com [10.36.112.38]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rA8AD7l5019639; Fri, 8 Nov 2013 05:13:08 -0500 From: Stefan Hajnoczi To: Date: Fri, 8 Nov 2013 11:12:09 +0100 Message-Id: <1383905551-16411-16-git-send-email-stefanha@redhat.com> In-Reply-To: <1383905551-16411-1-git-send-email-stefanha@redhat.com> References: <1383905551-16411-1-git-send-email-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Stefan Hajnoczi , Anthony Liguori Subject: [Qemu-devel] [PULL v2 15/37] qdev-monitor-test: add device_add leak test cases X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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 973f497..379cdd9 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -69,6 +69,7 @@ check-qtest-i386-y += tests/i440fx-test$(EXESUF) check-qtest-i386-y += tests/fw_cfg-test$(EXESUF) check-qtest-i386-y += tests/qom-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)) @@ -202,6 +203,7 @@ 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/qom-test$(EXESUF): tests/qom-test.o 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) tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o # 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(); +}