mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Convert QEMU driver over to use virPortAllocator APIs
Replace the current QEMU driver code for managing port reservations with the new virPortAllocator APIs.
This commit is contained in:
@@ -39,7 +39,7 @@
|
|||||||
# include "virusb.h"
|
# include "virusb.h"
|
||||||
# include "cpu_conf.h"
|
# include "cpu_conf.h"
|
||||||
# include "driver.h"
|
# include "driver.h"
|
||||||
# include "virbitmap.h"
|
# include "virportallocator.h"
|
||||||
# include "vircommand.h"
|
# include "vircommand.h"
|
||||||
# include "virthreadpool.h"
|
# include "virthreadpool.h"
|
||||||
# include "locking/lock_manager.h"
|
# include "locking/lock_manager.h"
|
||||||
@@ -150,7 +150,7 @@ struct _virQEMUDriver {
|
|||||||
|
|
||||||
virHashTablePtr sharedDisks;
|
virHashTablePtr sharedDisks;
|
||||||
|
|
||||||
virBitmapPtr reservedRemotePorts;
|
virPortAllocatorPtr remotePorts;
|
||||||
|
|
||||||
virSysinfoDefPtr hostsysinfo;
|
virSysinfoDefPtr hostsysinfo;
|
||||||
|
|
||||||
|
|||||||
@@ -809,9 +809,10 @@ qemuStartup(bool privileged,
|
|||||||
/* Allocate bitmap for remote display port reservations. We cannot
|
/* Allocate bitmap for remote display port reservations. We cannot
|
||||||
* 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->reservedRemotePorts =
|
if ((qemu_driver->remotePorts =
|
||||||
virBitmapNew(qemu_driver->remotePortMax - qemu_driver->remotePortMin)) == NULL)
|
virPortAllocatorNew(qemu_driver->remotePortMin,
|
||||||
goto out_of_memory;
|
qemu_driver->remotePortMax)) == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
/* We should always at least have the 'nop' manager, so
|
/* We should always at least have the 'nop' manager, so
|
||||||
* NULLs here are a fatal error
|
* NULLs here are a fatal error
|
||||||
@@ -1104,7 +1105,7 @@ qemuShutdown(void) {
|
|||||||
qemuCapsCacheFree(qemu_driver->capsCache);
|
qemuCapsCacheFree(qemu_driver->capsCache);
|
||||||
|
|
||||||
virDomainObjListDeinit(&qemu_driver->domains);
|
virDomainObjListDeinit(&qemu_driver->domains);
|
||||||
virBitmapFree(qemu_driver->reservedRemotePorts);
|
virObjectUnref(qemu_driver->remotePorts);
|
||||||
|
|
||||||
virSysinfoDefFree(qemu_driver->hostsysinfo);
|
virSysinfoDefFree(qemu_driver->hostsysinfo);
|
||||||
|
|
||||||
|
|||||||
@@ -2604,73 +2604,6 @@ qemuProcessInitPCIAddresses(virQEMUDriverPtr driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int qemuProcessNextFreePort(virQEMUDriverPtr driver,
|
|
||||||
int startPort)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = startPort ; i < driver->remotePortMax; i++) {
|
|
||||||
int fd;
|
|
||||||
int reuse = 1;
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
bool used = false;
|
|
||||||
|
|
||||||
if (virBitmapGetBit(driver->reservedRemotePorts,
|
|
||||||
i - driver->remotePortMin, &used) < 0)
|
|
||||||
VIR_DEBUG("virBitmapGetBit failed on bit %d", i - driver->remotePortMin);
|
|
||||||
|
|
||||||
if (used)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
addr.sin_port = htons(i);
|
|
||||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
fd = socket(PF_INET, SOCK_STREAM, 0);
|
|
||||||
if (fd < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse, sizeof(reuse)) < 0) {
|
|
||||||
VIR_FORCE_CLOSE(fd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
|
|
||||||
/* Not in use, lets grab it */
|
|
||||||
VIR_FORCE_CLOSE(fd);
|
|
||||||
/* Add port to bitmap of reserved ports */
|
|
||||||
if (virBitmapSetBit(driver->reservedRemotePorts,
|
|
||||||
i - driver->remotePortMin) < 0) {
|
|
||||||
VIR_DEBUG("virBitmapSetBit failed on bit %d",
|
|
||||||
i - driver->remotePortMin);
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
VIR_FORCE_CLOSE(fd);
|
|
||||||
|
|
||||||
if (errno == EADDRINUSE) {
|
|
||||||
/* In use, try next */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Some other bad failure, get out.. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
qemuProcessReturnPort(virQEMUDriverPtr driver,
|
|
||||||
int port)
|
|
||||||
{
|
|
||||||
if (port < driver->remotePortMin)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (virBitmapClearBit(driver->reservedRemotePorts,
|
|
||||||
port - driver->remotePortMin) < 0)
|
|
||||||
VIR_DEBUG("Could not mark port %d as unused", port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
||||||
virDomainChrDefPtr dev,
|
virDomainChrDefPtr dev,
|
||||||
@@ -3665,20 +3598,18 @@ int qemuProcessStart(virConnectPtr conn,
|
|||||||
if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
|
if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
|
||||||
!graphics->data.vnc.socket &&
|
!graphics->data.vnc.socket &&
|
||||||
graphics->data.vnc.autoport) {
|
graphics->data.vnc.autoport) {
|
||||||
int port = qemuProcessNextFreePort(driver, driver->remotePortMin);
|
unsigned short port;
|
||||||
if (port < 0) {
|
if (virPortAllocatorAcquire(driver->remotePorts, &port) < 0)
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
"%s", _("Unable to find an unused port for VNC"));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
graphics->data.vnc.port = port;
|
graphics->data.vnc.port = port;
|
||||||
} else if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
|
} else if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
|
||||||
int port = -1;
|
unsigned short port = 0;
|
||||||
if (graphics->data.spice.autoport ||
|
if (graphics->data.spice.autoport ||
|
||||||
graphics->data.spice.port == -1) {
|
graphics->data.spice.port == -1) {
|
||||||
port = qemuProcessNextFreePort(driver, driver->remotePortMin);
|
if (virPortAllocatorAcquire(driver->remotePorts, &port) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (port < 0) {
|
if (port == 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("Unable to find an unused port for SPICE"));
|
"%s", _("Unable to find an unused port for SPICE"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -3689,12 +3620,14 @@ int qemuProcessStart(virConnectPtr conn,
|
|||||||
if (driver->spiceTLS &&
|
if (driver->spiceTLS &&
|
||||||
(graphics->data.spice.autoport ||
|
(graphics->data.spice.autoport ||
|
||||||
graphics->data.spice.tlsPort == -1)) {
|
graphics->data.spice.tlsPort == -1)) {
|
||||||
int tlsPort = qemuProcessNextFreePort(driver,
|
unsigned short tlsPort;
|
||||||
graphics->data.spice.port + 1);
|
if (virPortAllocatorAcquire(driver->remotePorts, &tlsPort) < 0)
|
||||||
if (tlsPort < 0) {
|
goto cleanup;
|
||||||
|
|
||||||
|
if (tlsPort == 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
"%s", _("Unable to find an unused port for SPICE TLS"));
|
"%s", _("Unable to find an unused port for SPICE TLS"));
|
||||||
qemuProcessReturnPort(driver, port);
|
virPortAllocatorRelease(driver->remotePorts, port);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4363,12 +4296,15 @@ retry:
|
|||||||
virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
|
virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
|
||||||
if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
|
if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
|
||||||
graphics->data.vnc.autoport) {
|
graphics->data.vnc.autoport) {
|
||||||
qemuProcessReturnPort(driver, graphics->data.vnc.port);
|
ignore_value(virPortAllocatorRelease(driver->remotePorts,
|
||||||
|
graphics->data.vnc.port));
|
||||||
}
|
}
|
||||||
if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
|
if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE &&
|
||||||
graphics->data.spice.autoport) {
|
graphics->data.spice.autoport) {
|
||||||
qemuProcessReturnPort(driver, graphics->data.spice.port);
|
ignore_value(virPortAllocatorRelease(driver->remotePorts,
|
||||||
qemuProcessReturnPort(driver, graphics->data.spice.tlsPort);
|
graphics->data.spice.port));
|
||||||
|
ignore_value(virPortAllocatorRelease(driver->remotePorts,
|
||||||
|
graphics->data.spice.tlsPort));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user