mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
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:
parent
5590122937
commit
7ebc4f2a4c
@ -1220,7 +1220,7 @@ bhyveStateCleanup(void)
|
|||||||
virObjectUnref(bhyve_driver->closeCallbacks);
|
virObjectUnref(bhyve_driver->closeCallbacks);
|
||||||
virObjectUnref(bhyve_driver->domainEventState);
|
virObjectUnref(bhyve_driver->domainEventState);
|
||||||
virObjectUnref(bhyve_driver->config);
|
virObjectUnref(bhyve_driver->config);
|
||||||
virObjectUnref(bhyve_driver->remotePorts);
|
virPortAllocatorRangeFree(bhyve_driver->remotePorts);
|
||||||
|
|
||||||
virMutexDestroy(&bhyve_driver->lock);
|
virMutexDestroy(&bhyve_driver->lock);
|
||||||
VIR_FREE(bhyve_driver);
|
VIR_FREE(bhyve_driver);
|
||||||
@ -1267,7 +1267,8 @@ bhyveStateInitialize(bool privileged,
|
|||||||
if (!(bhyve_driver->domainEventState = virObjectEventStateNew()))
|
if (!(bhyve_driver->domainEventState = virObjectEventStateNew()))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!(bhyve_driver->remotePorts = virPortAllocatorNew(_("display"), 5900, 65535, 0)))
|
if (!(bhyve_driver->remotePorts = virPortAllocatorRangeNew(_("display"),
|
||||||
|
5900, 65535, 0)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
bhyve_driver->hostsysinfo = virSysinfoRead();
|
bhyve_driver->hostsysinfo = virSysinfoRead();
|
||||||
|
@ -59,7 +59,7 @@ struct _bhyveConn {
|
|||||||
|
|
||||||
virCloseCallbacksPtr closeCallbacks;
|
virCloseCallbacksPtr closeCallbacks;
|
||||||
|
|
||||||
virPortAllocatorPtr remotePorts;
|
virPortAllocatorRangePtr remotePorts;
|
||||||
|
|
||||||
unsigned bhyvecaps;
|
unsigned bhyvecaps;
|
||||||
unsigned grubcaps;
|
unsigned grubcaps;
|
||||||
|
@ -2535,7 +2535,8 @@ virPolkitCheckAuth;
|
|||||||
|
|
||||||
# util/virportallocator.h
|
# util/virportallocator.h
|
||||||
virPortAllocatorAcquire;
|
virPortAllocatorAcquire;
|
||||||
virPortAllocatorNew;
|
virPortAllocatorRangeFree;
|
||||||
|
virPortAllocatorRangeNew;
|
||||||
virPortAllocatorRelease;
|
virPortAllocatorRelease;
|
||||||
virPortAllocatorSetUsed;
|
virPortAllocatorSetUsed;
|
||||||
|
|
||||||
|
@ -1316,7 +1316,7 @@ libxlMakeNicList(virDomainDefPtr def, libxl_domain_config *d_config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
libxlMakeVfb(virPortAllocatorPtr graphicsports,
|
libxlMakeVfb(virPortAllocatorRangePtr graphicsports,
|
||||||
virDomainGraphicsDefPtr l_vfb,
|
virDomainGraphicsDefPtr l_vfb,
|
||||||
libxl_device_vfb *x_vfb)
|
libxl_device_vfb *x_vfb)
|
||||||
{
|
{
|
||||||
@ -1377,7 +1377,7 @@ libxlMakeVfb(virPortAllocatorPtr graphicsports,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
libxlMakeVfbList(virPortAllocatorPtr graphicsports,
|
libxlMakeVfbList(virPortAllocatorRangePtr graphicsports,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
libxl_domain_config *d_config)
|
libxl_domain_config *d_config)
|
||||||
{
|
{
|
||||||
@ -1426,7 +1426,7 @@ libxlMakeVfbList(virPortAllocatorPtr graphicsports,
|
|||||||
* populate libxl_domain_config->vfbs.
|
* populate libxl_domain_config->vfbs.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
libxlMakeBuildInfoVfb(virPortAllocatorPtr graphicsports,
|
libxlMakeBuildInfoVfb(virPortAllocatorRangePtr graphicsports,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
libxl_domain_config *d_config)
|
libxl_domain_config *d_config)
|
||||||
{
|
{
|
||||||
@ -2313,7 +2313,7 @@ libxlDriverNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
libxlBuildDomainConfig(virPortAllocatorPtr graphicsports,
|
libxlBuildDomainConfig(virPortAllocatorRangePtr graphicsports,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
const char *channelDir LIBXL_ATTR_UNUSED,
|
const char *channelDir LIBXL_ATTR_UNUSED,
|
||||||
libxl_ctx *ctx,
|
libxl_ctx *ctx,
|
||||||
|
@ -131,10 +131,10 @@ struct _libxlDriverPrivate {
|
|||||||
virObjectEventStatePtr domainEventState;
|
virObjectEventStatePtr domainEventState;
|
||||||
|
|
||||||
/* Immutable pointer, self-locking APIs */
|
/* Immutable pointer, self-locking APIs */
|
||||||
virPortAllocatorPtr reservedGraphicsPorts;
|
virPortAllocatorRangePtr reservedGraphicsPorts;
|
||||||
|
|
||||||
/* Immutable pointer, self-locking APIs */
|
/* Immutable pointer, self-locking APIs */
|
||||||
virPortAllocatorPtr migrationPorts;
|
virPortAllocatorRangePtr migrationPorts;
|
||||||
|
|
||||||
/* Immutable pointer, lockless APIs*/
|
/* Immutable pointer, lockless APIs*/
|
||||||
virSysinfoDefPtr hostsysinfo;
|
virSysinfoDefPtr hostsysinfo;
|
||||||
@ -189,7 +189,7 @@ libxlMakeNic(virDomainDefPtr def,
|
|||||||
libxl_device_nic *x_nic,
|
libxl_device_nic *x_nic,
|
||||||
bool attach);
|
bool attach);
|
||||||
int
|
int
|
||||||
libxlMakeVfb(virPortAllocatorPtr graphicsports,
|
libxlMakeVfb(virPortAllocatorRangePtr graphicsports,
|
||||||
virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb);
|
virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb);
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -213,7 +213,7 @@ libxlCreateXMLConf(void);
|
|||||||
# define LIBXL_ATTR_UNUSED ATTRIBUTE_UNUSED
|
# define LIBXL_ATTR_UNUSED ATTRIBUTE_UNUSED
|
||||||
# endif
|
# endif
|
||||||
int
|
int
|
||||||
libxlBuildDomainConfig(virPortAllocatorPtr graphicsports,
|
libxlBuildDomainConfig(virPortAllocatorRangePtr graphicsports,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
const char *channelDir LIBXL_ATTR_UNUSED,
|
const char *channelDir LIBXL_ATTR_UNUSED,
|
||||||
libxl_ctx *ctx,
|
libxl_ctx *ctx,
|
||||||
|
@ -476,8 +476,8 @@ libxlStateCleanup(void)
|
|||||||
virObjectUnref(libxl_driver->config);
|
virObjectUnref(libxl_driver->config);
|
||||||
virObjectUnref(libxl_driver->xmlopt);
|
virObjectUnref(libxl_driver->xmlopt);
|
||||||
virObjectUnref(libxl_driver->domains);
|
virObjectUnref(libxl_driver->domains);
|
||||||
virObjectUnref(libxl_driver->reservedGraphicsPorts);
|
virPortAllocatorRangeFree(libxl_driver->reservedGraphicsPorts);
|
||||||
virObjectUnref(libxl_driver->migrationPorts);
|
virPortAllocatorRangeFree(libxl_driver->migrationPorts);
|
||||||
virLockManagerPluginUnref(libxl_driver->lockManager);
|
virLockManagerPluginUnref(libxl_driver->lockManager);
|
||||||
|
|
||||||
virObjectUnref(libxl_driver->domainEventState);
|
virObjectUnref(libxl_driver->domainEventState);
|
||||||
@ -656,7 +656,7 @@ libxlStateInitialize(bool privileged,
|
|||||||
|
|
||||||
/* Allocate bitmap for vnc port reservation */
|
/* Allocate bitmap for vnc port reservation */
|
||||||
if (!(libxl_driver->reservedGraphicsPorts =
|
if (!(libxl_driver->reservedGraphicsPorts =
|
||||||
virPortAllocatorNew(_("VNC"),
|
virPortAllocatorRangeNew(_("VNC"),
|
||||||
LIBXL_VNC_PORT_MIN,
|
LIBXL_VNC_PORT_MIN,
|
||||||
LIBXL_VNC_PORT_MAX,
|
LIBXL_VNC_PORT_MAX,
|
||||||
0)))
|
0)))
|
||||||
@ -664,7 +664,7 @@ libxlStateInitialize(bool privileged,
|
|||||||
|
|
||||||
/* Allocate bitmap for migration port reservation */
|
/* Allocate bitmap for migration port reservation */
|
||||||
if (!(libxl_driver->migrationPorts =
|
if (!(libxl_driver->migrationPorts =
|
||||||
virPortAllocatorNew(_("migration"),
|
virPortAllocatorRangeNew(_("migration"),
|
||||||
LIBXL_MIGRATION_PORT_MIN,
|
LIBXL_MIGRATION_PORT_MIN,
|
||||||
LIBXL_MIGRATION_PORT_MAX, 0)))
|
LIBXL_MIGRATION_PORT_MAX, 0)))
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -264,13 +264,13 @@ struct _virQEMUDriver {
|
|||||||
virHashTablePtr sharedDevices;
|
virHashTablePtr sharedDevices;
|
||||||
|
|
||||||
/* Immutable pointer, self-locking APIs */
|
/* Immutable pointer, self-locking APIs */
|
||||||
virPortAllocatorPtr remotePorts;
|
virPortAllocatorRangePtr remotePorts;
|
||||||
|
|
||||||
/* Immutable pointer, self-locking APIs */
|
/* Immutable pointer, self-locking APIs */
|
||||||
virPortAllocatorPtr webSocketPorts;
|
virPortAllocatorRangePtr webSocketPorts;
|
||||||
|
|
||||||
/* Immutable pointer, self-locking APIs */
|
/* Immutable pointer, self-locking APIs */
|
||||||
virPortAllocatorPtr migrationPorts;
|
virPortAllocatorRangePtr migrationPorts;
|
||||||
|
|
||||||
/* Immutable pointer, lockless APIs*/
|
/* Immutable pointer, lockless APIs*/
|
||||||
virSysinfoDefPtr hostsysinfo;
|
virSysinfoDefPtr hostsysinfo;
|
||||||
|
@ -725,21 +725,21 @@ qemuStateInitialize(bool privileged,
|
|||||||
* do this before the config is loaded properly, since the port
|
* do this before the config is loaded properly, since the port
|
||||||
* numbers are configurable now */
|
* numbers are configurable now */
|
||||||
if ((qemu_driver->remotePorts =
|
if ((qemu_driver->remotePorts =
|
||||||
virPortAllocatorNew(_("display"),
|
virPortAllocatorRangeNew(_("display"),
|
||||||
cfg->remotePortMin,
|
cfg->remotePortMin,
|
||||||
cfg->remotePortMax,
|
cfg->remotePortMax,
|
||||||
0)) == NULL)
|
0)) == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if ((qemu_driver->webSocketPorts =
|
if ((qemu_driver->webSocketPorts =
|
||||||
virPortAllocatorNew(_("webSocket"),
|
virPortAllocatorRangeNew(_("webSocket"),
|
||||||
cfg->webSocketPortMin,
|
cfg->webSocketPortMin,
|
||||||
cfg->webSocketPortMax,
|
cfg->webSocketPortMax,
|
||||||
0)) == NULL)
|
0)) == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if ((qemu_driver->migrationPorts =
|
if ((qemu_driver->migrationPorts =
|
||||||
virPortAllocatorNew(_("migration"),
|
virPortAllocatorRangeNew(_("migration"),
|
||||||
cfg->migrationPortMin,
|
cfg->migrationPortMin,
|
||||||
cfg->migrationPortMax,
|
cfg->migrationPortMax,
|
||||||
0)) == NULL)
|
0)) == NULL)
|
||||||
@ -1085,9 +1085,9 @@ qemuStateCleanup(void)
|
|||||||
virObjectUnref(qemu_driver->qemuCapsCache);
|
virObjectUnref(qemu_driver->qemuCapsCache);
|
||||||
|
|
||||||
virObjectUnref(qemu_driver->domains);
|
virObjectUnref(qemu_driver->domains);
|
||||||
virObjectUnref(qemu_driver->remotePorts);
|
virPortAllocatorRangeFree(qemu_driver->remotePorts);
|
||||||
virObjectUnref(qemu_driver->webSocketPorts);
|
virPortAllocatorRangeFree(qemu_driver->webSocketPorts);
|
||||||
virObjectUnref(qemu_driver->migrationPorts);
|
virPortAllocatorRangeFree(qemu_driver->migrationPorts);
|
||||||
virObjectUnref(qemu_driver->migrationErrors);
|
virObjectUnref(qemu_driver->migrationErrors);
|
||||||
|
|
||||||
virObjectUnref(qemu_driver->xmlopt);
|
virObjectUnref(qemu_driver->xmlopt);
|
||||||
|
@ -35,10 +35,14 @@
|
|||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
|
|
||||||
|
typedef struct _virPortAllocator virPortAllocator;
|
||||||
|
typedef virPortAllocator *virPortAllocatorPtr;
|
||||||
struct _virPortAllocator {
|
struct _virPortAllocator {
|
||||||
virObjectLockable parent;
|
virObjectLockable parent;
|
||||||
virBitmapPtr bitmap;
|
virBitmapPtr bitmap;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _virPortAllocatorRange {
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
unsigned short start;
|
unsigned short start;
|
||||||
@ -48,6 +52,7 @@ struct _virPortAllocator {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static virClassPtr virPortAllocatorClass;
|
static virClassPtr virPortAllocatorClass;
|
||||||
|
static virPortAllocatorPtr virPortAllocatorInstance;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virPortAllocatorDispose(void *obj)
|
virPortAllocatorDispose(void *obj)
|
||||||
@ -55,10 +60,27 @@ virPortAllocatorDispose(void *obj)
|
|||||||
virPortAllocatorPtr pa = obj;
|
virPortAllocatorPtr pa = obj;
|
||||||
|
|
||||||
virBitmapFree(pa->bitmap);
|
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(),
|
if (!(virPortAllocatorClass = virClassNew(virClassForObjectLockable(),
|
||||||
"virPortAllocator",
|
"virPortAllocator",
|
||||||
@ -66,17 +88,21 @@ static int virPortAllocatorOnceInit(void)
|
|||||||
virPortAllocatorDispose)))
|
virPortAllocatorDispose)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (!(virPortAllocatorInstance = virPortAllocatorNew()))
|
||||||
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIR_ONCE_GLOBAL_INIT(virPortAllocator)
|
VIR_ONCE_GLOBAL_INIT(virPortAllocator)
|
||||||
|
|
||||||
virPortAllocatorPtr virPortAllocatorNew(const char *name,
|
virPortAllocatorRangePtr
|
||||||
|
virPortAllocatorRangeNew(const char *name,
|
||||||
unsigned short start,
|
unsigned short start,
|
||||||
unsigned short end,
|
unsigned short end,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
virPortAllocatorPtr pa;
|
virPortAllocatorRangePtr range;
|
||||||
|
|
||||||
if (start >= end) {
|
if (start >= end) {
|
||||||
virReportInvalidArg(start, "start port %d must be less than end port %d",
|
virReportInvalidArg(start, "start port %d must be less than end port %d",
|
||||||
@ -84,26 +110,35 @@ virPortAllocatorPtr virPortAllocatorNew(const char *name,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virPortAllocatorInitialize() < 0)
|
if (VIR_ALLOC(range) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(pa = virObjectLockableNew(virPortAllocatorClass)))
|
range->flags = flags;
|
||||||
|
range->start = start;
|
||||||
|
range->end = end;
|
||||||
|
|
||||||
|
if (VIR_STRDUP(range->name, name) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return range;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virPortAllocatorRangeFree(range);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pa->flags = flags;
|
|
||||||
pa->start = start;
|
|
||||||
pa->end = end;
|
|
||||||
|
|
||||||
if (!(pa->bitmap = virBitmapNew((end-start)+1)) ||
|
|
||||||
VIR_STRDUP(pa->name, name) < 0) {
|
|
||||||
virObjectUnref(pa);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pa;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int virPortAllocatorBindToPort(bool *used,
|
void
|
||||||
|
virPortAllocatorRangeFree(virPortAllocatorRangePtr range)
|
||||||
|
{
|
||||||
|
if (!range)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VIR_FREE(range->name);
|
||||||
|
VIR_FREE(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virPortAllocatorBindToPort(bool *used,
|
||||||
unsigned short port,
|
unsigned short port,
|
||||||
int family)
|
int family)
|
||||||
{
|
{
|
||||||
@ -172,22 +207,37 @@ static int virPortAllocatorBindToPort(bool *used,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virPortAllocatorAcquire(virPortAllocatorPtr pa,
|
static virPortAllocatorPtr
|
||||||
|
virPortAllocatorGet(void)
|
||||||
|
{
|
||||||
|
if (virPortAllocatorInitialize() < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return virPortAllocatorInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virPortAllocatorAcquire(virPortAllocatorRangePtr range,
|
||||||
unsigned short *port)
|
unsigned short *port)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
virPortAllocatorPtr pa = virPortAllocatorGet();
|
||||||
|
|
||||||
*port = 0;
|
*port = 0;
|
||||||
|
|
||||||
|
if (!pa)
|
||||||
|
return -1;
|
||||||
|
|
||||||
virObjectLock(pa);
|
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;
|
bool used = false, v6used = false;
|
||||||
|
|
||||||
if (virBitmapIsBitSet(pa->bitmap, i - pa->start))
|
if (virBitmapIsBitSet(pa->bitmap, i))
|
||||||
continue;
|
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 ||
|
if (virPortAllocatorBindToPort(&v6used, i, AF_INET6) < 0 ||
|
||||||
virPortAllocatorBindToPort(&used, i, AF_INET) < 0)
|
virPortAllocatorBindToPort(&used, i, AF_INET) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -195,8 +245,7 @@ int virPortAllocatorAcquire(virPortAllocatorPtr pa,
|
|||||||
|
|
||||||
if (!used && !v6used) {
|
if (!used && !v6used) {
|
||||||
/* Add port to bitmap of reserved ports */
|
/* Add port to bitmap of reserved ports */
|
||||||
if (virBitmapSetBit(pa->bitmap,
|
if (virBitmapSetBit(pa->bitmap, i) < 0) {
|
||||||
i - pa->start) < 0) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Failed to reserve port %zu"), i);
|
_("Failed to reserve port %zu"), i);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -209,32 +258,36 @@ int virPortAllocatorAcquire(virPortAllocatorPtr pa,
|
|||||||
if (*port == 0) {
|
if (*port == 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Unable to find an unused port in range '%s' (%d-%d)"),
|
_("Unable to find an unused port in range '%s' (%d-%d)"),
|
||||||
pa->name, pa->start, pa->end);
|
range->name, range->start, range->end);
|
||||||
}
|
}
|
||||||
cleanup:
|
cleanup:
|
||||||
virObjectUnlock(pa);
|
virObjectUnlock(pa);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virPortAllocatorRelease(virPortAllocatorPtr pa,
|
int
|
||||||
|
virPortAllocatorRelease(virPortAllocatorRangePtr range,
|
||||||
unsigned short port)
|
unsigned short port)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
virPortAllocatorPtr pa = virPortAllocatorGet();
|
||||||
|
|
||||||
|
if (!pa)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (!port)
|
if (!port)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
virObjectLock(pa);
|
virObjectLock(pa);
|
||||||
|
|
||||||
if (port < pa->start ||
|
if (port < range->start ||
|
||||||
port > pa->end) {
|
port > range->end) {
|
||||||
virReportInvalidArg(port, "port %d must be in range (%d, %d)",
|
virReportInvalidArg(port, "port %d must be in range (%d, %d)",
|
||||||
port, pa->start, pa->end);
|
port, range->start, range->end);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virBitmapClearBit(pa->bitmap,
|
if (virBitmapClearBit(pa->bitmap, port) < 0) {
|
||||||
port - pa->start) < 0) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Failed to release port %d"),
|
_("Failed to release port %d"),
|
||||||
port);
|
port);
|
||||||
@ -247,30 +300,34 @@ int virPortAllocatorRelease(virPortAllocatorPtr pa,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int virPortAllocatorSetUsed(virPortAllocatorPtr pa,
|
int
|
||||||
|
virPortAllocatorSetUsed(virPortAllocatorRangePtr range,
|
||||||
unsigned short port,
|
unsigned short port,
|
||||||
bool value)
|
bool value)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
virPortAllocatorPtr pa = virPortAllocatorGet();
|
||||||
|
|
||||||
|
if (!pa)
|
||||||
|
return -1;
|
||||||
|
|
||||||
virObjectLock(pa);
|
virObjectLock(pa);
|
||||||
|
|
||||||
if (port < pa->start ||
|
if (port < range->start ||
|
||||||
port > pa->end) {
|
port > range->end) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
if (virBitmapIsBitSet(pa->bitmap, port - pa->start) ||
|
if (virBitmapIsBitSet(pa->bitmap, port) ||
|
||||||
virBitmapSetBit(pa->bitmap, port - pa->start) < 0) {
|
virBitmapSetBit(pa->bitmap, port) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Failed to reserve port %d"), port);
|
_("Failed to reserve port %d"), port);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (virBitmapClearBit(pa->bitmap,
|
if (virBitmapClearBit(pa->bitmap, port) < 0) {
|
||||||
port - pa->start) < 0) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Failed to release port %d"),
|
_("Failed to release port %d"),
|
||||||
port);
|
port);
|
||||||
|
@ -25,25 +25,28 @@
|
|||||||
# include "internal.h"
|
# include "internal.h"
|
||||||
# include "virobject.h"
|
# include "virobject.h"
|
||||||
|
|
||||||
typedef struct _virPortAllocator virPortAllocator;
|
typedef struct _virPortAllocatorRange virPortAllocatorRange;
|
||||||
typedef virPortAllocator *virPortAllocatorPtr;
|
typedef virPortAllocatorRange *virPortAllocatorRangePtr;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK = (1 << 0),
|
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK = (1 << 0),
|
||||||
} virPortAllocatorFlags;
|
} virPortAllocatorFlags;
|
||||||
|
|
||||||
virPortAllocatorPtr virPortAllocatorNew(const char *name,
|
virPortAllocatorRangePtr
|
||||||
|
virPortAllocatorRangeNew(const char *name,
|
||||||
unsigned short start,
|
unsigned short start,
|
||||||
unsigned short end,
|
unsigned short end,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
int virPortAllocatorAcquire(virPortAllocatorPtr pa,
|
void virPortAllocatorRangeFree(virPortAllocatorRangePtr range);
|
||||||
|
|
||||||
|
int virPortAllocatorAcquire(virPortAllocatorRangePtr range,
|
||||||
unsigned short *port);
|
unsigned short *port);
|
||||||
|
|
||||||
int virPortAllocatorRelease(virPortAllocatorPtr pa,
|
int virPortAllocatorRelease(virPortAllocatorRangePtr range,
|
||||||
unsigned short port);
|
unsigned short port);
|
||||||
|
|
||||||
int virPortAllocatorSetUsed(virPortAllocatorPtr pa,
|
int virPortAllocatorSetUsed(virPortAllocatorRangePtr range,
|
||||||
unsigned short port,
|
unsigned short port,
|
||||||
bool value);
|
bool value);
|
||||||
|
|
||||||
|
@ -91,6 +91,15 @@ static int testCompareXMLToArgvFiles(const char *xml,
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
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(actualargv);
|
||||||
VIR_FREE(actualld);
|
VIR_FREE(actualld);
|
||||||
VIR_FREE(actualdm);
|
VIR_FREE(actualdm);
|
||||||
@ -145,7 +154,7 @@ mymain(void)
|
|||||||
if ((driver.xmlopt = virBhyveDriverCreateXMLConf(&driver)) == NULL)
|
if ((driver.xmlopt = virBhyveDriverCreateXMLConf(&driver)) == NULL)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
if (!(driver.remotePorts = virPortAllocatorNew("display", 5900, 65535,
|
if (!(driver.remotePorts = virPortAllocatorRangeNew("display", 5900, 65535,
|
||||||
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)))
|
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
@ -240,7 +249,7 @@ mymain(void)
|
|||||||
|
|
||||||
virObjectUnref(driver.caps);
|
virObjectUnref(driver.caps);
|
||||||
virObjectUnref(driver.xmlopt);
|
virObjectUnref(driver.xmlopt);
|
||||||
virObjectUnref(driver.remotePorts);
|
virPortAllocatorRangeFree(driver.remotePorts);
|
||||||
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ testCompareXMLToDomConfig(const char *xmlfile,
|
|||||||
libxl_domain_config expectconfig;
|
libxl_domain_config expectconfig;
|
||||||
xentoollog_logger *log = NULL;
|
xentoollog_logger *log = NULL;
|
||||||
libxl_ctx *ctx = NULL;
|
libxl_ctx *ctx = NULL;
|
||||||
virPortAllocatorPtr gports = NULL;
|
virPortAllocatorRangePtr gports = NULL;
|
||||||
virDomainXMLOptionPtr xmlopt = NULL;
|
virDomainXMLOptionPtr xmlopt = NULL;
|
||||||
virDomainDefPtr vmdef = NULL;
|
virDomainDefPtr vmdef = NULL;
|
||||||
char *actualjson = NULL;
|
char *actualjson = NULL;
|
||||||
@ -74,7 +74,7 @@ testCompareXMLToDomConfig(const char *xmlfile,
|
|||||||
if (libxl_ctx_alloc(&ctx, LIBXL_VERSION, 0, log) < 0)
|
if (libxl_ctx_alloc(&ctx, LIBXL_VERSION, 0, log) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!(gports = virPortAllocatorNew("vnc", 5900, 6000,
|
if (!(gports = virPortAllocatorRangeNew("vnc", 5900, 6000,
|
||||||
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)))
|
VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -112,11 +112,20 @@ testCompareXMLToDomConfig(const char *xmlfile,
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
cleanup:
|
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(expectjson);
|
||||||
VIR_FREE(actualjson);
|
VIR_FREE(actualjson);
|
||||||
VIR_FREE(tempjson);
|
VIR_FREE(tempjson);
|
||||||
virDomainDefFree(vmdef);
|
virDomainDefFree(vmdef);
|
||||||
virObjectUnref(gports);
|
virPortAllocatorRangeFree(gports);
|
||||||
virObjectUnref(xmlopt);
|
virObjectUnref(xmlopt);
|
||||||
libxl_ctx_free(ctx);
|
libxl_ctx_free(ctx);
|
||||||
libxl_domain_config_dispose(&actualconfig);
|
libxl_domain_config_dispose(&actualconfig);
|
||||||
|
@ -42,63 +42,71 @@ VIR_LOG_INIT("tests.portallocatortest");
|
|||||||
|
|
||||||
static int testAllocAll(const void *args ATTRIBUTE_UNUSED)
|
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;
|
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;
|
return -1;
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p1) < 0)
|
if (virPortAllocatorAcquire(ports, &p1) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (p1 != 5901) {
|
if (p1 != 5901) {
|
||||||
VIR_TEST_DEBUG("Expected 5901, got %d", p1);
|
VIR_TEST_DEBUG("Expected 5901, got %d", p1);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p2) < 0)
|
if (virPortAllocatorAcquire(ports, &p2) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (p2 != 5902) {
|
if (p2 != 5902) {
|
||||||
VIR_TEST_DEBUG("Expected 5902, got %d", p2);
|
VIR_TEST_DEBUG("Expected 5902, got %d", p2);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p3) < 0)
|
if (virPortAllocatorAcquire(ports, &p3) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (p3 != 5903) {
|
if (p3 != 5903) {
|
||||||
VIR_TEST_DEBUG("Expected 5903, got %d", p3);
|
VIR_TEST_DEBUG("Expected 5903, got %d", p3);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p4) < 0)
|
if (virPortAllocatorAcquire(ports, &p4) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (p4 != 5907) {
|
if (p4 != 5907) {
|
||||||
VIR_TEST_DEBUG("Expected 5907, got %d", p4);
|
VIR_TEST_DEBUG("Expected 5907, got %d", p4);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p5) < 0)
|
if (virPortAllocatorAcquire(ports, &p5) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (p5 != 5908) {
|
if (p5 != 5908) {
|
||||||
VIR_TEST_DEBUG("Expected 5908, got %d", p5);
|
VIR_TEST_DEBUG("Expected 5908, got %d", p5);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p6) < 0)
|
if (virPortAllocatorAcquire(ports, &p6) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (p6 != 5909) {
|
if (p6 != 5909) {
|
||||||
VIR_TEST_DEBUG("Expected 5909, got %d", p6);
|
VIR_TEST_DEBUG("Expected 5909, got %d", p6);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p7) == 0) {
|
if (virPortAllocatorAcquire(ports, &p7) == 0) {
|
||||||
VIR_TEST_DEBUG("Expected error, got %d", p7);
|
VIR_TEST_DEBUG("Expected error, got %d", p7);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,28 +114,28 @@ static int testAllocAll(const void *args ATTRIBUTE_UNUSED)
|
|||||||
|
|
||||||
static int testAllocReuse(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;
|
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;
|
return -1;
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p1) < 0)
|
if (virPortAllocatorAcquire(ports, &p1) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (p1 != 5901) {
|
if (p1 != 5901) {
|
||||||
VIR_TEST_DEBUG("Expected 5901, got %d", p1);
|
VIR_TEST_DEBUG("Expected 5901, got %d", p1);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p2) < 0)
|
if (virPortAllocatorAcquire(ports, &p2) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (p2 != 5902) {
|
if (p2 != 5902) {
|
||||||
VIR_TEST_DEBUG("Expected 5902, got %d", p2);
|
VIR_TEST_DEBUG("Expected 5902, got %d", p2);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p3) < 0)
|
if (virPortAllocatorAcquire(ports, &p3) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (p3 != 5903) {
|
if (p3 != 5903) {
|
||||||
VIR_TEST_DEBUG("Expected 5903, got %d", p3);
|
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;
|
goto cleanup;
|
||||||
|
|
||||||
if (virPortAllocatorAcquire(alloc, &p4) < 0)
|
if (virPortAllocatorAcquire(ports, &p4) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (p4 != 5902) {
|
if (p4 != 5902) {
|
||||||
VIR_TEST_DEBUG("Expected 5902, got %d", p4);
|
VIR_TEST_DEBUG("Expected 5902, got %d", p4);
|
||||||
@ -147,7 +155,11 @@ static int testAllocReuse(const void *args ATTRIBUTE_UNUSED)
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
virObjectUnref(alloc);
|
virPortAllocatorRelease(ports, p1);
|
||||||
|
virPortAllocatorRelease(ports, p3);
|
||||||
|
virPortAllocatorRelease(ports, p4);
|
||||||
|
|
||||||
|
virPortAllocatorRangeFree(ports);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user