From nobody Wed May 14 19:06:00 2025 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 Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1517908541543876.3829259974133; Tue, 6 Feb 2018 01:15:41 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 843D4C00038E; Tue, 6 Feb 2018 09:15:40 +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 4C609381A9; Tue, 6 Feb 2018 09:15:40 +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 EF9BA4A46F; Tue, 6 Feb 2018 09:15:39 +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 w169DpZj023593 for ; Tue, 6 Feb 2018 04:13:51 -0500 Received: by smtp.corp.redhat.com (Postfix) id 63B4160C4D; Tue, 6 Feb 2018 09:13:51 +0000 (UTC) Received: from mx1.redhat.com (ext-mx01.extmail.prod.ext.phx2.redhat.com [10.5.110.25]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5BBB960BE0 for ; Tue, 6 Feb 2018 09:13:51 +0000 (UTC) Received: from new-relay.sw.ru (new-relay.sw.ru [195.214.232.40]) (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 910F56E76B for ; Tue, 6 Feb 2018 09:13:48 +0000 (UTC) Received: from msk-vpn.virtuozzo.com ([195.214.232.6] helo=dim-vz7.qa.sw.ru) by new-relay.sw.ru with esmtp (Exim 4.89) (envelope-from ) id 1eizJy-0006tL-19 for libvir-list@redhat.com; Tue, 06 Feb 2018 12:13:46 +0300 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Date: Tue, 6 Feb 2018 12:09:06 +0300 Message-Id: <1517908151-337420-2-git-send-email-nshirokovskiy@virtuozzo.com> In-Reply-To: <1517908151-337420-1-git-send-email-nshirokovskiy@virtuozzo.com> References: <1517908151-337420-1-git-send-email-nshirokovskiy@virtuozzo.com> X-Greylist: Sender passed SPF test, ACL 227 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 06 Feb 2018 09:13:49 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 06 Feb 2018 09:13:49 +0000 (UTC) for IP:'195.214.232.40' DOMAIN:'new-relay.sw.ru' HELO:'new-relay.sw.ru' FROM:'nshirokovskiy@virtuozzo.com' RCPT:'' X-RedHat-Spam-Score: -0.001 (SPF_PASS) 195.214.232.40 new-relay.sw.ru 195.214.232.40 new-relay.sw.ru X-Scanned-By: MIMEDefang 2.83 on 10.5.110.25 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2 1/6] port allocator: make used port bitmap global 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 06 Feb 2018 09:15:41 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Host tcp4/tcp6 ports is a global resource thus we need to make port accounting also global or we have issues described in [1] when port allocator ranges of different instances are overlapped (which is by default for qemu for example). Let's have only one global port allocator object that take care of the entire ports range (0 - 65535) and introduce port range object for clients to specify desired auto allocation band. [1] https://www.redhat.com/archives/libvir-list/2017-December/msg00600.html --- src/bhyve/bhyve_driver.c | 5 +- src/bhyve/bhyve_utils.h | 2 +- src/libvirt_private.syms | 3 +- src/libxl/libxl_conf.c | 8 +-- src/libxl/libxl_conf.h | 8 +-- src/libxl/libxl_driver.c | 18 ++--- src/qemu/qemu_conf.h | 6 +- src/qemu/qemu_driver.c | 30 ++++----- src/util/virportallocator.c | 149 ++++++++++++++++++++++++++++---------= ---- src/util/virportallocator.h | 21 +++--- tests/bhyvexml2argvtest.c | 15 ++++- tests/libxlxml2domconfigtest.c | 17 +++-- tests/virportallocatortest.c | 52 ++++++++------ 13 files changed, 213 insertions(+), 121 deletions(-) diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index dd6e8ab..913c7b1 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -1220,7 +1220,7 @@ bhyveStateCleanup(void) virObjectUnref(bhyve_driver->closeCallbacks); virObjectUnref(bhyve_driver->domainEventState); virObjectUnref(bhyve_driver->config); - virObjectUnref(bhyve_driver->remotePorts); + virPortAllocatorRangeFree(bhyve_driver->remotePorts); =20 virMutexDestroy(&bhyve_driver->lock); VIR_FREE(bhyve_driver); @@ -1267,7 +1267,8 @@ bhyveStateInitialize(bool privileged, if (!(bhyve_driver->domainEventState =3D virObjectEventStateNew())) goto cleanup; =20 - if (!(bhyve_driver->remotePorts =3D virPortAllocatorNew(_("display"), = 5900, 65535, 0))) + if (!(bhyve_driver->remotePorts =3D virPortAllocatorRangeNew(_("displa= y"), + 5900, 65535= , 0))) goto cleanup; =20 bhyve_driver->hostsysinfo =3D virSysinfoRead(); diff --git a/src/bhyve/bhyve_utils.h b/src/bhyve/bhyve_utils.h index 8ad2698..d6fb676 100644 --- a/src/bhyve/bhyve_utils.h +++ b/src/bhyve/bhyve_utils.h @@ -59,7 +59,7 @@ struct _bhyveConn { =20 virCloseCallbacksPtr closeCallbacks; =20 - virPortAllocatorPtr remotePorts; + virPortAllocatorRangePtr remotePorts; =20 unsigned bhyvecaps; unsigned grubcaps; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0bce0bb..63a7e2c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2517,7 +2517,8 @@ virPolkitCheckAuth; =20 # util/virportallocator.h virPortAllocatorAcquire; -virPortAllocatorNew; +virPortAllocatorRangeFree; +virPortAllocatorRangeNew; virPortAllocatorRelease; virPortAllocatorSetUsed; =20 diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 970cff2..9184f2c 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -1287,7 +1287,7 @@ libxlMakeNicList(virDomainDefPtr def, libxl_domain_c= onfig *d_config) } =20 int -libxlMakeVfb(virPortAllocatorPtr graphicsports, +libxlMakeVfb(virPortAllocatorRangePtr graphicsports, virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb) { @@ -1348,7 +1348,7 @@ libxlMakeVfb(virPortAllocatorPtr graphicsports, } =20 static int -libxlMakeVfbList(virPortAllocatorPtr graphicsports, +libxlMakeVfbList(virPortAllocatorRangePtr graphicsports, virDomainDefPtr def, libxl_domain_config *d_config) { @@ -1397,7 +1397,7 @@ libxlMakeVfbList(virPortAllocatorPtr graphicsports, * populate libxl_domain_config->vfbs. */ static int -libxlMakeBuildInfoVfb(virPortAllocatorPtr graphicsports, +libxlMakeBuildInfoVfb(virPortAllocatorRangePtr graphicsports, virDomainDefPtr def, libxl_domain_config *d_config) { @@ -2284,7 +2284,7 @@ libxlDriverNodeGetInfo(libxlDriverPrivatePtr driver, = virNodeInfoPtr info) } =20 int -libxlBuildDomainConfig(virPortAllocatorPtr graphicsports, +libxlBuildDomainConfig(virPortAllocatorRangePtr graphicsports, virDomainDefPtr def, const char *channelDir LIBXL_ATTR_UNUSED, libxl_ctx *ctx, diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h index 264df11..ee09b7e 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -131,10 +131,10 @@ struct _libxlDriverPrivate { virObjectEventStatePtr domainEventState; =20 /* Immutable pointer, self-locking APIs */ - virPortAllocatorPtr reservedGraphicsPorts; + virPortAllocatorRangePtr reservedGraphicsPorts; =20 /* Immutable pointer, self-locking APIs */ - virPortAllocatorPtr migrationPorts; + virPortAllocatorRangePtr migrationPorts; =20 /* Immutable pointer, lockless APIs*/ virSysinfoDefPtr hostsysinfo; @@ -189,7 +189,7 @@ libxlMakeNic(virDomainDefPtr def, libxl_device_nic *x_nic, bool attach); int -libxlMakeVfb(virPortAllocatorPtr graphicsports, +libxlMakeVfb(virPortAllocatorRangePtr graphicsports, virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb); =20 int @@ -213,7 +213,7 @@ libxlCreateXMLConf(void); # define LIBXL_ATTR_UNUSED ATTRIBUTE_UNUSED # endif int -libxlBuildDomainConfig(virPortAllocatorPtr graphicsports, +libxlBuildDomainConfig(virPortAllocatorRangePtr graphicsports, virDomainDefPtr def, const char *channelDir LIBXL_ATTR_UNUSED, libxl_ctx *ctx, diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 79e29ce..5da9378 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -477,8 +477,8 @@ libxlStateCleanup(void) virObjectUnref(libxl_driver->config); virObjectUnref(libxl_driver->xmlopt); virObjectUnref(libxl_driver->domains); - virObjectUnref(libxl_driver->reservedGraphicsPorts); - virObjectUnref(libxl_driver->migrationPorts); + virPortAllocatorRangeFree(libxl_driver->reservedGraphicsPorts); + virPortAllocatorRangeFree(libxl_driver->migrationPorts); virLockManagerPluginUnref(libxl_driver->lockManager); =20 virObjectUnref(libxl_driver->domainEventState); @@ -657,17 +657,17 @@ libxlStateInitialize(bool privileged, =20 /* Allocate bitmap for vnc port reservation */ if (!(libxl_driver->reservedGraphicsPorts =3D - virPortAllocatorNew(_("VNC"), - LIBXL_VNC_PORT_MIN, - LIBXL_VNC_PORT_MAX, - 0))) + virPortAllocatorRangeNew(_("VNC"), + LIBXL_VNC_PORT_MIN, + LIBXL_VNC_PORT_MAX, + 0))) goto error; =20 /* Allocate bitmap for migration port reservation */ if (!(libxl_driver->migrationPorts =3D - virPortAllocatorNew(_("migration"), - LIBXL_MIGRATION_PORT_MIN, - LIBXL_MIGRATION_PORT_MAX, 0))) + virPortAllocatorRangeNew(_("migration"), + LIBXL_MIGRATION_PORT_MIN, + LIBXL_MIGRATION_PORT_MAX, 0))) goto error; =20 if (!(libxl_driver->domains =3D virDomainObjListNew())) diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 3f38a76..1640fa9 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -267,13 +267,13 @@ struct _virQEMUDriver { virHashTablePtr sharedDevices; =20 /* Immutable pointer, self-locking APIs */ - virPortAllocatorPtr remotePorts; + virPortAllocatorRangePtr remotePorts; =20 /* Immutable pointer, self-locking APIs */ - virPortAllocatorPtr webSocketPorts; + virPortAllocatorRangePtr webSocketPorts; =20 /* Immutable pointer, self-locking APIs */ - virPortAllocatorPtr migrationPorts; + virPortAllocatorRangePtr migrationPorts; =20 /* Immutable pointer, lockless APIs*/ virSysinfoDefPtr hostsysinfo; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index d7ac311..9f0bab5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -748,24 +748,24 @@ qemuStateInitialize(bool privileged, * do this before the config is loaded properly, since the port * numbers are configurable now */ if ((qemu_driver->remotePorts =3D - virPortAllocatorNew(_("display"), - cfg->remotePortMin, - cfg->remotePortMax, - 0)) =3D=3D NULL) + virPortAllocatorRangeNew(_("display"), + cfg->remotePortMin, + cfg->remotePortMax, + 0)) =3D=3D NULL) goto error; =20 if ((qemu_driver->webSocketPorts =3D - virPortAllocatorNew(_("webSocket"), - cfg->webSocketPortMin, - cfg->webSocketPortMax, - 0)) =3D=3D NULL) + virPortAllocatorRangeNew(_("webSocket"), + cfg->webSocketPortMin, + cfg->webSocketPortMax, + 0)) =3D=3D NULL) goto error; =20 if ((qemu_driver->migrationPorts =3D - virPortAllocatorNew(_("migration"), - cfg->migrationPortMin, - cfg->migrationPortMax, - 0)) =3D=3D NULL) + virPortAllocatorRangeNew(_("migration"), + cfg->migrationPortMin, + cfg->migrationPortMax, + 0)) =3D=3D NULL) goto error; =20 if (qemuSecurityInit(qemu_driver) < 0) @@ -1113,9 +1113,9 @@ qemuStateCleanup(void) virObjectUnref(qemu_driver->qemuCapsCache); =20 virObjectUnref(qemu_driver->domains); - virObjectUnref(qemu_driver->remotePorts); - virObjectUnref(qemu_driver->webSocketPorts); - virObjectUnref(qemu_driver->migrationPorts); + virPortAllocatorRangeFree(qemu_driver->remotePorts); + virPortAllocatorRangeFree(qemu_driver->webSocketPorts); + virPortAllocatorRangeFree(qemu_driver->migrationPorts); virObjectUnref(qemu_driver->migrationErrors); =20 virObjectUnref(qemu_driver->xmlopt); diff --git a/src/util/virportallocator.c b/src/util/virportallocator.c index fcd4f74..be29e97 100644 --- a/src/util/virportallocator.c +++ b/src/util/virportallocator.c @@ -35,10 +35,14 @@ =20 #define VIR_FROM_THIS VIR_FROM_NONE =20 +typedef struct _virPortAllocator virPortAllocator; +typedef virPortAllocator *virPortAllocatorPtr; struct _virPortAllocator { virObjectLockable parent; virBitmapPtr bitmap; +}; =20 +struct _virPortAllocatorRange { char *name; =20 unsigned short start; @@ -48,6 +52,7 @@ struct _virPortAllocator { }; =20 static virClassPtr virPortAllocatorClass; +static virPortAllocatorPtr virPortAllocatorInstance; =20 static void virPortAllocatorDispose(void *obj) @@ -55,10 +60,27 @@ virPortAllocatorDispose(void *obj) virPortAllocatorPtr pa =3D obj; =20 virBitmapFree(pa->bitmap); - VIR_FREE(pa->name); } =20 -static int virPortAllocatorOnceInit(void) +static virPortAllocatorPtr +virPortAllocatorNew(void) +{ + virPortAllocatorPtr pa; + + if (!(pa =3D virObjectLockableNew(virPortAllocatorClass))) + return NULL; + + if (!(pa->bitmap =3D virBitmapNew(USHRT_MAX))) + goto error; + + return pa; + error: + virObjectUnref(pa); + return NULL; +} + +static int +virPortAllocatorOnceInit(void) { if (!(virPortAllocatorClass =3D virClassNew(virClassForObjectLockable(= ), "virPortAllocator", @@ -66,17 +88,21 @@ static int virPortAllocatorOnceInit(void) virPortAllocatorDispose))) return -1; =20 + if (!(virPortAllocatorInstance =3D virPortAllocatorNew())) + return -1; + return 0; } =20 VIR_ONCE_GLOBAL_INIT(virPortAllocator) =20 -virPortAllocatorPtr virPortAllocatorNew(const char *name, - unsigned short start, - unsigned short end, - unsigned int flags) +virPortAllocatorRangePtr +virPortAllocatorRangeNew(const char *name, + unsigned short start, + unsigned short end, + unsigned int flags) { - virPortAllocatorPtr pa; + virPortAllocatorRangePtr range; =20 if (start >=3D end) { virReportInvalidArg(start, "start port %d must be less than end po= rt %d", @@ -84,28 +110,37 @@ virPortAllocatorPtr virPortAllocatorNew(const char *na= me, return NULL; } =20 - if (virPortAllocatorInitialize() < 0) + if (VIR_ALLOC(range) < 0) return NULL; =20 - if (!(pa =3D virObjectLockableNew(virPortAllocatorClass))) - return NULL; + range->flags =3D flags; + range->start =3D start; + range->end =3D end; =20 - pa->flags =3D flags; - pa->start =3D start; - pa->end =3D end; + if (VIR_STRDUP(range->name, name) < 0) + goto error; =20 - if (!(pa->bitmap =3D virBitmapNew((end-start)+1)) || - VIR_STRDUP(pa->name, name) < 0) { - virObjectUnref(pa); - return NULL; - } + return range; + + error: + virPortAllocatorRangeFree(range); + return NULL; +} + +void +virPortAllocatorRangeFree(virPortAllocatorRangePtr range) +{ + if (!range) + return; =20 - return pa; + VIR_FREE(range->name); + VIR_FREE(range); } =20 -static int virPortAllocatorBindToPort(bool *used, - unsigned short port, - int family) +static int +virPortAllocatorBindToPort(bool *used, + unsigned short port, + int family) { struct sockaddr_in6 addr6 =3D { .sin6_family =3D AF_INET6, @@ -172,22 +207,37 @@ static int virPortAllocatorBindToPort(bool *used, return ret; } =20 -int virPortAllocatorAcquire(virPortAllocatorPtr pa, - unsigned short *port) +static virPortAllocatorPtr +virPortAllocatorGet(void) +{ + if (virPortAllocatorInitialize() < 0) + return NULL; + + return virPortAllocatorInstance; +} + +int +virPortAllocatorAcquire(virPortAllocatorRangePtr range, + unsigned short *port) { int ret =3D -1; size_t i; + virPortAllocatorPtr pa =3D virPortAllocatorGet(); =20 *port =3D 0; + + if (!pa) + return -1; + virObjectLock(pa); =20 - for (i =3D pa->start; i <=3D pa->end && !*port; i++) { + for (i =3D range->start; i <=3D range->end && !*port; i++) { bool used =3D false, v6used =3D false; =20 - if (virBitmapIsBitSet(pa->bitmap, i - pa->start)) + if (virBitmapIsBitSet(pa->bitmap, i)) continue; =20 - if (!(pa->flags & VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)) { + if (!(range->flags & VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)) { if (virPortAllocatorBindToPort(&v6used, i, AF_INET6) < 0 || virPortAllocatorBindToPort(&used, i, AF_INET) < 0) goto cleanup; @@ -195,8 +245,7 @@ int virPortAllocatorAcquire(virPortAllocatorPtr pa, =20 if (!used && !v6used) { /* Add port to bitmap of reserved ports */ - if (virBitmapSetBit(pa->bitmap, - i - pa->start) < 0) { + if (virBitmapSetBit(pa->bitmap, i) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to reserve port %zu"), i); goto cleanup; @@ -209,32 +258,36 @@ int virPortAllocatorAcquire(virPortAllocatorPtr pa, if (*port =3D=3D 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to find an unused port in range '%s' (%d-= %d)"), - pa->name, pa->start, pa->end); + range->name, range->start, range->end); } cleanup: virObjectUnlock(pa); return ret; } =20 -int virPortAllocatorRelease(virPortAllocatorPtr pa, - unsigned short port) +int +virPortAllocatorRelease(virPortAllocatorRangePtr range, + unsigned short port) { int ret =3D -1; + virPortAllocatorPtr pa =3D virPortAllocatorGet(); + + if (!pa) + return -1; =20 if (!port) return 0; =20 virObjectLock(pa); =20 - if (port < pa->start || - port > pa->end) { + if (port < range->start || + port > range->end) { virReportInvalidArg(port, "port %d must be in range (%d, %d)", - port, pa->start, pa->end); + port, range->start, range->end); goto cleanup; } =20 - if (virBitmapClearBit(pa->bitmap, - port - pa->start) < 0) { + if (virBitmapClearBit(pa->bitmap, port) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to release port %d"), port); @@ -247,30 +300,34 @@ int virPortAllocatorRelease(virPortAllocatorPtr pa, return ret; } =20 -int virPortAllocatorSetUsed(virPortAllocatorPtr pa, - unsigned short port, - bool value) +int +virPortAllocatorSetUsed(virPortAllocatorRangePtr range, + unsigned short port, + bool value) { int ret =3D -1; + virPortAllocatorPtr pa =3D virPortAllocatorGet(); + + if (!pa) + return -1; =20 virObjectLock(pa); =20 - if (port < pa->start || - port > pa->end) { + if (port < range->start || + port > range->end) { ret =3D 0; goto cleanup; } =20 if (value) { - if (virBitmapIsBitSet(pa->bitmap, port - pa->start) || - virBitmapSetBit(pa->bitmap, port - pa->start) < 0) { + if (virBitmapIsBitSet(pa->bitmap, port) || + virBitmapSetBit(pa->bitmap, port) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to reserve port %d"), port); goto cleanup; } } else { - if (virBitmapClearBit(pa->bitmap, - port - pa->start) < 0) { + if (virBitmapClearBit(pa->bitmap, port) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to release port %d"), port); diff --git a/src/util/virportallocator.h b/src/util/virportallocator.h index 14c3b24..fb38c33 100644 --- a/src/util/virportallocator.h +++ b/src/util/virportallocator.h @@ -25,25 +25,28 @@ # include "internal.h" # include "virobject.h" =20 -typedef struct _virPortAllocator virPortAllocator; -typedef virPortAllocator *virPortAllocatorPtr; +typedef struct _virPortAllocatorRange virPortAllocatorRange; +typedef virPortAllocatorRange *virPortAllocatorRangePtr; =20 typedef enum { VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK =3D (1 << 0), } virPortAllocatorFlags; =20 -virPortAllocatorPtr virPortAllocatorNew(const char *name, - unsigned short start, - unsigned short end, - unsigned int flags); +virPortAllocatorRangePtr +virPortAllocatorRangeNew(const char *name, + unsigned short start, + unsigned short end, + unsigned int flags); =20 -int virPortAllocatorAcquire(virPortAllocatorPtr pa, +void virPortAllocatorRangeFree(virPortAllocatorRangePtr range); + +int virPortAllocatorAcquire(virPortAllocatorRangePtr range, unsigned short *port); =20 -int virPortAllocatorRelease(virPortAllocatorPtr pa, +int virPortAllocatorRelease(virPortAllocatorRangePtr range, unsigned short port); =20 -int virPortAllocatorSetUsed(virPortAllocatorPtr pa, +int virPortAllocatorSetUsed(virPortAllocatorRangePtr range, unsigned short port, bool value); =20 diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c index 8128589..47ea85b 100644 --- a/tests/bhyvexml2argvtest.c +++ b/tests/bhyvexml2argvtest.c @@ -91,6 +91,15 @@ static int testCompareXMLToArgvFiles(const char *xml, ret =3D 0; =20 out: + if (vmdef && + vmdef->ngraphics =3D=3D 1 && + vmdef->graphics[0]->type =3D=3D VIR_DOMAIN_GRAPHICS_TYPE_VNC) { + if (vmdef->graphics[0]->data.vnc.autoport) + virPortAllocatorRelease(gports, vmdef->graphics[0]->data.vnc.p= ort); + else + virPortAllocatorSetUsed(gports, vmdef->graphics[0]->data.vnc.p= ort, false); + } + VIR_FREE(actualargv); VIR_FREE(actualld); VIR_FREE(actualdm); @@ -145,8 +154,8 @@ mymain(void) if ((driver.xmlopt =3D virBhyveDriverCreateXMLConf(&driver)) =3D=3D NU= LL) return EXIT_FAILURE; =20 - if (!(driver.remotePorts =3D virPortAllocatorNew("display", 5900, 6553= 5, - VIR_PORT_ALLOCATOR_SKIP= _BIND_CHECK))) + if (!(driver.remotePorts =3D virPortAllocatorRangeNew("display", 5900,= 65535, + VIR_PORT_ALLOCATOR= _SKIP_BIND_CHECK))) return EXIT_FAILURE; =20 =20 @@ -240,7 +249,7 @@ mymain(void) =20 virObjectUnref(driver.caps); virObjectUnref(driver.xmlopt); - virObjectUnref(driver.remotePorts); + virPortAllocatorRangeFree(driver.remotePorts); =20 return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/libxlxml2domconfigtest.c b/tests/libxlxml2domconfigtest.c index bd4c3af..0512297 100644 --- a/tests/libxlxml2domconfigtest.c +++ b/tests/libxlxml2domconfigtest.c @@ -58,7 +58,7 @@ testCompareXMLToDomConfig(const char *xmlfile, libxl_domain_config expectconfig; xentoollog_logger *log =3D NULL; libxl_ctx *ctx =3D NULL; - virPortAllocatorPtr gports =3D NULL; + virPortAllocatorRangePtr gports =3D NULL; virDomainXMLOptionPtr xmlopt =3D NULL; virDomainDefPtr vmdef =3D NULL; char *actualjson =3D NULL; @@ -74,8 +74,8 @@ testCompareXMLToDomConfig(const char *xmlfile, if (libxl_ctx_alloc(&ctx, LIBXL_VERSION, 0, log) < 0) goto cleanup; =20 - if (!(gports =3D virPortAllocatorNew("vnc", 5900, 6000, - VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)= )) + if (!(gports =3D virPortAllocatorRangeNew("vnc", 5900, 6000, + VIR_PORT_ALLOCATOR_SKIP_BIND_C= HECK))) goto cleanup; =20 if (!(xmlopt =3D libxlCreateXMLConf())) @@ -112,11 +112,20 @@ testCompareXMLToDomConfig(const char *xmlfile, ret =3D 0; =20 cleanup: + if (vmdef && + vmdef->ngraphics =3D=3D 1 && + vmdef->graphics[0]->type =3D=3D VIR_DOMAIN_GRAPHICS_TYPE_VNC) { + if (vmdef->graphics[0]->data.vnc.autoport) + virPortAllocatorRelease(gports, vmdef->graphics[0]->data.vnc.p= ort); + else + virPortAllocatorSetUsed(gports, vmdef->graphics[0]->data.vnc.p= ort, false); + } + VIR_FREE(expectjson); VIR_FREE(actualjson); VIR_FREE(tempjson); virDomainDefFree(vmdef); - virObjectUnref(gports); + virPortAllocatorRangeFree(gports); virObjectUnref(xmlopt); libxl_ctx_free(ctx); libxl_domain_config_dispose(&actualconfig); diff --git a/tests/virportallocatortest.c b/tests/virportallocatortest.c index ed9c4f2..0a967d1 100644 --- a/tests/virportallocatortest.c +++ b/tests/virportallocatortest.c @@ -42,63 +42,71 @@ VIR_LOG_INIT("tests.portallocatortest"); =20 static int testAllocAll(const void *args ATTRIBUTE_UNUSED) { - virPortAllocatorPtr alloc =3D virPortAllocatorNew("test", 5900, 5909, = 0); + virPortAllocatorRangePtr ports =3D virPortAllocatorRangeNew("test", 59= 00, 5909, 0); int ret =3D -1; - unsigned short p1, p2, p3, p4, p5, p6, p7; + unsigned short p1 =3D 0, p2 =3D 0, p3 =3D 0, p4 =3D 0, p5 =3D 0, p6 = =3D 0, p7 =3D 0; =20 - if (!alloc) + if (!ports) return -1; =20 - if (virPortAllocatorAcquire(alloc, &p1) < 0) + if (virPortAllocatorAcquire(ports, &p1) < 0) goto cleanup; if (p1 !=3D 5901) { VIR_TEST_DEBUG("Expected 5901, got %d", p1); goto cleanup; } =20 - if (virPortAllocatorAcquire(alloc, &p2) < 0) + if (virPortAllocatorAcquire(ports, &p2) < 0) goto cleanup; if (p2 !=3D 5902) { VIR_TEST_DEBUG("Expected 5902, got %d", p2); goto cleanup; } =20 - if (virPortAllocatorAcquire(alloc, &p3) < 0) + if (virPortAllocatorAcquire(ports, &p3) < 0) goto cleanup; if (p3 !=3D 5903) { VIR_TEST_DEBUG("Expected 5903, got %d", p3); goto cleanup; } =20 - if (virPortAllocatorAcquire(alloc, &p4) < 0) + if (virPortAllocatorAcquire(ports, &p4) < 0) goto cleanup; if (p4 !=3D 5907) { VIR_TEST_DEBUG("Expected 5907, got %d", p4); goto cleanup; } =20 - if (virPortAllocatorAcquire(alloc, &p5) < 0) + if (virPortAllocatorAcquire(ports, &p5) < 0) goto cleanup; if (p5 !=3D 5908) { VIR_TEST_DEBUG("Expected 5908, got %d", p5); goto cleanup; } =20 - if (virPortAllocatorAcquire(alloc, &p6) < 0) + if (virPortAllocatorAcquire(ports, &p6) < 0) goto cleanup; if (p6 !=3D 5909) { VIR_TEST_DEBUG("Expected 5909, got %d", p6); goto cleanup; } =20 - if (virPortAllocatorAcquire(alloc, &p7) =3D=3D 0) { + if (virPortAllocatorAcquire(ports, &p7) =3D=3D 0) { VIR_TEST_DEBUG("Expected error, got %d", p7); goto cleanup; } =20 ret =3D 0; cleanup: - virObjectUnref(alloc); + virPortAllocatorRelease(ports, p1); + virPortAllocatorRelease(ports, p2); + virPortAllocatorRelease(ports, p3); + virPortAllocatorRelease(ports, p4); + virPortAllocatorRelease(ports, p5); + virPortAllocatorRelease(ports, p6); + virPortAllocatorRelease(ports, p7); + + virPortAllocatorRangeFree(ports); return ret; } =20 @@ -106,28 +114,28 @@ static int testAllocAll(const void *args ATTRIBUTE_UN= USED) =20 static int testAllocReuse(const void *args ATTRIBUTE_UNUSED) { - virPortAllocatorPtr alloc =3D virPortAllocatorNew("test", 5900, 5910, = 0); + virPortAllocatorRangePtr ports =3D virPortAllocatorRangeNew("test", 59= 00, 5910, 0); int ret =3D -1; - unsigned short p1, p2, p3, p4; + unsigned short p1 =3D 0, p2 =3D 0, p3 =3D 0, p4 =3D 0; =20 - if (!alloc) + if (!ports) return -1; =20 - if (virPortAllocatorAcquire(alloc, &p1) < 0) + if (virPortAllocatorAcquire(ports, &p1) < 0) goto cleanup; if (p1 !=3D 5901) { VIR_TEST_DEBUG("Expected 5901, got %d", p1); goto cleanup; } =20 - if (virPortAllocatorAcquire(alloc, &p2) < 0) + if (virPortAllocatorAcquire(ports, &p2) < 0) goto cleanup; if (p2 !=3D 5902) { VIR_TEST_DEBUG("Expected 5902, got %d", p2); goto cleanup; } =20 - if (virPortAllocatorAcquire(alloc, &p3) < 0) + if (virPortAllocatorAcquire(ports, &p3) < 0) goto cleanup; if (p3 !=3D 5903) { VIR_TEST_DEBUG("Expected 5903, got %d", p3); @@ -135,10 +143,10 @@ static int testAllocReuse(const void *args ATTRIBUTE_= UNUSED) } =20 =20 - if (virPortAllocatorRelease(alloc, p2) < 0) + if (virPortAllocatorRelease(ports, p2) < 0) goto cleanup; =20 - if (virPortAllocatorAcquire(alloc, &p4) < 0) + if (virPortAllocatorAcquire(ports, &p4) < 0) goto cleanup; if (p4 !=3D 5902) { VIR_TEST_DEBUG("Expected 5902, got %d", p4); @@ -147,7 +155,11 @@ static int testAllocReuse(const void *args ATTRIBUTE_U= NUSED) =20 ret =3D 0; cleanup: - virObjectUnref(alloc); + virPortAllocatorRelease(ports, p1); + virPortAllocatorRelease(ports, p3); + virPortAllocatorRelease(ports, p4); + + virPortAllocatorRangeFree(ports); return ret; } =20 --=20 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list