From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48313) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1tXe-0002ih-3W for qemu-devel@nongnu.org; Tue, 01 Jul 2014 04:36:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X1tXU-0000wY-UW for qemu-devel@nongnu.org; Tue, 01 Jul 2014 04:35:54 -0400 Received: from mail-wi0-x22b.google.com ([2a00:1450:400c:c05::22b]:33097) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1tXU-0000wM-NS for qemu-devel@nongnu.org; Tue, 01 Jul 2014 04:35:44 -0400 Received: by mail-wi0-f171.google.com with SMTP id n15so7359751wiw.4 for ; Tue, 01 Jul 2014 01:35:43 -0700 (PDT) Received: from playground.station (net-37-116-207-238.cust.vodafonedsl.it. [37.116.207.238]) by mx.google.com with ESMTPSA id dj2sm40758365wib.11.2014.07.01.01.35.42 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 01 Jul 2014 01:35:43 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Tue, 1 Jul 2014 10:35:05 +0200 Message-Id: <1404203705-15674-16-git-send-email-pbonzini@redhat.com> In-Reply-To: <1404203705-15674-1-git-send-email-pbonzini@redhat.com> References: <1404203705-15674-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PULL 15/15] qdev: correctly send DEVICE_DELETED for recursively-deleted devices List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org When a device is unparented (i.e. made completely hidden from management) we want to send a DEVICE_DELETED event only if the device actually was realized. This avoids raising DEVICE_DELETED events when device_add fails. However, this does not work right for recursively-deleted devices: the whole tree is _first_ unrealized, _then_ unparented. Then device_unparent sees realized==false and fails to trigger the event. The solution is simply to move have_realized into the DeviceState struct. If device_add fails, we never set the new field to true and DEVICE_DELETED is not sent. Fixes qemu-iotests testcase 067 (broken by commit 5942a19, though that commit in turn fixed a possible segfault in the same test). Reported-by: Markus Armbruster Reviewed-by: Markus Armbruster Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 5 +++-- include/hw/qdev-core.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index d1eba3c..c520415 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -848,6 +848,7 @@ static void device_set_realized(Object *obj, bool value, Error **errp) if (dev->hotplugged && local_err == NULL) { device_reset(dev); } + dev->pending_deleted_event = false; } else if (!value && dev->realized) { QLIST_FOREACH(bus, &dev->child_bus, sibling) { object_property_set_bool(OBJECT(bus), false, "realized", @@ -862,6 +863,7 @@ static void device_set_realized(Object *obj, bool value, Error **errp) if (dc->unrealize && local_err == NULL) { dc->unrealize(dev, &local_err); } + dev->pending_deleted_event = true; } if (local_err != NULL) { @@ -972,7 +974,6 @@ static void device_unparent(Object *obj) { DeviceState *dev = DEVICE(obj); BusState *bus; - bool have_realized = dev->realized; if (dev->realized) { object_property_set_bool(obj, false, "realized", NULL); @@ -988,7 +989,7 @@ static void device_unparent(Object *obj) } /* Only send event if the device had been completely realized */ - if (have_realized) { + if (dev->pending_deleted_event) { gchar *path = object_get_canonical_path(OBJECT(dev)); qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 9221cfc..0799ff2 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -156,6 +156,7 @@ struct DeviceState { const char *id; bool realized; + bool pending_deleted_event; QemuOpts *opts; int hotplugged; BusState *parent_bus; -- 1.8.3.1