port allocator: make used port bitmap global

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

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
This commit is contained in:
Nikolay Shirokovskiy 2018-02-06 12:09:06 +03:00 committed by Michal Privoznik
parent 5590122937
commit 7ebc4f2a4c
13 changed files with 213 additions and 121 deletions

View File

@ -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);
virMutexDestroy(&bhyve_driver->lock);
VIR_FREE(bhyve_driver);
@ -1267,7 +1267,8 @@ bhyveStateInitialize(bool privileged,
if (!(bhyve_driver->domainEventState = virObjectEventStateNew()))
goto cleanup;
if (!(bhyve_driver->remotePorts = virPortAllocatorNew(_("display"), 5900, 65535, 0)))
if (!(bhyve_driver->remotePorts = virPortAllocatorRangeNew(_("display"),
5900, 65535, 0)))
goto cleanup;
bhyve_driver->hostsysinfo = virSysinfoRead();

View File

@ -59,7 +59,7 @@ struct _bhyveConn {
virCloseCallbacksPtr closeCallbacks;
virPortAllocatorPtr remotePorts;
virPortAllocatorRangePtr remotePorts;
unsigned bhyvecaps;
unsigned grubcaps;

View File

@ -2535,7 +2535,8 @@ virPolkitCheckAuth;
# util/virportallocator.h
virPortAllocatorAcquire;
virPortAllocatorNew;
virPortAllocatorRangeFree;
virPortAllocatorRangeNew;
virPortAllocatorRelease;
virPortAllocatorSetUsed;

View File

@ -1316,7 +1316,7 @@ libxlMakeNicList(virDomainDefPtr def, libxl_domain_config *d_config)
}
int
libxlMakeVfb(virPortAllocatorPtr graphicsports,
libxlMakeVfb(virPortAllocatorRangePtr graphicsports,
virDomainGraphicsDefPtr l_vfb,
libxl_device_vfb *x_vfb)
{
@ -1377,7 +1377,7 @@ libxlMakeVfb(virPortAllocatorPtr graphicsports,
}
static int
libxlMakeVfbList(virPortAllocatorPtr graphicsports,
libxlMakeVfbList(virPortAllocatorRangePtr graphicsports,
virDomainDefPtr def,
libxl_domain_config *d_config)
{
@ -1426,7 +1426,7 @@ libxlMakeVfbList(virPortAllocatorPtr graphicsports,
* populate libxl_domain_config->vfbs.
*/
static int
libxlMakeBuildInfoVfb(virPortAllocatorPtr graphicsports,
libxlMakeBuildInfoVfb(virPortAllocatorRangePtr graphicsports,
virDomainDefPtr def,
libxl_domain_config *d_config)
{
@ -2313,7 +2313,7 @@ libxlDriverNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info)
}
int
libxlBuildDomainConfig(virPortAllocatorPtr graphicsports,
libxlBuildDomainConfig(virPortAllocatorRangePtr graphicsports,
virDomainDefPtr def,
const char *channelDir LIBXL_ATTR_UNUSED,
libxl_ctx *ctx,

View File

@ -131,10 +131,10 @@ struct _libxlDriverPrivate {
virObjectEventStatePtr domainEventState;
/* Immutable pointer, self-locking APIs */
virPortAllocatorPtr reservedGraphicsPorts;
virPortAllocatorRangePtr reservedGraphicsPorts;
/* Immutable pointer, self-locking APIs */
virPortAllocatorPtr migrationPorts;
virPortAllocatorRangePtr migrationPorts;
/* 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);
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,

View File

@ -476,8 +476,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);
virObjectUnref(libxl_driver->domainEventState);
@ -656,17 +656,17 @@ libxlStateInitialize(bool privileged,
/* Allocate bitmap for vnc port reservation */
if (!(libxl_driver->reservedGraphicsPorts =
virPortAllocatorNew(_("VNC"),
LIBXL_VNC_PORT_MIN,
LIBXL_VNC_PORT_MAX,
0)))
virPortAllocatorRangeNew(_("VNC"),
LIBXL_VNC_PORT_MIN,
LIBXL_VNC_PORT_MAX,
0)))
goto error;
/* Allocate bitmap for migration port reservation */
if (!(libxl_driver->migrationPorts =
virPortAllocatorNew(_("migration"),
LIBXL_MIGRATION_PORT_MIN,
LIBXL_MIGRATION_PORT_MAX, 0)))
virPortAllocatorRangeNew(_("migration"),
LIBXL_MIGRATION_PORT_MIN,
LIBXL_MIGRATION_PORT_MAX, 0)))
goto error;
if (!(libxl_driver->domains = virDomainObjListNew()))

View File

@ -264,13 +264,13 @@ struct _virQEMUDriver {
virHashTablePtr sharedDevices;
/* Immutable pointer, self-locking APIs */
virPortAllocatorPtr remotePorts;
virPortAllocatorRangePtr remotePorts;
/* Immutable pointer, self-locking APIs */
virPortAllocatorPtr webSocketPorts;
virPortAllocatorRangePtr webSocketPorts;
/* Immutable pointer, self-locking APIs */
virPortAllocatorPtr migrationPorts;
virPortAllocatorRangePtr migrationPorts;
/* Immutable pointer, lockless APIs*/
virSysinfoDefPtr hostsysinfo;

View File

@ -725,24 +725,24 @@ qemuStateInitialize(bool privileged,
* do this before the config is loaded properly, since the port
* numbers are configurable now */
if ((qemu_driver->remotePorts =
virPortAllocatorNew(_("display"),
cfg->remotePortMin,
cfg->remotePortMax,
0)) == NULL)
virPortAllocatorRangeNew(_("display"),
cfg->remotePortMin,
cfg->remotePortMax,
0)) == NULL)
goto error;
if ((qemu_driver->webSocketPorts =
virPortAllocatorNew(_("webSocket"),
cfg->webSocketPortMin,
cfg->webSocketPortMax,
0)) == NULL)
virPortAllocatorRangeNew(_("webSocket"),
cfg->webSocketPortMin,
cfg->webSocketPortMax,
0)) == NULL)
goto error;
if ((qemu_driver->migrationPorts =
virPortAllocatorNew(_("migration"),
cfg->migrationPortMin,
cfg->migrationPortMax,
0)) == NULL)
virPortAllocatorRangeNew(_("migration"),
cfg->migrationPortMin,
cfg->migrationPortMax,
0)) == NULL)
goto error;
if (qemuSecurityInit(qemu_driver) < 0)
@ -1085,9 +1085,9 @@ qemuStateCleanup(void)
virObjectUnref(qemu_driver->qemuCapsCache);
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);
virObjectUnref(qemu_driver->xmlopt);

