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);
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();
virCloseCallbacksPtr closeCallbacks;
- virPortAllocatorPtr remotePorts;
+ virPortAllocatorRangePtr remotePorts;
unsigned bhyvecaps;
unsigned grubcaps;
# util/virportallocator.h
virPortAllocatorAcquire;
-virPortAllocatorNew;
+virPortAllocatorRangeFree;
+virPortAllocatorRangeNew;
virPortAllocatorRelease;
virPortAllocatorSetUsed;
}
int
-libxlMakeVfb(virPortAllocatorPtr graphicsports,
+libxlMakeVfb(virPortAllocatorRangePtr graphicsports,
virDomainGraphicsDefPtr l_vfb,
libxl_device_vfb *x_vfb)
{
}
static int
-libxlMakeVfbList(virPortAllocatorPtr graphicsports,
+libxlMakeVfbList(virPortAllocatorRangePtr graphicsports,
virDomainDefPtr def,
libxl_domain_config *d_config)
{
* populate libxl_domain_config->vfbs.
*/
static int
-libxlMakeBuildInfoVfb(virPortAllocatorPtr graphicsports,
+libxlMakeBuildInfoVfb(virPortAllocatorRangePtr graphicsports,
virDomainDefPtr def,
libxl_domain_config *d_config)
{
}
int
-libxlBuildDomainConfig(virPortAllocatorPtr graphicsports,
+libxlBuildDomainConfig(virPortAllocatorRangePtr graphicsports,
virDomainDefPtr def,
const char *channelDir LIBXL_ATTR_UNUSED,
libxl_ctx *ctx,
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;
libxl_device_nic *x_nic,
bool attach);
int
-libxlMakeVfb(virPortAllocatorPtr graphicsports,
+libxlMakeVfb(virPortAllocatorRangePtr graphicsports,
virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb);
int
# 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,
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);
/* 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()))
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;
* 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)
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);
#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;
};
static virClassPtr virPortAllocatorClass;
+static virPortAllocatorPtr virPortAllocatorInstance;
static void
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",
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",
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;
+}
+
+void
+virPortAllocatorRangeFree(virPortAllocatorRangePtr range)
+{
+ if (!range)
+ return;
+
+ VIR_FREE(range->name);
+ VIR_FREE(range);
}
-static int virPortAllocatorBindToPort(bool *used,
- unsigned short port,
- int family)
+static int
+virPortAllocatorBindToPort(bool *used,
+ unsigned short port,
+ int family)
{
struct sockaddr_in6 addr6 = {
.sin6_family = AF_INET6,
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;
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;
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);
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);
# 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);
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);
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;
virObjectUnref(driver.caps);
virObjectUnref(driver.xmlopt);
- virObjectUnref(driver.remotePorts);
+ virPortAllocatorRangeFree(driver.remotePorts);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
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;
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()))
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);
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;
}
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);
}
- 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);
ret = 0;
cleanup:
- virObjectUnref(alloc);
+ virPortAllocatorRelease(ports, p1);
+ virPortAllocatorRelease(ports, p3);
+ virPortAllocatorRelease(ports, p4);
+
+ virPortAllocatorRangeFree(ports);
return ret;
}