From nobody Sun May 5 05:05:33 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1567166952; cv=none; d=zoho.com; s=zohoarc; b=bcytvCnfIYkv7V3on/LuO1erbt83nXyIl3Dh+Bfr/f16fKVfIBisVWe85xDBR+Tf2lW8aP4zDjQpkBu7C3PaY3DLupXvAUcMRz8sAO86pREUUqZADv6bJ1rHHxy/9xTGM0uNQBH8sL4H3oATuu8fLrxg7kcS62cKWJL0gF2BDvs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567166952; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=ayYW5hbNe6hTni6+KNchalVS46l4THYxz8MhaCxGxtI=; b=ZJxR1AsGtgdrtT0PZhLx1qRNvm5jGwEYGrahthFMthpqKM5cLrf6rEbrL5UaBUiyx+ScEJNYILpJBKymsFs8wxho1oIy5zW7vjuiZFHcOrPlB7EqkYSABl6FKWMb+/IMHUubUMrTW/L5xy7k/kyucb/5N8PT1n0Pp1+JkJFqwYk= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 156716695213432.40903643892932; Fri, 30 Aug 2019 05:09:12 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E05FB308AA11; Fri, 30 Aug 2019 12:09:10 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8B47A19C77; Fri, 30 Aug 2019 12:09:10 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id C9ECF1806B01; Fri, 30 Aug 2019 12:09:09 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x7UC984q018313 for ; Fri, 30 Aug 2019 08:09:08 -0400 Received: by smtp.corp.redhat.com (Postfix) id AC2675EE1D; Fri, 30 Aug 2019 12:09:08 +0000 (UTC) Received: from mx1.redhat.com (ext-mx03.extmail.prod.ext.phx2.redhat.com [10.5.110.27]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A6E9B5D721 for ; Fri, 30 Aug 2019 12:09:06 +0000 (UTC) Received: from relay.sw.ru (relay.sw.ru [185.231.240.75]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 32C8981129 for ; Fri, 30 Aug 2019 12:09:04 +0000 (UTC) Received: from [172.16.24.106] (helo=shiny.sw.ru) by relay.sw.ru with esmtp (Exim 4.92) (envelope-from ) id 1i3fiA-0000GK-0s for libvir-list@redhat.com; Fri, 30 Aug 2019 15:09:02 +0300 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Fri, 30 Aug 2019 15:08:29 +0300 Message-Id: <20190830120834.27404-2-nshirokovskiy@virtuozzo.com> In-Reply-To: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> References: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> MIME-Version: 1.0 X-Greylist: Sender passed SPF test, ACL 264 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 30 Aug 2019 12:09:05 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 30 Aug 2019 12:09:05 +0000 (UTC) for IP:'185.231.240.75' DOMAIN:'relay.sw.ru' HELO:'relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: 0 (SPF_HELO_NONE, SPF_PASS) 185.231.240.75 relay.sw.ru 185.231.240.75 relay.sw.ru X-Scanned-By: MIMEDefang 2.78 on 10.5.110.27 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 1/6] qemu: track hostdev delete cause X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Fri, 30 Aug 2019 12:09:11 +0000 (UTC) Content-Type: text/plain; charset="utf-8" qemuDomainDetachDeviceLive is called when client asks for detaching a device. We are going to call this function when usb device is detached on node itself. The function itself requests qemu to detach device from guest but as device detaching is asynchronous libvirt config changes are done in DEVICE_DELETED event handler. As we want to keep device in libvirt config if device detached from node opposite to the case of client initiated detaching we need to track the delete cause. Signed-off-by: Nikolay Shirokovskiy --- src/conf/domain_conf.h | 9 +++++++++ src/qemu/qemu_driver.c | 4 ++-- src/qemu/qemu_hotplug.c | 21 ++++++++++++++++++++- src/qemu/qemu_hotplug.h | 3 ++- tests/qemuhotplugtest.c | 2 +- 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 33cef5b75c..49392d0286 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -326,6 +326,14 @@ struct _virDomainHostdevCaps { } u; }; =20 +typedef enum { + VIR_DOMAIN_HOSTDEV_DELETE_CAUSE_NONE =3D 0, + VIR_DOMAIN_HOSTDEV_DELETE_CAUSE_CLIENT, + VIR_DOMAIN_HOSTDEV_DELETE_CAUSE_REATTACHING, + + VIR_DOMAIN_HOSTDEV_DELETE_CAUSE_LAST +} virDomainHostdevDeleteCauseType; + =20 /* basic device for direct passthrough */ struct _virDomainHostdevDef { @@ -343,6 +351,7 @@ struct _virDomainHostdevDef { bool missing; bool readonly; bool shareable; + virDomainHostdevDeleteCauseType deleteCause; union { virDomainHostdevSubsys subsys; virDomainHostdevCaps caps; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 78f5471b79..2378a2e7d0 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9123,7 +9123,7 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriverPtr = driver, if (flags & VIR_DOMAIN_AFFECT_LIVE) { int rc; =20 - if ((rc =3D qemuDomainDetachDeviceLive(vm, dev_copy, driver, false= )) < 0) + if ((rc =3D qemuDomainDetachDeviceLive(vm, dev_copy, driver, false= , false)) < 0) goto cleanup; =20 if (rc =3D=3D 0 && qemuDomainUpdateDeviceList(driver, vm, QEMU_ASY= NC_JOB_NONE) < 0) @@ -9212,7 +9212,7 @@ qemuDomainDetachDeviceAliasLiveAndConfig(virQEMUDrive= rPtr driver, if (virDomainDefFindDevice(def, alias, &dev, true) < 0) goto cleanup; =20 - if ((rc =3D qemuDomainDetachDeviceLive(vm, &dev, driver, true)) < = 0) + if ((rc =3D qemuDomainDetachDeviceLive(vm, &dev, driver, true, fal= se)) < 0) goto cleanup; =20 if (rc =3D=3D 0 && qemuDomainUpdateDeviceList(driver, vm, QEMU_ASY= NC_JOB_NONE) < 0) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 63acb9c451..08e60dcd0e 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -5721,7 +5721,8 @@ int qemuDomainDetachDeviceLive(virDomainObjPtr vm, virDomainDeviceDefPtr match, virQEMUDriverPtr driver, - bool async) + bool async, + bool reattaching) { virDomainDeviceDef detach =3D { .type =3D match->type }; virDomainDeviceInfoPtr info =3D NULL; @@ -5880,6 +5881,24 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, goto cleanup; } =20 + if (detach.type =3D=3D VIR_DOMAIN_DEVICE_HOSTDEV) { + virDomainHostdevDefPtr hostdev =3D detach.data.hostdev; + + /* + * Why having additional check in second branch? Suppose client + * asks for device detaching and we pass the intention to qemu + * but don't get DEVICE_DELETED event yet. Next USB is detached + * on node and we have this function called again. If we reset + * delete cause to 'reattaching' then device will be left in + * libvirt config after handling DEVICE_DELETED event while + * it should not as client asked to detach the device before. + */ + if (!reattaching) + hostdev->deleteCause =3D VIR_DOMAIN_HOSTDEV_DELETE_CAUSE_CLIEN= T; + else if (hostdev->deleteCause !=3D VIR_DOMAIN_HOSTDEV_DELETE_CAUSE= _CLIENT) + hostdev->deleteCause =3D VIR_DOMAIN_HOSTDEV_DELETE_CAUSE_REATT= ACHING; + } + if (async) { ret =3D 0; } else { diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 896e6c7b98..bf812eab1a 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -116,7 +116,8 @@ int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver, int qemuDomainDetachDeviceLive(virDomainObjPtr vm, virDomainDeviceDefPtr match, virQEMUDriverPtr driver, - bool async); + bool async, + bool reattaching); =20 void qemuDomainRemoveVcpuAlias(virQEMUDriverPtr driver, virDomainObjPtr vm, diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index b6aad330a9..ef91d4f131 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -151,7 +151,7 @@ testQemuHotplugDetach(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_CHR: case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_WATCHDOG: - ret =3D qemuDomainDetachDeviceLive(vm, dev, &driver, async); + ret =3D qemuDomainDetachDeviceLive(vm, dev, &driver, async, false); break; default: VIR_TEST_VERBOSE("device type '%s' cannot be detached", --=20 2.23.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 05:05:33 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1567166952; cv=none; d=zoho.com; s=zohoarc; b=dr/8Nt+Bz5Z67I3TdjstyqXR4aR1NH76Y64O/bYtfgVFFNuL9xGvUUOCh5A/fbngiLEc9m2ZXmqnpb8CESpb0KdFDmoeBHhZRly/Cqielm/34b5kWmiwjNRujVM5cb/7Dy+pqt8Z5qu57HLSjqomUxc4yyQyhl+db6fCntYYxUw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567166952; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=LowsaZAK6kEs/C0Co4YN11vIoDk7ABzH3D2qsX1UhM0=; b=Km4DQX//KMHo9wjFjfolMxuDAkAu/Bem4QuKgHN1nCHyfWxpjUD3nUUrZ5mgi16kLbUUNfy2uYOQwi/WDxG0HImprKjP+w8vekmLpHVD7egd2GezL3ci08OBzLZDe6mGrDnOyH+hkc0GJd7dUvQx/pny0lFwpO0mFiD/9vvmu4c= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1567166952201669.868161867941; Fri, 30 Aug 2019 05:09:12 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D205C81129; Fri, 30 Aug 2019 12:09:10 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8EE1960C05; Fri, 30 Aug 2019 12:09:10 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id CB82C1806B09; Fri, 30 Aug 2019 12:09:09 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x7UC98Va018310 for ; Fri, 30 Aug 2019 08:09:08 -0400 Received: by smtp.corp.redhat.com (Postfix) id A21BB60A9D; Fri, 30 Aug 2019 12:09:08 +0000 (UTC) Received: from mx1.redhat.com (ext-mx24.extmail.prod.ext.phx2.redhat.com [10.5.110.65]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9C11760605 for ; Fri, 30 Aug 2019 12:09:06 +0000 (UTC) Received: from relay.sw.ru (relay.sw.ru [185.231.240.75]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6563510C6976 for ; Fri, 30 Aug 2019 12:09:04 +0000 (UTC) Received: from [172.16.24.106] (helo=shiny.sw.ru) by relay.sw.ru with esmtp (Exim 4.92) (envelope-from ) id 1i3fiA-0000GK-G3 for libvir-list@redhat.com; Fri, 30 Aug 2019 15:09:02 +0300 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Fri, 30 Aug 2019 15:08:30 +0300 Message-Id: <20190830120834.27404-3-nshirokovskiy@virtuozzo.com> In-Reply-To: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> References: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> MIME-Version: 1.0 X-Greylist: Sender passed SPF test, ACL 264 matched, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.65]); Fri, 30 Aug 2019 12:09:05 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.65]); Fri, 30 Aug 2019 12:09:05 +0000 (UTC) for IP:'185.231.240.75' DOMAIN:'relay.sw.ru' HELO:'relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: 0 (SPF_HELO_NONE, SPF_PASS) 185.231.240.75 relay.sw.ru 185.231.240.75 relay.sw.ru X-Scanned-By: MIMEDefang 2.84 on 10.5.110.65 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 2/6] qemu: handle usb hostdev add/del udev events X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 30 Aug 2019 12:09:11 +0000 (UTC) Content-Type: text/plain; charset="utf-8" In either case detach qemu hostdev device (it is dummy in case node hostdev is absent). Meaningful processing will be in DEVICE_DELETED event handler. Signed-off-by: Nikolay Shirokovskiy --- src/qemu/Makefile.inc.am | 2 + src/qemu/qemu_conf.h | 3 + src/qemu/qemu_domain.c | 2 + src/qemu/qemu_domain.h | 2 + src/qemu/qemu_driver.c | 344 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 352 insertions(+), 1 deletion(-) diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am index d16b315ebc..8be0dee396 100644 --- a/src/qemu/Makefile.inc.am +++ b/src/qemu/Makefile.inc.am @@ -85,6 +85,7 @@ libvirt_driver_qemu_impl_la_CFLAGS =3D \ -I$(srcdir)/conf \ -I$(srcdir)/secret \ $(AM_CFLAGS) \ + $(UDEV_CFLAGS) \ $(NULL) libvirt_driver_qemu_impl_la_LDFLAGS =3D $(AM_LDFLAGS) libvirt_driver_qemu_impl_la_LIBADD =3D \ @@ -93,6 +94,7 @@ libvirt_driver_qemu_impl_la_LIBADD =3D \ $(LIBNL_LIBS) \ $(SELINUX_LIBS) \ $(LIBXML_LIBS) \ + $(UDEV_LIBS) \ $(NULL) libvirt_driver_qemu_impl_la_SOURCES =3D $(QEMU_DRIVER_SOURCES) =20 diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 0cbddd7a9c..2e50bb0950 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -294,6 +294,9 @@ struct _virQEMUDriver { =20 /* Immutable pointer, self-locking APIs */ virHashAtomicPtr migrationErrors; + + struct udev_monitor *udev_monitor; + int udev_watch; }; =20 virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 657f3ecfe4..4784804d1e 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -15034,6 +15034,8 @@ qemuProcessEventFree(struct qemuProcessEvent *event) case QEMU_PROCESS_EVENT_SERIAL_CHANGED: case QEMU_PROCESS_EVENT_BLOCK_JOB: case QEMU_PROCESS_EVENT_MONITOR_EOF: + case QEMU_PROCESS_EVENT_USB_REMOVED: + case QEMU_PROCESS_EVENT_USB_ADDED: VIR_FREE(event->data); break; case QEMU_PROCESS_EVENT_JOB_STATUS_CHANGE: diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index d097f23342..94aea62693 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -521,6 +521,8 @@ typedef enum { QEMU_PROCESS_EVENT_MONITOR_EOF, QEMU_PROCESS_EVENT_PR_DISCONNECT, QEMU_PROCESS_EVENT_RDMA_GID_STATUS_CHANGED, + QEMU_PROCESS_EVENT_USB_REMOVED, + QEMU_PROCESS_EVENT_USB_ADDED, =20 QEMU_PROCESS_EVENT_LAST } qemuProcessEventType; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2378a2e7d0..33b75a3c71 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -34,6 +34,7 @@ #include #include #include +#include =20 =20 #include "qemu_driver.h" @@ -719,6 +720,254 @@ qemuDomainFindMaxID(virDomainObjPtr vm, } =20 =20 +struct qemuUdevUSBRemoveData { + unsigned int bus; + unsigned int device; +}; + +struct qemuUdevUSBAddData { + unsigned int vendor; + unsigned int product; +}; + +struct qemuUdevUSBEventData { + union { + struct qemuUdevUSBRemoveData remove; + struct qemuUdevUSBAddData add; + } data; + bool found; + bool remove; +}; + +static int +qemuUdevUSBHandleEvent(virDomainObjPtr vm, void *opaque) +{ + struct qemuUdevUSBEventData *data =3D opaque; + struct qemuProcessEvent *event =3D NULL; + size_t i; + + if (data->found) + return 0; + + virObjectLock(vm); + + if (!virDomainObjIsActive(vm)) + goto cleanup; + + for (i =3D 0; i < vm->def->nhostdevs; i++) { + virDomainHostdevDefPtr hostdev =3D vm->def->hostdevs[i]; + virDomainHostdevSubsysUSBPtr usbsrc =3D &hostdev->source.subsys.u.= usb; + + if (hostdev->source.subsys.type !=3D VIR_DOMAIN_HOSTDEV_SUBSYS_TYP= E_USB) + continue; + + if (data->remove) { + if (usbsrc->bus !=3D data->data.remove.bus || + usbsrc->device !=3D data->data.remove.device) + continue; + } else { + if (usbsrc->vendor !=3D data->data.add.vendor || + usbsrc->product !=3D data->data.add.product) + continue; + } + + data->found =3D true; + + if (VIR_ALLOC(event) < 0) + goto cleanup; + + if (data->remove) { + struct qemuUdevUSBRemoveData *rm_data; + + + if (VIR_ALLOC(rm_data) < 0) + goto cleanup; + + *rm_data =3D data->data.remove; + event->data =3D rm_data; + event->eventType =3D QEMU_PROCESS_EVENT_USB_REMOVED; + } else { + struct qemuUdevUSBAddData *add_data; + + if (VIR_ALLOC(add_data) < 0) + goto cleanup; + + *add_data =3D data->data.add; + event->data =3D add_data; + event->eventType =3D QEMU_PROCESS_EVENT_USB_ADDED; + } + + event->vm =3D virObjectRef(vm); + + if (virThreadPoolSendJob(qemu_driver->workerPool, 0, event) < 0) { + virObjectUnref(vm); + goto cleanup; + } + + event =3D NULL; + + break; + } + + cleanup: + virObjectUnlock(vm); + + qemuProcessEventFree(event); + + return 0; +} + + +static void +qemuUdevEventHandleCallback(int watch ATTRIBUTE_UNUSED, + int fd ATTRIBUTE_UNUSED, + int events ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + struct qemuUdevUSBEventData event_data; + struct udev_device *dev =3D NULL; + const char *action; + const char *devtype; + const char *tmp; + + /* libvirtd daemon do not run event loop before full state drivers + * initialization. Also state drivers uninitialized only after + * full stop of event loop. In short driver initialization/uninitializ= ation + * and handling events occurs in same main loop thread. Thus we + * don't need any locking here. */ + + if (!(dev =3D udev_monitor_receive_device(qemu_driver->udev_monitor)))= { + VIR_WARNINGS_NO_WLOGICALOP_EQUAL_EXPR + if (errno =3D=3D EAGAIN || errno =3D=3D EWOULDBLOCK) { + VIR_WARNINGS_RESET + return; + } + + virReportSystemError(errno, "%s", + _("failed to receive device from udev monitor= ")); + return; + } + + devtype =3D udev_device_get_devtype(dev); + + if (STRNEQ_NULLABLE(devtype, "usb_device")) + goto cleanup; + + if (!(action =3D udev_device_get_action(dev))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to receive action from udev monitor")); + goto cleanup; + } + + if (STREQ(action, "remove")) { + struct qemuUdevUSBRemoveData *rm_data =3D &event_data.data.remove; + + if (!(tmp =3D udev_device_get_property_value(dev, "BUSNUM"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to receive busnum from udev monitor")= ); + goto cleanup; + } + if (virStrToLong_ui(tmp, NULL, 10, &rm_data->bus) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to convert busnum to int")); + goto cleanup; + } + + if (!(tmp =3D udev_device_get_property_value(dev, "DEVNUM"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to receive devnum from udev monitor")= ); + goto cleanup; + } + if (virStrToLong_ui(tmp, NULL, 10, &rm_data->device) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to convert devnum to int")); + goto cleanup; + } + event_data.remove =3D true; + } else if (STREQ(action, "add")) { + struct qemuUdevUSBAddData *add_data =3D &event_data.data.add; + + if (!(tmp =3D udev_device_get_property_value(dev, "ID_VENDOR_ID"))= ) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to receive vendor from udev monitor")= ); + goto cleanup; + } + if (virStrToLong_ui(tmp, NULL, 16, &add_data->vendor) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to convert vendor to int")); + goto cleanup; + } + + if (!(tmp =3D udev_device_get_property_value(dev, "ID_MODEL_ID")))= { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to receive product from udev monitor"= )); + goto cleanup; + } + if (virStrToLong_ui(tmp, NULL, 16, &add_data->product) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to convert product to int")); + goto cleanup; + } + event_data.remove =3D false; + } + + event_data.found =3D false; + virDomainObjListForEach(qemu_driver->domains, qemuUdevUSBHandleEvent, = &event_data); + + cleanup: + udev_device_unref(dev); +} + + +static int +qemuUdevInitialize(void) +{ + struct udev *udev; + + if (!(udev =3D udev_new())) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to create udev context")); + return -1; + } + + if (!(qemu_driver->udev_monitor =3D udev_monitor_new_from_netlink(udev= , "udev"))) { + udev_unref(udev); + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("udev_monitor_new_from_netlink returned NULL")); + return -1; + } + + udev_monitor_enable_receiving(qemu_driver->udev_monitor); + + qemu_driver->udev_watch =3D virEventAddHandle(udev_monitor_get_fd(qemu= _driver->udev_monitor), + VIR_EVENT_HANDLE_READABLE, + qemuUdevEventHandleCallbac= k, NULL, NULL); + + if (qemu_driver->udev_watch < 0) + return -1; + + return 0; +} + + +static void +qemuUdevCleanup(void) +{ + if (qemu_driver->udev_monitor) { + struct udev *udev =3D udev_monitor_get_udev(qemu_driver->udev_moni= tor); + + udev_monitor_unref(qemu_driver->udev_monitor); + udev_unref(udev); + qemu_driver->udev_monitor =3D NULL; + } + + if (qemu_driver->udev_watch > 0) { + virEventRemoveHandle(qemu_driver->udev_watch); + qemu_driver->udev_watch =3D 0; + } +} + + /** * qemuStateInitialize: * @@ -1030,6 +1279,9 @@ qemuStateInitialize(bool privileged, if (!(qemu_driver->closeCallbacks =3D virCloseCallbacksNew())) goto error; =20 + if (qemuUdevInitialize() < 0) + goto error; + /* Get all the running persistent or transient configs first */ if (virDomainObjListLoadAllConfigs(qemu_driver->domains, cfg->stateDir, @@ -1239,6 +1491,8 @@ qemuStateCleanup(void) =20 virLockManagerPluginUnref(qemu_driver->lockManager); =20 + qemuUdevCleanup(); + virMutexDestroy(&qemu_driver->lock); VIR_FREE(qemu_driver); =20 @@ -5011,7 +5265,89 @@ processRdmaGidStatusChangedEvent(virDomainObjPtr vm, } =20 =20 -static void qemuProcessEventHandler(void *data, void *opaque) +static void +processUSBAddedEvent(virQEMUDriverPtr driver, + virDomainObjPtr vm, + struct qemuUdevUSBAddData *data) +{ + virDomainDeviceDef dev =3D { .type =3D VIR_DOMAIN_DEVICE_HOSTDEV }; + virDomainHostdevDefPtr hostdev; + size_t i; + + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) + return; + + if (!virDomainObjIsActive(vm)) { + VIR_DEBUG("Domain is not running"); + goto cleanup; + } + + for (i =3D 0; i < vm->def->nhostdevs; i++) { + virDomainHostdevSubsysUSBPtr usbsrc; + + hostdev =3D vm->def->hostdevs[i]; + usbsrc =3D &hostdev->source.subsys.u.usb; + + if (hostdev->source.subsys.type =3D=3D VIR_DOMAIN_HOSTDEV_SUBSYS_T= YPE_USB && + usbsrc->vendor =3D=3D data->vendor && usbsrc->product =3D=3D d= ata->product && + hostdev->missing) + break; + } + + if (i =3D=3D vm->def->nhostdevs) + goto cleanup; + + dev.data.hostdev =3D hostdev; + if (qemuDomainDetachDeviceLive(vm, &dev, driver, true, true) < 0) + goto cleanup; + + cleanup: + qemuDomainObjEndJob(driver, vm); +} + + +static void +processUSBRemovedEvent(virQEMUDriverPtr driver, + virDomainObjPtr vm, + struct qemuUdevUSBRemoveData *data) +{ + size_t i; + virDomainDeviceDef dev =3D { .type =3D VIR_DOMAIN_DEVICE_HOSTDEV }; + virDomainHostdevDefPtr hostdev; + + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) + return; + + if (!virDomainObjIsActive(vm)) { + VIR_DEBUG("Domain is not running"); + goto cleanup; + } + + for (i =3D 0; i < vm->def->nhostdevs; i++) { + virDomainHostdevSubsysUSBPtr usbsrc; + + hostdev =3D vm->def->hostdevs[i]; + usbsrc =3D &hostdev->source.subsys.u.usb; + + if (hostdev->source.subsys.type =3D=3D VIR_DOMAIN_HOSTDEV_SUBSYS_T= YPE_USB && + usbsrc->bus =3D=3D data->bus && usbsrc->device =3D=3D data->de= vice) + break; + } + + if (i =3D=3D vm->def->nhostdevs) + goto cleanup; + + dev.data.hostdev =3D hostdev; + if (qemuDomainDetachDeviceLive(vm, &dev, driver, true, true) < 0) + goto cleanup; + + cleanup: + qemuDomainObjEndJob(driver, vm); +} + + +static void +qemuProcessEventHandler(void *data, void *opaque) { struct qemuProcessEvent *processEvent =3D data; virDomainObjPtr vm =3D processEvent->vm; @@ -5057,6 +5393,12 @@ static void qemuProcessEventHandler(void *data, void= *opaque) case QEMU_PROCESS_EVENT_RDMA_GID_STATUS_CHANGED: processRdmaGidStatusChangedEvent(vm, processEvent->data); break; + case QEMU_PROCESS_EVENT_USB_REMOVED: + processUSBRemovedEvent(driver, vm, processEvent->data); + break; + case QEMU_PROCESS_EVENT_USB_ADDED: + processUSBAddedEvent(driver, vm, processEvent->data); + break; case QEMU_PROCESS_EVENT_LAST: break; } --=20 2.23.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 05:05:33 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1567166961; cv=none; d=zoho.com; s=zohoarc; b=joTuUpUJ+tZAHLbSW16i2OD9CvcNs08Wh/b81KaHjAocRTx+FCFDjZ6BMMv5OaP/6QktDPN26ERWitg5OAL4MukCmPWM6JEi15RWyeu/Lme34J27s9wwbXNLNpp7hD+YCMWVM53YQ0JO5gW1Jge7KpQcCVbULnlZNoAjlBm2vME= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567166961; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=hIuPTsvIC5cHGnZytG/nNUN2tlZ1Aesr2svY1IJC/tQ=; b=fR8wtArQz+nP8Z+vwoJsq/vuCy73YWsMbSMe/fYuAIvnIui7r/5MHL5FPYDCmUUyfj72OGQAhCgVex3D3YiKcso9XC9KZ9Dprfig7rCqNpgbXyz7z9pOqSOGKnWU/AzHOFOklpPD/MJYJ3Tygg2r26ZRWHPMtPpS6WnTNceOWfE= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1567166961340448.06829159291215; Fri, 30 Aug 2019 05:09:21 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0C7108796BC; Fri, 30 Aug 2019 12:09:20 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D93065B69A; Fri, 30 Aug 2019 12:09:19 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 7A1894EE75; Fri, 30 Aug 2019 12:09:19 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x7UC98dU018309 for ; Fri, 30 Aug 2019 08:09:08 -0400 Received: by smtp.corp.redhat.com (Postfix) id A227F6061E; Fri, 30 Aug 2019 12:09:08 +0000 (UTC) Received: from mx1.redhat.com (ext-mx18.extmail.prod.ext.phx2.redhat.com [10.5.110.47]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9CB1960610 for ; Fri, 30 Aug 2019 12:09:06 +0000 (UTC) Received: from relay.sw.ru (relay.sw.ru [185.231.240.75]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 019CE309B6C4 for ; Fri, 30 Aug 2019 12:09:05 +0000 (UTC) Received: from [172.16.24.106] (helo=shiny.sw.ru) by relay.sw.ru with esmtp (Exim 4.92) (envelope-from ) id 1i3fiB-0000GK-0w for libvir-list@redhat.com; Fri, 30 Aug 2019 15:09:03 +0300 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Fri, 30 Aug 2019 15:08:31 +0300 Message-Id: <20190830120834.27404-4-nshirokovskiy@virtuozzo.com> In-Reply-To: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> References: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> MIME-Version: 1.0 X-Greylist: Sender passed SPF test, ACL 264 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Fri, 30 Aug 2019 12:09:05 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Fri, 30 Aug 2019 12:09:05 +0000 (UTC) for IP:'185.231.240.75' DOMAIN:'relay.sw.ru' HELO:'relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: 0 (SPF_HELO_NONE, SPF_PASS) 185.231.240.75 relay.sw.ru 185.231.240.75 relay.sw.ru X-Scanned-By: MIMEDefang 2.84 on 10.5.110.47 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 3/6] qemu: handle usb hostdev add/del on device DELETED_EVENT X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.68]); Fri, 30 Aug 2019 12:09:20 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Now device DELETED_EVENT can have 2 causes. First is detaching device by client just as before. Second is attaching/detaching hostdev assigned to guest on node. In the latter case we reattach hostdev to guest. When device is detached from node we remove device from qemu and insert new dummy one with unset bus and device values and have missing flag set to true. This is on par with case when we start domain with startupPolicy =3D optional and device is missing on node. When device is attached to node back we remove dummy device from qemu and insert proper one with discovered bus and device and missing flag is appropriately set to false. Signed-off-by: Nikolay Shirokovskiy --- src/qemu/qemu_driver.c | 12 ++----- src/qemu/qemu_hotplug.c | 73 ++++++++++++++++++++++++++++++++++------- src/qemu/qemu_hotplug.h | 4 +++ src/util/virhostdev.c | 6 ++-- 4 files changed, 72 insertions(+), 23 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 33b75a3c71..352f6d0376 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4677,7 +4677,6 @@ processDeviceDeletedEvent(virQEMUDriverPtr driver, const char *devAlias) { virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); - virDomainDeviceDef dev; =20 VIR_DEBUG("Removing device %s from domain %p %s", devAlias, vm, vm->def->name); @@ -4690,15 +4689,10 @@ processDeviceDeletedEvent(virQEMUDriverPtr driver, goto endjob; } =20 - if (STRPREFIX(devAlias, "vcpu")) { + if (STRPREFIX(devAlias, "vcpu")) qemuDomainRemoveVcpuAlias(driver, vm, devAlias); - } else { - if (virDomainDefFindDevice(vm->def, devAlias, &dev, true) < 0) - goto endjob; - - if (qemuDomainRemoveDevice(driver, vm, &dev) < 0) - goto endjob; - } + else if (qemuDomainRemoveDeviceAlias(driver, vm, devAlias) < 0) + goto endjob; =20 if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->cap= s) < 0) VIR_WARN("unable to save domain status after removing device %s", diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 08e60dcd0e..197b2b2fd7 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2437,8 +2437,10 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr drive= r, bool teardownlabel =3D false; bool teardowndevice =3D false; int ret =3D -1; + bool reattaching =3D hostdev->deleteCause =3D=3D VIR_DOMAIN_HOSTDEV_DE= LETE_CAUSE_REATTACHING; =20 - if (virDomainUSBAddressEnsure(priv->usbaddrs, hostdev->info) < 0) + if (!reattaching && + virDomainUSBAddressEnsure(priv->usbaddrs, hostdev->info) < 0) return -1; =20 if (qemuHostdevPrepareUSBDevices(driver, vm->def->name, &hostdev, 1, 0= ) < 0) @@ -2463,7 +2465,7 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver, if (!(devstr =3D qemuBuildUSBHostdevDevStr(vm->def, hostdev, priv->qem= uCaps))) goto cleanup; =20 - if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) + if (!reattaching && VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdev= s+1) < 0) goto cleanup; =20 qemuDomainObjEnterMonitor(driver, vm); @@ -2476,7 +2478,8 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver, if (ret < 0) goto cleanup; =20 - vm->def->hostdevs[vm->def->nhostdevs++] =3D hostdev; + if (!reattaching) + vm->def->hostdevs[vm->def->nhostdevs++] =3D hostdev; =20 ret =3D 0; cleanup: @@ -2491,7 +2494,8 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver, VIR_WARN("Unable to remove host device from /dev"); if (added) qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev,= 1); - virDomainUSBAddressRelease(priv->usbaddrs, hostdev->info); + if (!reattaching) + virDomainUSBAddressRelease(priv->usbaddrs, hostdev->info); } VIR_FREE(devstr); return ret; @@ -4366,7 +4370,8 @@ qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver, virDomainHostdevDefPtr hostdev) { qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1); - qemuDomainReleaseDeviceAddress(vm, hostdev->info); + if (hostdev->deleteCause !=3D VIR_DOMAIN_HOSTDEV_DELETE_CAUSE_REATTACH= ING) + qemuDomainReleaseDeviceAddress(vm, hostdev->info); } =20 static void @@ -4408,6 +4413,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, char *drivealias =3D NULL; char *objAlias =3D NULL; bool is_vfio =3D false; + bool reattaching =3D hostdev->deleteCause =3D=3D VIR_DOMAIN_HOSTDEV_DE= LETE_CAUSE_REATTACHING; =20 VIR_DEBUG("Removing host device %s from domain %p %s", hostdev->info->alias, vm, vm->def->name); @@ -4454,16 +4460,25 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, } } =20 - for (i =3D 0; i < vm->def->nhostdevs; i++) { - if (vm->def->hostdevs[i] =3D=3D hostdev) { - virDomainHostdevRemove(vm->def, i); - break; + if (!reattaching) { + for (i =3D 0; i < vm->def->nhostdevs; i++) { + if (vm->def->hostdevs[i] =3D=3D hostdev) { + virDomainHostdevRemove(vm->def, i); + break; + } } } =20 virDomainAuditHostdev(vm, hostdev, "detach", true); =20 - if (!is_vfio && + /* + * In case of reattaching (when usb is detached from host) the attempt= to + * restore label will fail. But we don't need to restore the label! In= case + * of separate mount namespace for the domain we remove device file la= ter + * in this function. In case of global mount namespace the device file= is + * deleted or being deleted by systemd. + */ + if (!is_vfio && !reattaching && qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0) VIR_WARN("Failed to restore host device labelling"); =20 @@ -4497,7 +4512,13 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, break; } =20 - virDomainHostdevDefFree(hostdev); + if (reattaching) { + virDomainHostdevSubsysUSBPtr usbsrc =3D &hostdev->source.subsys.u.= usb; + usbsrc->bus =3D 0; + usbsrc->device =3D 0; + } else { + virDomainHostdevDefFree(hostdev); + } =20 if (net) { if (net->type =3D=3D VIR_DOMAIN_NET_TYPE_NETWORK) { @@ -6565,3 +6586,33 @@ qemuDomainSetVcpuInternal(virQEMUDriverPtr driver, virBitmapFree(livevcpus); return ret; } + + +int +qemuDomainRemoveDeviceAlias(virQEMUDriverPtr driver, + virDomainObjPtr vm, + const char *devAlias) +{ + virDomainDeviceDef dev; + + if (virDomainDefFindDevice(vm->def, devAlias, &dev, true) < 0) + return -1; + + if (dev.type =3D=3D VIR_DOMAIN_DEVICE_HOSTDEV && + dev.data.hostdev->deleteCause =3D=3D VIR_DOMAIN_HOSTDEV_DELETE_CAU= SE_REATTACHING) { + virDomainHostdevDefPtr hostdev =3D dev.data.hostdev; + + if (qemuDomainRemoveHostDevice(driver, vm, hostdev) < 0) + return -1; + + if (qemuDomainAttachHostDevice(driver, vm, hostdev) < 0) + return -1; + + hostdev->deleteCause =3D 0; + } else { + if (qemuDomainRemoveDevice(driver, vm, &dev) < 0) + return -1; + } + + return 0; +} diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index bf812eab1a..f85e5db2fe 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -151,3 +151,7 @@ int qemuDomainSetVcpuInternal(virQEMUDriverPtr driver, virDomainDefPtr persistentDef, virBitmapPtr vcpus, bool state); + +int qemuDomainRemoveDeviceAlias(virQEMUDriverPtr driver, + virDomainObjPtr vm, + const char *devAlias); diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c index d710193b94..a2c0c07eb9 100644 --- a/src/util/virhostdev.c +++ b/src/util/virhostdev.c @@ -1429,8 +1429,7 @@ virHostdevFindUSBDevice(virDomainHostdevDefPtr hostde= v, } =20 out: - if (!*usb) - hostdev->missing =3D true; + hostdev->missing =3D !*usb; return 0; } =20 @@ -1472,7 +1471,8 @@ virHostdevPrepareUSBDevices(virHostdevManagerPtr mgr, =20 if (hostdev->startupPolicy =3D=3D VIR_DOMAIN_STARTUP_POLICY_OPTION= AL || (hostdev->startupPolicy =3D=3D VIR_DOMAIN_STARTUP_POLICY_REQUI= SITE && - !coldBoot)) + !coldBoot) || + hostdev->deleteCause =3D=3D VIR_DOMAIN_HOSTDEV_DELETE_CAUSE_RE= ATTACHING) required =3D false; =20 if (virHostdevFindUSBDevice(hostdev, required, &usb) < 0) --=20 2.23.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 05:05:33 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1567166952; cv=none; d=zoho.com; s=zohoarc; b=cPdmLa8bg4zQftc8OlJerd+d/1yVpQp6gPS4IxkoYns+OfPdVv7AIN4osDPKWdFvMRrbF7DOnzaYTrpTtyLcKj35Njy8918NVjsNG3nzelvDlDTEH3WO4UIyT3vF13fXsUKPWTqKzu+OvZ304mdIox8LG8I7AfVdFbMKVCmLzDo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567166952; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=1z02yYpUx5y6PNw1dKbajw8PY12HWNth08V6R6ANPlg=; b=hTHeqxCbxeK7Pi39ORvusJt94Gzh15srg4jT8zw6kKZ86jSf58Mzoo2Nhg0V18wHyIr2fyWz4oIGKRvpBxFnbj4ZqJbO/2JuOIDTNZ2AYtQo741zilJXKVAPs3ALw2EyIZx755flqJs/teXzqDF370J10cuHRBJMQN6GB/LJoxE= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1567166952279259.1636851164084; Fri, 30 Aug 2019 05:09:12 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E26A23082DDD; Fri, 30 Aug 2019 12:09:10 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9F0AA60605; Fri, 30 Aug 2019 12:09:10 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 515C84EE6D; Fri, 30 Aug 2019 12:09:10 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x7UC98bb018304 for ; Fri, 30 Aug 2019 08:09:08 -0400 Received: by smtp.corp.redhat.com (Postfix) id 51D2660C5D; Fri, 30 Aug 2019 12:09:08 +0000 (UTC) Received: from mx1.redhat.com (ext-mx29.extmail.prod.ext.phx2.redhat.com [10.5.110.70]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4D6A560C05 for ; Fri, 30 Aug 2019 12:09:06 +0000 (UTC) Received: from relay.sw.ru (relay.sw.ru [185.231.240.75]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6C47018B20EB for ; Fri, 30 Aug 2019 12:09:05 +0000 (UTC) Received: from [172.16.24.106] (helo=shiny.sw.ru) by relay.sw.ru with esmtp (Exim 4.92) (envelope-from ) id 1i3fiB-0000GK-E5 for libvir-list@redhat.com; Fri, 30 Aug 2019 15:09:03 +0300 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Fri, 30 Aug 2019 15:08:32 +0300 Message-Id: <20190830120834.27404-5-nshirokovskiy@virtuozzo.com> In-Reply-To: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> References: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> MIME-Version: 1.0 X-Greylist: Sender passed SPF test, ACL 264 matched, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.70]); Fri, 30 Aug 2019 12:09:05 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.70]); Fri, 30 Aug 2019 12:09:05 +0000 (UTC) for IP:'185.231.240.75' DOMAIN:'relay.sw.ru' HELO:'relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: 0 (SPF_HELO_NONE, SPF_PASS) 185.231.240.75 relay.sw.ru 185.231.240.75 relay.sw.ru X-Scanned-By: MIMEDefang 2.84 on 10.5.110.70 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 4/6] conf: parse hostdev missing flag X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 30 Aug 2019 12:09:11 +0000 (UTC) Content-Type: text/plain; charset="utf-8" We want to keep this flag across libvirtd restarts. Signed-off-by: Nikolay Shirokovskiy --- src/conf/domain_conf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b7a342bb91..9a2385e31c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7533,6 +7533,7 @@ virDomainHostdevSubsysUSBDefParseXML(xmlNodePtr node, virDomainHostdevSubsysUSBPtr usbsrc =3D &def->source.subsys.u.usb; VIR_AUTOFREE(char *) startupPolicy =3D NULL; VIR_AUTOFREE(char *) autoAddress =3D NULL; + VIR_AUTOFREE(char *) missing =3D NULL; =20 if ((startupPolicy =3D virXMLPropString(node, "startupPolicy"))) { def->startupPolicy =3D @@ -7550,6 +7551,11 @@ virDomainHostdevSubsysUSBDefParseXML(xmlNodePtr node, usbsrc->autoAddress =3D true; } =20 + if ((missing =3D virXMLPropString(node, "missing"))) { + if (STREQ(missing, "yes")) + def->missing =3D true; + } + /* Product can validly be 0, so we need some extra help to determine * if it is uninitialized*/ got_product =3D false; --=20 2.23.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 05:05:33 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1567166957; cv=none; d=zoho.com; s=zohoarc; b=cDQq6z9A2Qkm4afsYx3Z/VtfYSWgwA2zp7Gb0S/87Z8JLfzuI5t2G7kw2q3Va0P5lbPtwqbS1ALsw7ntf4vBVofVhC3ffQ6bL85lJ26frExkwNZxPqllyCIZ6UX+sFeWocbEw+op0phhurqggrHi7N68ZkhQUh9+UxTTHIJRt98= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567166957; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=cf9MWLJQgPZLLZxWoQ6AsPokWJ/wFqn29s8z+tmZjP4=; b=CAmBJZOK3rfmkdbwr3dnlZW6z160QbaEm2TNq6QOIelTfNPXGuEZqyqlnbxSiCjr/sVRPetspdqUofh7WVrqHu8+soqtKxIt4yPubt9CukLY3aSRpp0a9UMscnubAWlhD/UDWd6+TaOn2+UfaM2OeaEXewLUdrxlHvmlMEMYTQc= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 15671669576871020.9058363458958; Fri, 30 Aug 2019 05:09:17 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7D9B8190C034; Fri, 30 Aug 2019 12:09:16 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 568105C221; Fri, 30 Aug 2019 12:09:16 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 15E9518034E0; Fri, 30 Aug 2019 12:09:16 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x7UC98B9018316 for ; Fri, 30 Aug 2019 08:09:08 -0400 Received: by smtp.corp.redhat.com (Postfix) id BF57B3DE1; Fri, 30 Aug 2019 12:09:08 +0000 (UTC) Received: from mx1.redhat.com (ext-mx24.extmail.prod.ext.phx2.redhat.com [10.5.110.65]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B8A3019C77 for ; Fri, 30 Aug 2019 12:09:06 +0000 (UTC) Received: from relay.sw.ru (relay.sw.ru [185.231.240.75]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9171610C6966 for ; Fri, 30 Aug 2019 12:09:05 +0000 (UTC) Received: from [172.16.24.106] (helo=shiny.sw.ru) by relay.sw.ru with esmtp (Exim 4.92) (envelope-from ) id 1i3fiB-0000GK-R2 for libvir-list@redhat.com; Fri, 30 Aug 2019 15:09:04 +0300 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Fri, 30 Aug 2019 15:08:33 +0300 Message-Id: <20190830120834.27404-6-nshirokovskiy@virtuozzo.com> In-Reply-To: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> References: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> MIME-Version: 1.0 X-Greylist: Sender passed SPF test, ACL 264 matched, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.65]); Fri, 30 Aug 2019 12:09:06 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.65]); Fri, 30 Aug 2019 12:09:06 +0000 (UTC) for IP:'185.231.240.75' DOMAIN:'relay.sw.ru' HELO:'relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: 0 (SPF_HELO_NONE, SPF_PASS) 185.231.240.75 relay.sw.ru 185.231.240.75 relay.sw.ru X-Scanned-By: MIMEDefang 2.84 on 10.5.110.65 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 5/6] qemu: handle libvirtd restarts during hostdev reattaching X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.70]); Fri, 30 Aug 2019 12:09:17 +0000 (UTC) Content-Type: text/plain; charset="utf-8" We need to handle case when libvirtd is restarted after qemu device is deleted in order to reattach hostdev and before device deleted event is delivired. First we need to save delete_cause in status xml so that if event is delivered after libvirtd started back we can proceed with reattaching. Second if we missed the event we need to continue with reattaching too. Signed-off-by: Nikolay Shirokovskiy --- src/conf/domain_conf.c | 26 ++++++++++++++++++++++++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_driver.c | 20 ++++++++++++++++++-- src/qemu/qemu_process.c | 6 ++---- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9a2385e31c..ecab83147e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1236,6 +1236,13 @@ VIR_ENUM_IMPL(virDomainShmemModel, "ivshmem-doorbell", ); =20 +VIR_ENUM_IMPL(virDomainHostdevDeleteCause, + VIR_DOMAIN_HOSTDEV_DELETE_CAUSE_LAST, + "none", + "client", + "reattaching" +); + VIR_ENUM_IMPL(virDomainLaunchSecurity, VIR_DOMAIN_LAUNCH_SECURITY_LAST, "", @@ -7534,6 +7541,7 @@ virDomainHostdevSubsysUSBDefParseXML(xmlNodePtr node, VIR_AUTOFREE(char *) startupPolicy =3D NULL; VIR_AUTOFREE(char *) autoAddress =3D NULL; VIR_AUTOFREE(char *) missing =3D NULL; + VIR_AUTOFREE(char *) deleteCause =3D NULL; =20 if ((startupPolicy =3D virXMLPropString(node, "startupPolicy"))) { def->startupPolicy =3D @@ -7556,6 +7564,18 @@ virDomainHostdevSubsysUSBDefParseXML(xmlNodePtr node, def->missing =3D true; } =20 + if ((deleteCause =3D virXMLPropString(node, "deleteCause"))) { + def->deleteCause =3D + virDomainHostdevDeleteCauseTypeFromString(deleteCause); + + if (def->deleteCause <=3D 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown deleteCause '%s'"), + deleteCause); + goto out; + } + } + /* Product can validly be 0, so we need some extra help to determine * if it is uninitialized*/ got_product =3D false; @@ -24911,6 +24931,12 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, =20 if (def->missing && !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) virBufferAddLit(buf, " missing=3D'yes'"); + + if (def->deleteCause && (flags & VIR_DOMAIN_DEF_FORMAT_STATUS)) { + const char *deleteCause; + deleteCause =3D virDomainHostdevDeleteCauseTypeToString(def->d= eleteCause); + virBufferAsprintf(buf, " deleteCause=3D'%s'", deleteCause); + } } =20 if (def->source.subsys.type =3D=3D VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI= && diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 49392d0286..a2de4c7657 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -333,6 +333,7 @@ typedef enum { =20 VIR_DOMAIN_HOSTDEV_DELETE_CAUSE_LAST } virDomainHostdevDeleteCauseType; +VIR_ENUM_DECL(virDomainHostdevDeleteCause); =20 =20 /* basic device for direct passthrough */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 352f6d0376..b912766445 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5265,11 +5265,14 @@ processUSBAddedEvent(virQEMUDriverPtr driver, struct qemuUdevUSBAddData *data) { virDomainDeviceDef dev =3D { .type =3D VIR_DOMAIN_DEVICE_HOSTDEV }; + virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); virDomainHostdevDefPtr hostdev; size_t i; =20 - if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) { + virObjectUnref(cfg); return; + } =20 if (!virDomainObjIsActive(vm)) { VIR_DEBUG("Domain is not running"); @@ -5295,8 +5298,13 @@ processUSBAddedEvent(virQEMUDriverPtr driver, if (qemuDomainDetachDeviceLive(vm, &dev, driver, true, true) < 0) goto cleanup; =20 + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->cap= s) < 0) + VIR_WARN("unable to save domain status after reattaching device %s= ", + hostdev->info->alias); + cleanup: qemuDomainObjEndJob(driver, vm); + virObjectUnref(cfg); } =20 =20 @@ -5307,10 +5315,13 @@ processUSBRemovedEvent(virQEMUDriverPtr driver, { size_t i; virDomainDeviceDef dev =3D { .type =3D VIR_DOMAIN_DEVICE_HOSTDEV }; + virQEMUDriverConfigPtr cfg =3D virQEMUDriverGetConfig(driver); virDomainHostdevDefPtr hostdev; =20 - if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) { + virObjectUnref(cfg); return; + } =20 if (!virDomainObjIsActive(vm)) { VIR_DEBUG("Domain is not running"); @@ -5335,8 +5346,13 @@ processUSBRemovedEvent(virQEMUDriverPtr driver, if (qemuDomainDetachDeviceLive(vm, &dev, driver, true, true) < 0) goto cleanup; =20 + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->cap= s) < 0) + VIR_WARN("unable to save domain status after reattaching device %s= ", + hostdev->info->alias); + cleanup: qemuDomainObjEndJob(driver, vm); + virObjectUnref(cfg); } =20 =20 diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index c9921646e9..5cb97de4f3 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3720,7 +3720,6 @@ qemuProcessUpdateDevices(virQEMUDriverPtr driver, virDomainObjPtr vm) { qemuDomainObjPrivatePtr priv =3D vm->privateData; - virDomainDeviceDef dev; const char **qemuDevices; char **old; char **tmp; @@ -3735,10 +3734,9 @@ qemuProcessUpdateDevices(virQEMUDriverPtr driver, if ((tmp =3D old)) { while (*tmp) { if (!virStringListHasString(qemuDevices, *tmp) && - virDomainDefFindDevice(vm->def, *tmp, &dev, false) =3D=3D = 0 && - qemuDomainRemoveDevice(driver, vm, &dev) < 0) { + qemuDomainRemoveDeviceAlias(driver, vm, *tmp) < 0) goto cleanup; - } + tmp++; } } --=20 2.23.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sun May 5 05:05:33 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=none dis=none) header.from=virtuozzo.com ARC-Seal: i=1; a=rsa-sha256; t=1567166965; cv=none; d=zoho.com; s=zohoarc; b=eRM8pH4Cf8wwz00NErVxiyvkOCS4fO2mxmV5qdHh5O9as/0lsXpXxfUBmDl25Hct7Bv1gKVmiHOeawFIzD1UQu6wJavDgX99J64VwGulDhLWmN8bLErgIB4f1jWiZAX4lDkvQL7ymS8USaRQIy887wdtOgnhKg0KBL8ULLas+/I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567166965; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=4+XeZvslMD1ggyESovsHG60TC9euMVeqIBehxrrmG5o=; b=Z+pruoFMnSGGtxUb69B735VfHmvHL6g693Z1mueKnvht26Gf5xIvLB7sXeDrJUlhzTPW5GhsmuHQ9+eO1nvB9Orh83/UC/+NkziZOMoJT4vayNqqy0mumSJzJhH9Koa0Fto72kIMwS4QHDwPie9Yj5TOUs0+OGTrpmQShJMlRlE= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1567166965428815.6793787574393; Fri, 30 Aug 2019 05:09:25 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3EEDD30860C7; Fri, 30 Aug 2019 12:09:24 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 17E2960610; Fri, 30 Aug 2019 12:09:24 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id C81BA180BA9C; Fri, 30 Aug 2019 12:09:23 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x7UC9BxI018351 for ; Fri, 30 Aug 2019 08:09:11 -0400 Received: by smtp.corp.redhat.com (Postfix) id CFD925C221; Fri, 30 Aug 2019 12:09:11 +0000 (UTC) Received: from mx1.redhat.com (ext-mx13.extmail.prod.ext.phx2.redhat.com [10.5.110.42]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CAFEB5C1D6 for ; Fri, 30 Aug 2019 12:09:06 +0000 (UTC) Received: from relay.sw.ru (relay.sw.ru [185.231.240.75]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F026B3086218 for ; Fri, 30 Aug 2019 12:09:05 +0000 (UTC) Received: from [172.16.24.106] (helo=shiny.sw.ru) by relay.sw.ru with esmtp (Exim 4.92) (envelope-from ) id 1i3fiC-0000GK-7D for libvir-list@redhat.com; Fri, 30 Aug 2019 15:09:04 +0300 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Fri, 30 Aug 2019 15:08:34 +0300 Message-Id: <20190830120834.27404-7-nshirokovskiy@virtuozzo.com> In-Reply-To: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> References: <20190830120834.27404-1-nshirokovskiy@virtuozzo.com> MIME-Version: 1.0 X-Greylist: Sender passed SPF test, ACL 264 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 30 Aug 2019 12:09:06 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 30 Aug 2019 12:09:06 +0000 (UTC) for IP:'185.231.240.75' DOMAIN:'relay.sw.ru' HELO:'relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: 0 (SPF_HELO_NONE, SPF_PASS) 185.231.240.75 relay.sw.ru 185.231.240.75 relay.sw.ru X-Scanned-By: MIMEDefang 2.84 on 10.5.110.42 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 6/6] qemu: handle hostdev add/del when libvirtd is down X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Fri, 30 Aug 2019 12:09:24 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Somebody can easily detach hostdev on node while libvirtd is being stopped. Also hostdev can be attached or detached and attached back and so forth. Let's handle such cases. Signed-off-by: Nikolay Shirokovskiy --- src/qemu/qemu_process.c | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 5cb97de4f3..f70f0ae251 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3747,6 +3747,52 @@ qemuProcessUpdateDevices(virQEMUDriverPtr driver, return ret; } =20 + +static int +qemuProcessReattachUSBDevices(virQEMUDriverPtr driver, + virDomainObjPtr vm) +{ + size_t i; + + for (i =3D 0; i < vm->def->nhostdevs; i++) { + virDomainDeviceDef dev =3D { .type =3D VIR_DOMAIN_DEVICE_HOSTDEV }; + virDomainHostdevDefPtr hostdev =3D vm->def->hostdevs[i]; + virDomainHostdevSubsysUSBPtr usbsrc =3D &hostdev->source.subsys.u.= usb; + bool found; + + + if (hostdev->source.subsys.type !=3D VIR_DOMAIN_HOSTDEV_SUBSYS_TYP= E_USB) + continue; + + if (hostdev->missing) { + int num; + + if ((num =3D virUSBDeviceFindByVendor(usbsrc->vendor, usbsrc->= product, + NULL, false, NULL)) < 0) + return -1; + + found =3D num !=3D 0; + } else { + virUSBDevicePtr usb; + + if (virUSBDeviceFindByBus(usbsrc->bus, usbsrc->device, + NULL, false, &usb) < 0) + return -1; + + found =3D usb !=3D NULL; + virUSBDeviceFree(usb); + } + + dev.data.hostdev =3D hostdev; + if ((hostdev->missing ^ !found) && + qemuDomainDetachDeviceLive(vm, &dev, driver, true, true) < 0) + return -1; + } + + return 0; +} + + static int qemuDomainPerfRestart(virDomainObjPtr vm) { @@ -8204,6 +8250,9 @@ qemuProcessReconnect(void *opaque) if (qemuProcessUpdateDevices(driver, obj) < 0) goto error; =20 + if (qemuProcessReattachUSBDevices(driver, obj) < 0) + goto error; + if (qemuRefreshPRManagerState(driver, obj) < 0) goto error; =20 --=20 2.23.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list