mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
Fix connection to already running session libvirtd
Since 1b807f92, connecting with virsh to an already running session libvirtd fails with: $ virsh list --all error: failed to connect to the hypervisor error: no valid connection error: Failed to connect socket to '/run/user/1000/libvirt/libvirt-sock': Transport endpoint is already connected This is caused by a logic error in virNetSocketNewConnectUnix: even if the connection to the daemon socket succeeded, we still try to spawn the daemon and then connect to it. This commit changes the logic to not try to spawn libvirtd if we successfully connected to its socket. Most of this commit is whitespace changes, use of -w is recommended to look at it.
This commit is contained in:
parent
c4d2a10238
commit
0f03ca6d29
@ -573,65 +573,67 @@ int virNetSocketNewConnectUNIX(const char *path,
|
||||
remoteAddr.data.un.sun_path[0] = '\0';
|
||||
|
||||
retry:
|
||||
if (connect(fd, &remoteAddr.data.sa, remoteAddr.len) < 0 && !spawnDaemon) {
|
||||
virReportSystemError(errno, _("Failed to connect socket to '%s'"),
|
||||
path);
|
||||
goto error;
|
||||
} else if (spawnDaemon) {
|
||||
int status = 0;
|
||||
pid_t pid = 0;
|
||||
|
||||
if ((passfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
virReportSystemError(errno, "%s", _("Failed to create socket"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to fork() here, because umask() is set
|
||||
* per-process, chmod() is racy and fchmod() has undefined
|
||||
* behaviour on sockets according to POSIX, so it doesn't
|
||||
* work outside Linux.
|
||||
*/
|
||||
if ((pid = virFork()) < 0)
|
||||
goto error;
|
||||
|
||||
if (pid == 0) {
|
||||
umask(0077);
|
||||
if (bind(passfd, &remoteAddr.data.sa, remoteAddr.len) < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (virProcessWait(pid, &status, false) < 0)
|
||||
goto error;
|
||||
|
||||
if (status != EXIT_SUCCESS) {
|
||||
/*
|
||||
* OK, so the subprocces failed to bind() the socket. This may mean
|
||||
* that another daemon was starting at the same time and succeeded
|
||||
* with its bind(). So we'll try connecting again, but this time
|
||||
* without spawning the daemon.
|
||||
*/
|
||||
spawnDaemon = false;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (listen(passfd, 0) < 0) {
|
||||
virReportSystemError(errno, "%s",
|
||||
_("Failed to listen on socket that's about "
|
||||
"to be passed to the daemon"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (connect(fd, &remoteAddr.data.sa, remoteAddr.len) < 0) {
|
||||
if (connect(fd, &remoteAddr.data.sa, remoteAddr.len) < 0) {
|
||||
if (!spawnDaemon) {
|
||||
virReportSystemError(errno, _("Failed to connect socket to '%s'"),
|
||||
path);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
int status = 0;
|
||||
pid_t pid = 0;
|
||||
|
||||
if (virNetSocketForkDaemon(binary, passfd) < 0)
|
||||
goto error;
|
||||
if ((passfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
virReportSystemError(errno, "%s", _("Failed to create socket"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to fork() here, because umask() is set
|
||||
* per-process, chmod() is racy and fchmod() has undefined
|
||||
* behaviour on sockets according to POSIX, so it doesn't
|
||||
* work outside Linux.
|
||||
*/
|
||||
if ((pid = virFork()) < 0)
|
||||
goto error;
|
||||
|
||||
if (pid == 0) {
|
||||
umask(0077);
|
||||
if (bind(passfd, &remoteAddr.data.sa, remoteAddr.len) < 0)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (virProcessWait(pid, &status, false) < 0)
|
||||
goto error;
|
||||
|
||||
if (status != EXIT_SUCCESS) {
|
||||
/*
|
||||
* OK, so the subprocces failed to bind() the socket. This may mean
|
||||
* that another daemon was starting at the same time and succeeded
|
||||
* with its bind(). So we'll try connecting again, but this time
|
||||
* without spawning the daemon.
|
||||
*/
|
||||
spawnDaemon = false;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (listen(passfd, 0) < 0) {
|
||||
virReportSystemError(errno, "%s",
|
||||
_("Failed to listen on socket that's about "
|
||||
"to be passed to the daemon"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (connect(fd, &remoteAddr.data.sa, remoteAddr.len) < 0) {
|
||||
virReportSystemError(errno, _("Failed to connect socket to '%s'"),
|
||||
path);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (virNetSocketForkDaemon(binary, passfd) < 0)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
localAddr.len = sizeof(localAddr.data);
|
||||
|
Loading…
x
Reference in New Issue
Block a user