From nobody Fri Apr 26 08:50:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.39 as permitted sender) client-ip=209.132.183.39; envelope-from=libvir-list-bounces@redhat.com; helo=mx6-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.39 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx6-phx2.redhat.com (mx6-phx2.redhat.com [209.132.183.39]) by mx.zohomail.com with SMTPS id 148769503192965.16517403820455; Tue, 21 Feb 2017 08:37:11 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx6-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1LGXWGh005615; Tue, 21 Feb 2017 11:33:32 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1LGXVDM026489 for ; Tue, 21 Feb 2017 11:33:31 -0500 Received: from localhost.localdomain.com (ovpn-116-126.phx2.redhat.com [10.3.116.126]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1LGXUVT020390 for ; Tue, 21 Feb 2017 11:33:31 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Tue, 21 Feb 2017 11:33:26 -0500 Message-Id: <20170221163328.7070-2-jferlan@redhat.com> In-Reply-To: <20170221163328.7070-1-jferlan@redhat.com> References: <20170221163328.7070-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH REPOST v2 1/3] nodedev: Add driver callback mechanism to add/remove devices 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: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add a callback mechanism as a side door of sorts to the event mgmt functions that are triggered when a node_device object is added or removed. This includes a mechanism to enumerate already added devices for those stateInitialize functions called after the initial nodedevRegister is called. If there is no enumeration callback, a failure would be returned since the caller would seem to need that. Signed-off-by: John Ferlan --- src/check-aclrules.pl | 3 +- src/check-driverimpls.pl | 1 + src/conf/node_device_conf.c | 112 +++++++++++++++++++++++++++++++++= +++- src/conf/node_device_conf.h | 18 ++++++ src/libvirt_private.syms | 3 + src/node_device/node_device_udev.c | 29 ++++++++++ 6 files changed, 164 insertions(+), 2 deletions(-) diff --git a/src/check-aclrules.pl b/src/check-aclrules.pl index 8739cda..161d954 100755 --- a/src/check-aclrules.pl +++ b/src/check-aclrules.pl @@ -243,7 +243,8 @@ while (<>) { } elsif (/^(?:static\s+)?(vir(?:\w+)?Driver)\s+/) { if ($1 ne "virNWFilterCallbackDriver" && $1 ne "virNWFilterTechDriver" && - $1 ne "virDomainConfNWFilterDriver") { + $1 ne "virDomainConfNWFilterDriver" && + $1 ne "virNodeDeviceCallbackDriver") { $intable =3D 1; $table =3D $1; } diff --git a/src/check-driverimpls.pl b/src/check-driverimpls.pl index e320558..b707fc8 100755 --- a/src/check-driverimpls.pl +++ b/src/check-driverimpls.pl @@ -70,6 +70,7 @@ while (<>) { } elsif (/^(?:static\s+)?(vir(?:\w+)?Driver)\s+/) { next if $1 eq "virNWFilterCallbackDriver" || $1 eq "virNWFilterTechDriver" || + $1 eq "virNodeDeviceCallbackDriver" || $1 eq "virConnectDriver"; $intable =3D 1; $table =3D $1; diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index c802840..061f013 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -278,6 +278,99 @@ void virNodeDeviceDefFree(virNodeDeviceDefPtr def) VIR_FREE(def); } =20 + +/* Provide callback infrastructure that is expected to be called when + * devices are added/removed from a node_device subsystem that supports + * the callback mechanism. This provides a way for drivers to register + * to be notified when a node_device is added/removed. */ +virNodedevEnumerateAddDevices virNodedevEnumerateAddDevicesCb =3D NULL; +int nodeDeviceCallbackDriver; +#define MAX_CALLBACK_DRIVER 10 +static virNodeDeviceCallbackDriverPtr nodeDeviceDrvArray[MAX_CALLBACK_DRIV= ER]; + + +/** + * @cb: Driver function to be called. + * + * Set a callback at driver initialization to provide a callback to a + * driver specific function that can handle the enumeration of the existing + * devices and the addition of those devices for the registering driver. + * + * The initial node_device enumeration is done prior to other drivers, thus + * this provides a mechanism to load the existing data since the functions + * virNodeDeviceAssignDef and virNodeDeviceObjRemove would typically + * only be called when a new device is added/removed after the initial + * enumeration. The registering driver will need to handle duplication + * of data. + */ +void +virNodeDeviceConfEnumerateInit(virNodedevEnumerateAddDevices cb) +{ + virNodedevEnumerateAddDevicesCb =3D cb; +} + + +/** + * @cbd: Driver callback pointers to add/remove devices + * + * Register a callback function in the registering driver to be called + * when devices are added or removed. Additionally, ensure the initial + * enumeration of the devices is completed taking care to do it after + * setting the callbacks + * + * Returns address of enumerate callback on success, NULL on failure + */ +virNodedevEnumerateAddDevices +virNodeDeviceRegisterCallbackDriver(virNodeDeviceCallbackDriverPtr cbd) +{ + if (nodeDeviceCallbackDriver >=3D MAX_CALLBACK_DRIVER) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("no space available for another callback driver")= ); + return NULL; + } + + if (!cbd->nodeDeviceAdd || !cbd->nodeDeviceRemove) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("callback requires both add and remove functions"= )); + return NULL; + } + + if (!virNodedevEnumerateAddDevicesCb) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("no enumeration callback API is registered")); + return NULL; + } + + nodeDeviceDrvArray[nodeDeviceCallbackDriver++] =3D cbd; + + return virNodedevEnumerateAddDevicesCb; +} + + +/** + * @cb: Driver function to be called. + * + * Clear the callback function. It'll be up to the calling driver to + * clear it's own data properly + */ +void +virNodeDeviceUnregisterCallbackDriver(virNodeDeviceCallbackDriverPtr cbd) +{ + size_t i =3D 0; + + while (i < nodeDeviceCallbackDriver && nodeDeviceDrvArray[i] !=3D cbd) + i++; + + if (i < nodeDeviceCallbackDriver) { + memmove(&nodeDeviceDrvArray[i], &nodeDeviceDrvArray[i+1], + (nodeDeviceCallbackDriver - i - 1) * + sizeof(nodeDeviceDrvArray[i])); + nodeDeviceDrvArray[i] =3D NULL; + nodeDeviceCallbackDriver--; + } +} + + void virNodeDeviceObjFree(virNodeDeviceObjPtr dev) { if (!dev) @@ -304,6 +397,7 @@ void virNodeDeviceObjListFree(virNodeDeviceObjListPtr d= evs) virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDeviceObjListPtr devs, virNodeDeviceDefPtr def) { + size_t i; virNodeDeviceObjPtr device; =20 if ((device =3D virNodeDeviceFindByName(devs, def->name))) { @@ -330,6 +424,13 @@ virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDevi= ceObjListPtr devs, } device->def =3D def; =20 + /* Call any registered drivers that want to be notified of a new devic= e */ + for (i =3D 0; i < nodeDeviceCallbackDriver; i++) { + if (nodeDeviceDrvArray[i]->nodeDeviceAdd(def, false) < 0) + VIR_WARN("Failed to add device name '%s' parent '%s' for " + "register callback %zu", def->name, def->parent, i); + } + return device; =20 } @@ -337,13 +438,22 @@ virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDev= iceObjListPtr devs, void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs, virNodeDeviceObjPtr *dev) { - size_t i; + size_t i, j; =20 virNodeDeviceObjUnlock(*dev); =20 for (i =3D 0; i < devs->count; i++) { virNodeDeviceObjLock(*dev); if (devs->objs[i] =3D=3D *dev) { + /* Call any registered drivers that want to be notified of a + * removed device */ + for (j =3D 0; j < nodeDeviceCallbackDriver; j++) { + if (nodeDeviceDrvArray[j]->nodeDeviceRemove((*dev)->def) <= 0) { + VIR_WARN("failed to remove name=3D'%s' parent=3D'%s' f= rom " + "callback driver, continuing", + (*dev)->def->name, (*dev)->def->parent); + } + } virNodeDeviceObjUnlock(*dev); virNodeDeviceObjFree(devs->objs[i]); *dev =3D NULL; diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 8213c27..b1d878a 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -234,6 +234,24 @@ struct _virNodeDeviceDef { virNodeDevCapsDefPtr caps; /* optional device capabilities */ }; =20 +/* Callback mechanism to add/remove node device's by name/parent + * to a target driver that cares to know */ +typedef int (*virNodeDeviceAdd)(virNodeDeviceDefPtr def, bool enumerate); +typedef int (*virNodeDeviceRemove)(virNodeDeviceDefPtr def); + +typedef struct _virNodeDeviceCallbackDriver virNodeDeviceCallbackDriver; +typedef virNodeDeviceCallbackDriver *virNodeDeviceCallbackDriverPtr; +struct _virNodeDeviceCallbackDriver { + const char *name; + virNodeDeviceAdd nodeDeviceAdd; + virNodeDeviceRemove nodeDeviceRemove; +}; + +typedef int (*virNodedevEnumerateAddDevices)(virNodeDeviceAdd deviceAddCb); +void virNodeDeviceConfEnumerateInit(virNodedevEnumerateAddDevices cb); + +virNodedevEnumerateAddDevices virNodeDeviceRegisterCallbackDriver(virNodeD= eviceCallbackDriverPtr); +void virNodeDeviceUnregisterCallbackDriver(virNodeDeviceCallbackDriverPtr); =20 typedef struct _virNodeDeviceObj virNodeDeviceObj; typedef virNodeDeviceObj *virNodeDeviceObjPtr; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e6ccd69..f426c76 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -695,6 +695,7 @@ virNodeDevCapsDefFree; virNodeDevCapTypeFromString; virNodeDevCapTypeToString; virNodeDeviceAssignDef; +virNodeDeviceConfEnumerateInit; virNodeDeviceDefFormat; virNodeDeviceDefFree; virNodeDeviceDefParseFile; @@ -711,6 +712,8 @@ virNodeDeviceObjListFree; virNodeDeviceObjLock; virNodeDeviceObjRemove; virNodeDeviceObjUnlock; +virNodeDeviceRegisterCallbackDriver; +virNodeDeviceUnregisterCallbackDriver; =20 =20 # conf/node_device_event.h diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index 1016075..52e5e97 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1529,6 +1529,33 @@ static int udevPCITranslateInit(bool privileged ATTR= IBUTE_UNUSED) return 0; } =20 + +/* + * @deviceAddCb: Callback routine for adding a device + * + * Enumerate all known devices calling the add device callback function + * + * Returns 0 on success, -1 on failure + */ +static int +udevEnumerateAddDevices(virNodeDeviceAdd deviceAddCb) +{ + size_t i; + int ret =3D 0; + + nodeDeviceLock(); + for (i =3D 0; i < driver->devs.count && ret >=3D 0; i++) { + virNodeDeviceObjPtr obj =3D driver->devs.objs[i]; + virNodeDeviceObjLock(obj); + ret =3D deviceAddCb(obj->def, true); + virNodeDeviceObjUnlock(obj); + } + nodeDeviceUnlock(); + + return ret; +} + + static int nodeStateInitialize(bool privileged, virStateInhibitCallback callback ATTRIBUTE_= UNUSED, void *opaque ATTRIBUTE_UNUSED) @@ -1606,6 +1633,8 @@ static int nodeStateInitialize(bool privileged, if (udevEnumerateDevices(udev) !=3D 0) goto cleanup; =20 + virNodeDeviceConfEnumerateInit(udevEnumerateAddDevices); + ret =3D 0; =20 cleanup: --=20 2.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri Apr 26 08:50:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.25 as permitted sender) client-ip=209.132.183.25; envelope-from=libvir-list-bounces@redhat.com; helo=mx4-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.25 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx4-phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) by mx.zohomail.com with SMTPS id 1487695035493862.9494602595556; Tue, 21 Feb 2017 08:37:15 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1LGXcvg009234; Tue, 21 Feb 2017 11:33:38 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1LGXV3e026495 for ; Tue, 21 Feb 2017 11:33:31 -0500 Received: from localhost.localdomain.com (ovpn-116-126.phx2.redhat.com [10.3.116.126]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1LGXUVU020390 for ; Tue, 21 Feb 2017 11:33:31 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Tue, 21 Feb 2017 11:33:27 -0500 Message-Id: <20170221163328.7070-3-jferlan@redhat.com> In-Reply-To: <20170221163328.7070-1-jferlan@redhat.com> References: <20170221163328.7070-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH REPOST v2 2/3] qemu: Use nodedev callback mechanism to to get a nodedev data 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: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Using the nodedev driver callback mechanism - allow qemu to be notified whenever a nodedev is added/removed. Keep track of the node devices in a hash table rather than requiring a connection in order to get specific information about a node device that qemu would eventually like to keep track of. Signed-off-by: John Ferlan --- src/qemu/qemu_conf.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++= ++ src/qemu/qemu_conf.h | 14 ++++++++++++++ src/qemu/qemu_driver.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index b5b0645..476179f 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1619,3 +1619,51 @@ qemuGetDomainHupageMemPath(const virDomainDef *def, =20 return 0; } + + +/** + * @driver: qemu driver pointer + * @def: Node device definition + * @enumeration: boolean for emumeration indication + * + * Taking the @def from the node device driver, add the device to + * the qemu node device hash table. The @enumeration is true when + * this callback is called from the node device enumeration and false + * when called when the @def was added to the node device. + * + * Returns -1 on failure, 0 on adding device name, 1 on already added name + */ +int +qemuNodeDeviceEntryAdd(virQEMUDriverPtr driver, + virNodeDeviceDefPtr def, + bool enumerate) +{ + VIR_DEBUG("Attempt to add name=3D'%s', parent=3D'%s' enumerate=3D%d", + def->name, def->parent, enumerate); + + if (!virHashLookup(driver->nodeDevices, def->name)) { + if (virHashAddEntry(driver->nodeDevices, def->name, NULL) < 0) + return -1; + return 0; + } + return 1; +} + + +/** + * @driver: qemu driver pointer + * @def: node device definition + * + * Remove the definition from qemu's node device hash table. + * + * Returns 0 on success, -1 on failure + */ +int +qemuNodeDeviceEntryRemove(virQEMUDriverPtr driver, + virNodeDeviceDefPtr def) +{ + VIR_DEBUG("Attempt to remove name=3D'%s' parent=3D'%s'", + def->name, def->parent); + + return virHashRemoveEntry(driver->nodeDevices, def->name); +} diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index e585f81..d47c9cc 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -32,6 +32,7 @@ # include "network_conf.h" # include "domain_conf.h" # include "snapshot_conf.h" +# include "node_device_conf.h" # include "domain_event.h" # include "virthread.h" # include "security/security_manager.h" @@ -255,6 +256,9 @@ struct _virQEMUDriver { virHashTablePtr sharedDevices; =20 /* Immutable pointer, self-locking APIs */ + virHashTablePtr nodeDevices; + + /* Immutable pointer, self-locking APIs */ virPortAllocatorPtr remotePorts; =20 /* Immutable pointer, self-locking APIs */ @@ -351,4 +355,14 @@ int qemuGetDomainHupageMemPath(const virDomainDef *def, virQEMUDriverConfigPtr cfg, unsigned long long pagesize, char **memPath); + +void qemuNodeDeviceEntryFree(void *payload, const void *name); + +int qemuNodeDeviceEntryAdd(virQEMUDriverPtr driver, + virNodeDeviceDefPtr def, + bool enumerate); + +int qemuNodeDeviceEntryRemove(virQEMUDriverPtr driver, + virNodeDeviceDefPtr def); + #endif /* __QEMUD_CONF_H */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6e1e3d4..546fea7 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -197,6 +197,28 @@ static virNWFilterCallbackDriver qemuCallbackDriver = =3D { }; =20 =20 +static int +qemuNodeDeviceAdd(virNodeDeviceDefPtr def, + bool enumerate) +{ + return qemuNodeDeviceEntryAdd(qemu_driver, def, enumerate); +} + + +static int +qemuNodeDeviceRemove(virNodeDeviceDefPtr def) +{ + return qemuNodeDeviceEntryRemove(qemu_driver, def); +} + + +static virNodeDeviceCallbackDriver qemuNodedevCallbackDriver =3D { + .name =3D QEMU_DRIVER_NAME, + .nodeDeviceAdd =3D qemuNodeDeviceAdd, + .nodeDeviceRemove =3D qemuNodeDeviceRemove, +}; + + struct qemuAutostartData { virQEMUDriverPtr driver; virConnectPtr conn; @@ -638,6 +660,7 @@ qemuStateInitialize(bool privileged, char *driverConf =3D NULL; virConnectPtr conn =3D NULL; virQEMUDriverConfigPtr cfg; + virNodedevEnumerateAddDevices nodedevEnumCb; uid_t run_uid =3D -1; gid_t run_gid =3D -1; char *hugepagePath =3D NULL; @@ -776,6 +799,23 @@ qemuStateInitialize(bool privileged, if (!(qemu_driver->sharedDevices =3D virHashCreate(30, qemuSharedDevic= eEntryFree))) goto error; =20 + /* Create a hash table to keep track of node device's by name */ + if (!(qemu_driver->nodeDevices =3D virHashCreate(100, NULL))) + goto error; + + /* Set up a callback mechanism with the node device conf code to get + * called whenever a node device is added or removed. */ + if (!(nodedevEnumCb =3D + virNodeDeviceRegisterCallbackDriver(&qemuNodedevCallbackDriver))) + goto error; + + /* Setting the add/remove callback first ensures that there is no + * window of opportunity for a device to be added after enumeration + * is complete, but before the callback is in place. So, set the + * callback first, then do the enumeration. */ + if (nodedevEnumCb(qemuNodeDeviceAdd) < 0) + goto error; + if (qemuMigrationErrorInit(qemu_driver) < 0) goto error; =20 @@ -1075,6 +1115,7 @@ qemuStateCleanup(void) return -1; =20 virNWFilterUnRegisterCallbackDriver(&qemuCallbackDriver); + virNodeDeviceUnregisterCallbackDriver(&qemuNodedevCallbackDriver); virThreadPoolFree(qemu_driver->workerPool); virObjectUnref(qemu_driver->config); virObjectUnref(qemu_driver->hostdevMgr); --=20 2.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri Apr 26 08:50:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.24 as permitted sender) client-ip=209.132.183.24; envelope-from=libvir-list-bounces@redhat.com; helo=mx3-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.24 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by mx.zohomail.com with SMTPS id 148769504550463.21903060664329; Tue, 21 Feb 2017 08:37:25 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1LGXfOQ003476; Tue, 21 Feb 2017 11:33:41 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1LGXWdj026500 for ; Tue, 21 Feb 2017 11:33:32 -0500 Received: from localhost.localdomain.com (ovpn-116-126.phx2.redhat.com [10.3.116.126]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1LGXUVV020390 for ; Tue, 21 Feb 2017 11:33:32 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Tue, 21 Feb 2017 11:33:28 -0500 Message-Id: <20170221163328.7070-4-jferlan@redhat.com> In-Reply-To: <20170221163328.7070-1-jferlan@redhat.com> References: <20170221163328.7070-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH REPOST v2 3/3] qemu: Add configuration variable to control nodedev enumeration 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: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add an 'enumerate_nodedev' qemu configuration variable to control whether the node device enumeration and add/remove event notification mechanism is enabled. This ensures only those environments that desire to utilize a domain vHBA need to have the (slight) overhead of adding the device hash table to qemu and managing add/remove events for specific scsi_host and scsi_target events. Signed-off-by: John Ferlan --- src/qemu/libvirtd_qemu.aug | 1 + src/qemu/qemu.conf | 19 +++++++++++++++++++ src/qemu/qemu_conf.c | 5 +++++ src/qemu/qemu_conf.h | 3 +++ src/qemu/qemu_driver.c | 33 +++++++++++++++++++-------------- src/qemu/test_libvirtd_qemu.aug.in | 1 + 6 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index 82bae9e..ef759ce 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -92,6 +92,7 @@ module Libvirtd_qemu =3D let device_entry =3D bool_entry "mac_filter" | bool_entry "relaxed_acs_check" | bool_entry "allow_disk_format_probing" + | bool_entry "nodedev_enumeration" | str_entry "lock_manager" =20 let rpc_entry =3D int_entry "max_queued" diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 9f990c2..712473e 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -531,6 +531,25 @@ #allow_disk_format_probing =3D 1 =20 =20 +# In order for a properly configured qemu domain to be able to passthrough +# NPIV vHBA LUN's to the guest qemu will need to enumerate all the node +# device's and then handle the add and remove events. In order to enable +# qemu to handle this, set this parameter to 1 and restart libvirtd. This +# enables communication between qemu and udev node device event management +# to provide the functionality. When a domain is started or reconnected +# with a vHBA controller configured in the domain XML or when a vHBA +# controller is hot-plugged, the qemu driver will handle the "scsi_hostN" +# device creation and removal events by hot-(un)plugging "scsi_targetB_T_L" +# (Bus, Target, Lun) Direct-Access LUNs to/from the guest. +# +# This is not required for qemu domain environments that utilize the Stora= ge +# Pool NPIV vHBA's to define LUNs in the domain XML. +# +# Defaults to 0. +# +#nodedev_enumeration =3D 1 + + # In order to prevent accidentally starting two domains that # share one writable disk, libvirt offers two approaches for # locking files. The first one is sanlock, the other one, diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 476179f..5f480d5 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -349,6 +349,8 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool priv= ileged) goto error; #endif =20 + cfg->nodeDeviceEnumeration =3D false; + return cfg; =20 error: @@ -712,6 +714,9 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr = cfg, goto cleanup; if (virConfGetValueBool(conf, "allow_disk_format_probing", &cfg->allow= DiskFormatProbing) < 0) goto cleanup; + if (virConfGetValueBool(conf, "nodedev_enumeration", + &cfg->nodeDeviceEnumeration) < 0) + goto cleanup; if (virConfGetValueBool(conf, "set_process_name", &cfg->setProcessName= ) < 0) goto cleanup; if (virConfGetValueUInt(conf, "max_processes", &cfg->maxProcesses) < 0) diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index d47c9cc..10ccb54 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -198,6 +198,9 @@ struct _virQEMUDriverConfig { unsigned int glusterDebugLevel; =20 char *memoryBackingDir; + + /* Node device enumeration enabled */ + bool nodeDeviceEnumeration; }; =20 /* Main driver state */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 546fea7..db0cf87 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -799,22 +799,27 @@ qemuStateInitialize(bool privileged, if (!(qemu_driver->sharedDevices =3D virHashCreate(30, qemuSharedDevic= eEntryFree))) goto error; =20 - /* Create a hash table to keep track of node device's by name */ - if (!(qemu_driver->nodeDevices =3D virHashCreate(100, NULL))) - goto error; + /* If node device enumeration is enabled, create a hash table to + * keep track of node device's by name and set up a callback mechanism + * with the node device conf code to get called whenever a node device + * is added or removed. */ + if (cfg->nodeDeviceEnumeration) { + if (!(qemu_driver->nodeDevices =3D virHashCreate(100, NULL))) + goto error; =20 - /* Set up a callback mechanism with the node device conf code to get - * called whenever a node device is added or removed. */ - if (!(nodedevEnumCb =3D - virNodeDeviceRegisterCallbackDriver(&qemuNodedevCallbackDriver))) - goto error; + /* Set up a callback mechanism with the node device conf code to g= et + * called whenever a node device is added or removed. */ + if (!(nodedevEnumCb =3D + virNodeDeviceRegisterCallbackDriver(&qemuNodedevCallbackDriv= er))) + goto error; =20 - /* Setting the add/remove callback first ensures that there is no - * window of opportunity for a device to be added after enumeration - * is complete, but before the callback is in place. So, set the - * callback first, then do the enumeration. */ - if (nodedevEnumCb(qemuNodeDeviceAdd) < 0) - goto error; + /* Setting the add/remove callback first ensures that there is no + * window of opportunity for a device to be added after enumeration + * is complete, but before the callback is in place. So, set the + * callback first, then do the enumeration. */ + if (nodedevEnumCb(qemuNodeDeviceAdd) < 0) + goto error; + } =20 if (qemuMigrationErrorInit(qemu_driver) < 0) goto error; diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qe= mu.aug.in index 6f03898..9b29fff 100644 --- a/src/qemu/test_libvirtd_qemu.aug.in +++ b/src/qemu/test_libvirtd_qemu.aug.in @@ -73,6 +73,7 @@ module Test_libvirtd_qemu =3D { "mac_filter" =3D "1" } { "relaxed_acs_check" =3D "1" } { "allow_disk_format_probing" =3D "1" } +{ "nodedev_enumeration" =3D "1" } { "lock_manager" =3D "lockd" } { "max_queued" =3D "0" } { "keepalive_interval" =3D "5" } --=20 2.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list