mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Split out bind() from virPortAllocatorAcquire
This commit is contained in:
parent
ad95fa5957
commit
531bc0bbd0
@ -99,19 +99,59 @@ virPortAllocatorPtr virPortAllocatorNew(const char *name,
|
|||||||
return pa;
|
return pa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int virPortAllocatorBindToPort(bool *used,
|
||||||
|
unsigned short port)
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr = {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_port = htons(port),
|
||||||
|
.sin_addr.s_addr = htonl(INADDR_ANY)
|
||||||
|
};
|
||||||
|
int reuse = 1;
|
||||||
|
int ret = -1;
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
*used = false;
|
||||||
|
|
||||||
|
fd = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
virReportSystemError(errno, "%s", _("Unable to open test socket"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse,
|
||||||
|
sizeof(reuse)) < 0) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to set socket reuse addr flag"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
||||||
|
if (errno == EADDRINUSE) {
|
||||||
|
*used = true;
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
virReportSystemError(errno, _("Unable to bind to port %d"), port);
|
||||||
|
}
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
VIR_FORCE_CLOSE(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int virPortAllocatorAcquire(virPortAllocatorPtr pa,
|
int virPortAllocatorAcquire(virPortAllocatorPtr pa,
|
||||||
unsigned short *port)
|
unsigned short *port)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
size_t i;
|
size_t i;
|
||||||
int fd = -1;
|
|
||||||
|
|
||||||
*port = 0;
|
*port = 0;
|
||||||
virObjectLock(pa);
|
virObjectLock(pa);
|
||||||
|
|
||||||
for (i = pa->start; i <= pa->end && !*port; i++) {
|
for (i = pa->start; i <= pa->end && !*port; i++) {
|
||||||
int reuse = 1;
|
|
||||||
struct sockaddr_in addr;
|
|
||||||
bool used = false;
|
bool used = false;
|
||||||
|
|
||||||
if (virBitmapGetBit(pa->bitmap,
|
if (virBitmapGetBit(pa->bitmap,
|
||||||
@ -124,31 +164,10 @@ int virPortAllocatorAcquire(virPortAllocatorPtr pa,
|
|||||||
if (used)
|
if (used)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
if (virPortAllocatorBindToPort(&used, i) < 0)
|
||||||
addr.sin_port = htons(i);
|
|
||||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
fd = socket(PF_INET, SOCK_STREAM, 0);
|
|
||||||
if (fd < 0) {
|
|
||||||
virReportSystemError(errno, "%s",
|
|
||||||
_("Unable to open test socket"));
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&reuse, sizeof(reuse)) < 0) {
|
if (!used) {
|
||||||
virReportSystemError(errno, "%s",
|
|
||||||
_("Unable to set socket reuse addr flag"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
|
|
||||||
if (errno != EADDRINUSE) {
|
|
||||||
virReportSystemError(errno,
|
|
||||||
_("Unable to bind to port %zu"), i);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
/* In use, try next */
|
|
||||||
VIR_FORCE_CLOSE(fd);
|
|
||||||
} else {
|
|
||||||
/* Add port to bitmap of reserved ports */
|
/* Add port to bitmap of reserved ports */
|
||||||
if (virBitmapSetBit(pa->bitmap,
|
if (virBitmapSetBit(pa->bitmap,
|
||||||
i - pa->start) < 0) {
|
i - pa->start) < 0) {
|
||||||
@ -168,7 +187,6 @@ int virPortAllocatorAcquire(virPortAllocatorPtr pa,
|
|||||||
}
|
}
|
||||||
cleanup:
|
cleanup:
|
||||||
virObjectUnlock(pa);
|
virObjectUnlock(pa);
|
||||||
VIR_FORCE_CLOSE(fd);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user