When libvirtd exits it is leaving UNIX domain sockets on
the filesystem. These need to be removed.
The qemudInitPaths() method has signficant code churn to
switch from using a pre-allocated buffer on the stack, to
dynamically allocating on the heap.
* daemon/libvirtd.c, daemon/libvirtd.h: Store a reference
to the UNIX domain socket path and unlink it on shutdown
---
daemon/libvirtd.c | 127 ++++++++++++++++++++++++++++------------------------
daemon/libvirtd.h | 1 +
2 files changed, 69 insertions(+), 59 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index e86f78d..381b2df 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -533,7 +533,7 @@ static int qemudWritePidFile(const char *pidFile) {
}
static int qemudListenUnix(struct qemud_server *server,
- const char *path, int readonly, int auth) {
+ char *path, int readonly, int auth) {
struct qemud_socket *sock;
struct sockaddr_un addr;
mode_t oldmask;
@@ -549,6 +549,7 @@ static int qemudListenUnix(struct qemud_server *server,
sock->port = -1;
sock->type = QEMUD_SOCK_TYPE_UNIX;
sock->auth = auth;
+ sock->path = path;
if ((sock->fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
VIR_ERROR(_("Failed to create socket: %s"),
@@ -743,17 +744,30 @@ cleanup:
}
static int qemudInitPaths(struct qemud_server *server,
- char *sockname,
- char *roSockname,
- int maxlen)
+ char **sockname,
+ char **roSockname)
{
- char *sock_dir;
- char *dir_prefix = NULL;
- int ret = -1;
+ char *base_dir_prefix = NULL;
char *sock_dir_prefix = NULL;
+ int ret = -1;
+
+ /* The base_dir_prefix is the base under which all libvirtd
+ * files live */
+ if (server->privileged) {
+ if (!(base_dir_prefix = strdup (LOCAL_STATE_DIR)))
+ goto no_memory;
+ } else {
+ uid_t uid = geteuid();
+ if (!(base_dir_prefix = virGetUserDirectory(uid)))
+ goto cleanup;
+ }
+ /* The unix_sock_dir is the location under which all
+ * unix domain sockets live */
if (unix_sock_dir) {
- sock_dir = unix_sock_dir;
+ if (!(sock_dir_prefix = strdup(unix_sock_dir)))
+ goto no_memory;
+
/* Change the group ownership of /var/run/libvirt to unix_sock_gid */
if (server->privileged) {
if (chown(unix_sock_dir, -1, unix_sock_gid) < 0)
@@ -761,68 +775,53 @@ static int qemudInitPaths(struct qemud_server *server,
unix_sock_dir);
}
} else {
- sock_dir = sockname;
if (server->privileged) {
- dir_prefix = strdup (LOCAL_STATE_DIR);
- if (dir_prefix == NULL) {
- virReportOOMError();
- goto cleanup;
- }
- if (snprintf (sock_dir, maxlen, "%s/run/libvirt",
- dir_prefix) >= maxlen)
- goto snprintf_error;
+ if (virAsprintf(&sock_dir_prefix, "%s/run/libvirt",
+ base_dir_prefix) < 0)
+ goto no_memory;
} else {
- uid_t uid = geteuid();
- dir_prefix = virGetUserDirectory(uid);
- if (dir_prefix == NULL) {
- /* Do not diagnose here; virGetUserDirectory does that. */
- goto snprintf_error;
- }
-
- if (snprintf(sock_dir, maxlen, "%s/.libvirt", dir_prefix) >=
maxlen)
- goto snprintf_error;
+ if (virAsprintf(&sock_dir_prefix, "%s/.libvirt",
+ base_dir_prefix) < 0)
+ goto no_memory;
}
}
- sock_dir_prefix = strdup (sock_dir);
- if (!sock_dir_prefix) {
- virReportOOMError();
- goto cleanup;
- }
-
if (server->privileged) {
- if (snprintf (sockname, maxlen, "%s/libvirt-sock",
- sock_dir_prefix) >= maxlen
- || (snprintf (roSockname, maxlen, "%s/libvirt-sock-ro",
- sock_dir_prefix) >= maxlen))
- goto snprintf_error;
- unlink(sockname);
- unlink(roSockname);
+ if (virAsprintf(sockname, "%s/libvirt-sock",
+ sock_dir_prefix) < 0)
+ goto no_memory;
+ if (virAsprintf(roSockname, "%s/libvirt-sock-ro",
+ sock_dir_prefix) < 0)
+ goto no_memory;
+ unlink(*sockname);
+ unlink(*roSockname);
} else {
- if (snprintf(sockname, maxlen, "@%s/libvirt-sock",
- sock_dir_prefix) >= maxlen)
- goto snprintf_error;
+ if (virAsprintf(sockname, "@%s/libvirt-sock",
+ sock_dir_prefix) < 0)
+ goto no_memory;
+ /* There is no RO socket in unprivileged mode,
+ * since the user always has full RW access
+ * to their private instance */
}
if (server->privileged) {
- if (!(server->logDir = strdup (LOCAL_STATE_DIR "/log/libvirt")))
- virReportOOMError();
+ if (virAsprintf(&server->logDir, "%s/log/libvirt",
+ base_dir_prefix) < 0)
+ goto no_memory;
} else {
- if (virAsprintf(&server->logDir, "%s/.libvirt/log", dir_prefix)
< 0)
- virReportOOMError();
+ if (virAsprintf(&server->logDir, "%s/.libvirt/log",
+ base_dir_prefix) < 0)
+ goto no_memory;
}
- if (server->logDir == NULL)
- goto cleanup;
-
ret = 0;
- snprintf_error:
- if (ret)
- VIR_ERROR0(_("Resulting path too long for buffer in
qemudInitPaths()"));
+no_memory:
+ if (ret != 0)
+ virReportOOMError();
cleanup:
- VIR_FREE(dir_prefix);
+ VIR_FREE(base_dir_prefix);
VIR_FREE(sock_dir_prefix);
return ret;
}
@@ -931,22 +930,22 @@ static struct qemud_server *qemudInitialize(void) {
}
static int qemudNetworkInit(struct qemud_server *server) {
- char sockname[PATH_MAX];
- char roSockname[PATH_MAX];
+ char *sockname = NULL;
+ char *roSockname = NULL;
#if HAVE_SASL
int err;
#endif /* HAVE_SASL */
- roSockname[0] = '\0';
-
- if (qemudInitPaths(server, sockname, roSockname, PATH_MAX) < 0)
+ if (qemudInitPaths(server, &sockname, &roSockname) < 0)
goto cleanup;
if (qemudListenUnix(server, sockname, 0, auth_unix_rw) < 0)
goto cleanup;
+ sockname = NULL;
- if (roSockname[0] != '\0' && qemudListenUnix(server, roSockname, 1,
auth_unix_ro) < 0)
+ if (roSockname != NULL && qemudListenUnix(server, roSockname, 1,
auth_unix_ro) < 0)
goto cleanup;
+ roSockname = NULL;
#if HAVE_SASL
if (auth_unix_rw == REMOTE_AUTH_SASL ||
@@ -1057,6 +1056,8 @@ static int qemudNetworkInit(struct qemud_server *server) {
return 0;
cleanup:
+ VIR_FREE(sockname);
+ VIR_FREE(roSockname);
return -1;
}
@@ -1080,6 +1081,7 @@ static int qemudNetworkEnable(struct qemud_server *server) {
return 0;
}
+
static gnutls_session_t
remoteInitializeTLSSession (void)
{
@@ -2422,6 +2424,13 @@ static void qemudCleanup(struct qemud_server *server) {
if (sock->watch)
virEventRemoveHandleImpl(sock->watch);
close(sock->fd);
+
+ /* Unlink unix domain sockets which are not in
+ * the abstract namespace */
+ if (sock->path &&
+ sock->path[0] != '@')
+ unlink(sock->path);
+
VIR_FREE(sock);
sock = next;
}
diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h
index d292681..4d8e7e2 100644
--- a/daemon/libvirtd.h
+++ b/daemon/libvirtd.h
@@ -233,6 +233,7 @@ struct qemud_client {
struct qemud_socket {
+ char *path;
int fd;
int watch;
int readonly;
--
1.6.6.1