View File

@ -35,10 +35,14 @@
#define VIR_FROM_THIS VIR_FROM_NONE
typedef struct _virPortAllocator virPortAllocator;
typedef virPortAllocator *virPortAllocatorPtr;
struct _virPortAllocator {
virObjectLockable parent;
virBitmapPtr bitmap;
};
struct _virPortAllocatorRange {
char *name;
unsigned short start;
@ -48,6 +52,7 @@ struct _virPortAllocator {
};
static virClassPtr virPortAllocatorClass;
static virPortAllocatorPtr virPortAllocatorInstance;
static void
virPortAllocatorDispose(void *obj)
@ -55,10 +60,27 @@ virPortAllocatorDispose(void *obj)
virPortAllocatorPtr pa = obj;
virBitmapFree(pa->bitmap);
VIR_FREE(pa->name);
}
static int virPortAllocatorOnceInit(void)
static virPortAllocatorPtr
virPortAllocatorNew(void)
{
virPortAllocatorPtr pa;
if (!(pa = virObjectLockableNew(virPortAllocatorClass)))
return NULL;
if (!(pa->bitmap = virBitmapNew(USHRT_MAX)))
goto error;
return pa;
error:
virObjectUnref(pa);
return NULL;
}
static int
virPortAllocatorOnceInit(void)
{
if (!(virPortAllocatorClass = virClassNew(virClassForObjectLockable(),
"virPortAllocator",
@ -66,17 +88,21 @@ static int virPortAllocatorOnceInit(void)
virPortAllocatorDispose)))
return -1;
if (!(virPortAllocatorInstance = virPortAllocatorNew()))
return -1;
return 0;
}
VIR_ONCE_GLOBAL_INIT(virPortAllocator)
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;
if (start >= end) {
virReportInvalidArg(start, "start port %d must be less than end port %d",
@ -84,28 +110,37 @@ virPortAllocatorPtr virPortAllocatorNew(const char *name,
return NULL;
}
if (virPortAllocatorInitialize() < 0)
if (VIR_ALLOC(range) < 0)
return NULL;
if (!(pa = virObjectLockableNew(virPortAllocatorClass)))
return NULL;
range->flags = flags;
range->start = start;
range->end = end;
pa->flags = flags;
pa->start = start;
pa->end = end;
if (VIR_STRDUP(range->name, name) < 0)
goto error;
if (!(pa->bitmap = virBitmapNew((end-start)+1)) ||
VIR_STRDUP(pa->name, name) < 0) {
virObjectUnref(pa);
return NULL;
}
return range;
return pa;
error:
virPortAllocatorRangeFree(range);
return NULL;
}
static int virPortAllocatorBindToPort(bool *used,
unsigned short port,
int family)
void
virPortAllocatorRangeFree(virPortAllocatorRangePtr range)
{
if (!range)
return;
VIR_FREE(range->name);
VIR_FREE(range);
}
static int
virPortAllocatorBindToPort(bool *used,
unsigned short port,
int family)
{
struct sockaddr_in6 addr6 = {
.sin6_family = AF_INET6,
@ -172,22 +207,37 @@ static int virPortAllocatorBindToPort(bool *used,
return ret;
}
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 = -1;
size_t i;
virPortAllocatorPtr pa = virPortAllocatorGet();
*port = 0;
if (!pa)
return -1;
virObjectLock(pa);
for (i = pa->start; i <= pa->end && !*port; i++) {
for (i = range->start; i <= range->end && !*port; i++) {
bool used = false, v6used = false;
if (virBitmapIsBitSet(pa->bitmap, i - pa->start))
if (virBitmapIsBitSet(pa->bitmap, i))
continue;
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,
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 == 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;
}
int virPortAllocatorRelease(virPortAllocatorPtr pa,
unsigned short port)
int
virPortAllocatorRelease(virPortAllocatorRangePtr range,
unsigned short port)
{
int ret = -1;
virPortAllocatorPtr pa = virPortAllocatorGet();
if (!pa)
return -1;
if (!port)
return 0;
virObjectLock(pa);
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;
}
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;
}
int virPortAllocatorSetUsed(virPortAllocatorPtr pa,
unsigned short port,
bool value)
int
virPortAllocatorSetUsed(virPortAllocatorRangePtr range,
unsigned short port,
bool value)
{
int ret = -1;
virPortAllocatorPtr pa = virPortAllocatorGet();
if (!pa)
return -1;
virObjectLock(pa);
if (port < pa->start ||
port > pa->end) {
if (port < range->start ||
port > range->end) {
ret = 0;
goto cleanup;
}
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);

View File

@ -25,25 +25,28 @@
# include "internal.h"
# include "virobject.h"
typedef struct _virPortAllocator virPortAllocator;
typedef virPortAllocator *virPortAllocatorPtr;
typedef struct _virPortAllocatorRange virPortAllocatorRange;
typedef virPortAllocatorRange *virPortAllocatorRangePtr;
typedef enum {
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK = (1 << 0),
} virPortAllocatorFlags;
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);
int virPortAllocatorAcquire(virPortAllocatorPtr pa,
void virPortAllocatorRangeFree(virPortAllocatorRangePtr range);
int virPortAllocatorAcquire(virPortAllocatorRangePtr range,
unsigned short *port);
int virPortAllocatorRelease(virPortAllocatorPtr pa,
int virPortAllocatorRelease(virPortAllocatorRangePtr range,
unsigned short port);
int virPortAllocatorSetUsed(virPortAllocatorPtr pa,
int virPortAllocatorSetUsed(virPortAllocatorRangePtr range,
unsigned short port,
bool value);

View File

@ -91,6 +91,15 @@ static int testCompareXMLToArgvFiles(const char *xml,
ret = 0;
out:
if (vmdef &&
vmdef->ngraphics == 1 &&
vmdef->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
if (vmdef->graphics[0]->data.vnc.autoport)
virPortAllocatorRelease(gports, vmdef->graphics[0]->data.vnc.port);
else
virPortAllocatorSetUsed(gports, vmdef->graphics[0]->data.vnc.port, false);
}
VIR_FREE(actualargv);
VIR_FREE(actualld);
VIR_FREE(actualdm);
@ -145,8 +154,8 @@ mymain(void)
if ((driver.xmlopt = virBhyveDriverCreateXMLConf(&driver)) == NULL)
return EXIT_FAILURE;
if (!(driver.remotePorts = virPortAllocatorNew("display", 5900, 65535,
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)))
if (!(driver.remotePorts = virPortAllocatorRangeNew("display", 5900, 65535,
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)))
return EXIT_FAILURE;
@ -240,7 +249,7 @@ mymain(void)
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);
virObjectUnref(driver.remotePorts);
virPortAllocatorRangeFree(driver.remotePorts);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@ -58,7 +58,7 @@ testCompareXMLToDomConfig(const char *xmlfile,
libxl_domain_config expectconfig;
xentoollog_logger *log = NULL;
libxl_ctx *ctx = NULL;
virPortAllocatorPtr gports = NULL;
virPortAllocatorRangePtr gports = NULL;
virDomainXMLOptionPtr xmlopt = NULL;
virDomainDefPtr vmdef = NULL;
char *actualjson = NULL;
@ -74,8 +74,8 @@ testCompareXMLToDomConfig(const char *xmlfile,
if (libxl_ctx_alloc(&ctx, LIBXL_VERSION, 0, log) < 0)
goto cleanup;
if (!(gports = virPortAllocatorNew("vnc", 5900, 6000,
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)))
if (!(gports = virPortAllocatorRangeNew("vnc", 5900, 6000,
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)))
goto cleanup;
if (!(xmlopt = libxlCreateXMLConf()))
@ -112,11 +112,20 @@ testCompareXMLToDomConfig(const char *xmlfile,
ret = 0;
cleanup:
if (vmdef &&
vmdef->ngraphics == 1 &&
vmdef->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
if (vmdef->graphics[0]->data.vnc.autoport)
virPortAllocatorRelease(gports, vmdef->graphics[0]->data.vnc.port);
else
virPortAllocatorSetUsed(gports, vmdef->graphics[0]->data.vnc.port, 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);

View File

@ -42,63 +42,71 @@ VIR_LOG_INIT("tests.portallocatortest");
static int testAllocAll(const void *args ATTRIBUTE_UNUSED)
{
virPortAllocatorPtr alloc = virPortAllocatorNew("test", 5900, 5909, 0);
virPortAllocatorRangePtr ports = virPortAllocatorRangeNew("test", 5900, 5909, 0);
int ret = -1;
unsigned short p1, p2, p3, p4, p5, p6, p7;
unsigned short p1 = 0, p2 = 0, p3 = 0, p4 = 0, p5 = 0, p6 = 0, p7 = 0;
if (!alloc)
if (!ports)
return -1;
if (virPortAllocatorAcquire(alloc, &p1) < 0)
if (virPortAllocatorAcquire(ports, &p1) < 0)
goto cleanup;
if (p1 != 5901) {
VIR_TEST_DEBUG("Expected 5901, got %d", p1);
goto cleanup;
}
if (virPortAllocatorAcquire(alloc, &p2) < 0)
if (virPortAllocatorAcquire(ports, &p2) < 0)
goto cleanup;
if (p2 != 5902) {
VIR_TEST_DEBUG("Expected 5902, got %d", p2);
goto cleanup;
}
if (virPortAllocatorAcquire(alloc, &p3) < 0)
if (virPortAllocatorAcquire(ports, &p3) < 0)
goto cleanup;
if (p3 != 5903) {
VIR_TEST_DEBUG("Expected 5903, got %d", p3);
goto cleanup;
}
if (virPortAllocatorAcquire(alloc, &p4) < 0)
if (virPortAllocatorAcquire(ports, &p4) < 0)
goto cleanup;
if (p4 != 5907) {
VIR_TEST_DEBUG("Expected 5907, got %d", p4);
goto cleanup;
}
if (virPortAllocatorAcquire(alloc, &p5) < 0)
if (virPortAllocatorAcquire(ports, &p5) < 0)
goto cleanup;
if (p5 != 5908) {
VIR_TEST_DEBUG("Expected 5908, got %d", p5);
goto cleanup;
}
if (virPortAllocatorAcquire(alloc, &p6) < 0)
if (virPortAllocatorAcquire(ports, &p6) < 0)
goto cleanup;
if (p6 != 5909) {
VIR_TEST_DEBUG("Expected 5909, got %d", p6);
goto cleanup;
}
if (virPortAllocatorAcquire(alloc, &p7) == 0) {
if (virPortAllocatorAcquire(ports, &p7) == 0) {
VIR_TEST_DEBUG("Expected error, got %d", p7);
goto cleanup;
}
ret = 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;
}
@ -106,28 +114,28 @@ static int testAllocAll(const void *args ATTRIBUTE_UNUSED)
static int testAllocReuse(const void *args ATTRIBUTE_UNUSED)
{
virPortAllocatorPtr alloc = virPortAllocatorNew("test", 5900, 5910, 0);
virPortAllocatorRangePtr ports = virPortAllocatorRangeNew("test", 5900, 5910, 0);
int ret = -1;
unsigned short p1, p2, p3, p4;
unsigned short p1 = 0, p2 = 0, p3 = 0, p4 = 0;
if (!alloc)
if (!ports)
return -1;
if (virPortAllocatorAcquire(alloc, &p1) < 0)
if (virPortAllocatorAcquire(ports, &p1) < 0)
goto cleanup;
if (p1 != 5901) {
VIR_TEST_DEBUG("Expected 5901, got %d", p1);
goto cleanup;
}
if (virPortAllocatorAcquire(alloc, &p2) < 0)
if (virPortAllocatorAcquire(ports, &p2) < 0)
goto cleanup;
if (p2 != 5902) {
VIR_TEST_DEBUG("Expected 5902, got %d", p2);
goto cleanup;
}
if (virPortAllocatorAcquire(alloc, &p3) < 0)
if (virPortAllocatorAcquire(ports, &p3) < 0)
goto cleanup;
if (p3 != 5903) {
VIR_TEST_DEBUG("Expected 5903, got %d", p3);
@ -135,10 +143,10 @@ static int testAllocReuse(const void *args ATTRIBUTE_UNUSED)
}
if (virPortAllocatorRelease(alloc, p2) < 0)
if (virPortAllocatorRelease(ports, p2) < 0)
goto cleanup;
if (virPortAllocatorAcquire(alloc, &p4) < 0)
if (virPortAllocatorAcquire(ports, &p4) < 0)
goto cleanup;
if (p4 != 5902) {
VIR_TEST_DEBUG("Expected 5902, got %d", p4);
@ -147,7 +155,11 @@ static int testAllocReuse(const void *args ATTRIBUTE_UNUSED)
ret = 0;
cleanup:
virObjectUnref(alloc);
virPortAllocatorRelease(ports, p1);
virPortAllocatorRelease(ports, p3);
virPortAllocatorRelease(ports, p4);
virPortAllocatorRangeFree(ports);
return ret;
}