Here's the result: FYI: additional incremental changes were: * qemud/qemud.h (struct qemud_server) [logDir]: Change type from char[PATH_MAX] to char*. * qemud/qemud.c: Adjust accordingly. (qemudCleanup): Free logDir. Here's the full patch: >From 367b5f9932afb5fac14837481ae9ea4f6187e8d4 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering@xxxxxxxxxx> Date: Mon, 12 Jan 2009 17:17:19 +0100 Subject: [PATCH] libvirtd: new config-file option: unix_sock_dir Before this change, the unix socket directory was hard-coded to be e.g., /var/run/libvirt for euid==0 and ~/.libvirt otherwise. With this change, you may now specify that directory in libvirtd's config file via a line like this: unix_sock_dir = "/var/run/libvirt". This is essential for running tests that do not impinge on any existing libvirtd process, and in running tests in parallel. * qemud/libvirtd.conf (unix_sock_dir): Add comment and example. * qemud/qemud.h (struct qemud_server) [logDir]: Change type from char[PATH_MAX] to char*. * qemud/qemud.c (unix_sock_dir): New global (remoteReadConfigFile): Set the global. (qemudInitPaths): Use the global, unix_sock_dir, if non-NULL. One minor improvement: unlink both sockets or none, never just one of them. (qemudCleanup): Free logDir. (main): Use the new global rather than hard-coding "/run/libvirt". * qemud/libvirtd.aug (sock_acl_entry): Add "unix_sock_dir". --- qemud/libvirtd.aug | 2 +- qemud/libvirtd.conf | 3 +- qemud/qemud.c | 103 ++++++++++++++++++++++++++++++++++----------------- qemud/qemud.h | 4 +- 4 files changed, 74 insertions(+), 38 deletions(-) diff --git a/qemud/libvirtd.aug b/qemud/libvirtd.aug index 40acd93..7406d23 100644 --- a/qemud/libvirtd.aug +++ b/qemud/libvirtd.aug @@ -35,6 +35,7 @@ module Libvirtd = let sock_acl_entry = str_entry "unix_sock_group" | str_entry "unix_sock_ro_perms" | str_entry "unix_sock_rw_perms" + | str_entry "unix_sock_dir" let authentication_entry = str_entry "auth_unix_ro" | str_entry "auth_unix_rw" @@ -79,4 +80,3 @@ module Libvirtd = . Util.stdexcl let xfm = transform lns filter - diff --git a/qemud/libvirtd.conf b/qemud/libvirtd.conf index 4932084..1fd5918 100644 --- a/qemud/libvirtd.conf +++ b/qemud/libvirtd.conf @@ -97,7 +97,8 @@ # control then you may want to relax this to: #unix_sock_rw_perms = "0770" - +# Set the name of the directory in which sockets will be found/created. +#unix_sock_dir = "/var/run/libvirt" ################################################################# # diff --git a/qemud/qemud.c b/qemud/qemud.c index a4add5a..ca6357c 100644 --- a/qemud/qemud.c +++ b/qemud/qemud.c @@ -51,6 +51,8 @@ #include "libvirt_internal.h" #include "virterror_internal.h" +#define VIR_FROM_THIS VIR_FROM_QEMU + #include "qemud.h" #include "util.h" #include "remote_internal.h" @@ -136,6 +138,8 @@ static char *listen_addr = (char *) LIBVIRTD_LISTEN_ADDR; static char *tls_port = (char *) LIBVIRTD_TLS_PORT; static char *tcp_port = (char *) LIBVIRTD_TCP_PORT; +static char *unix_sock_dir = NULL; + #if HAVE_POLKIT static int auth_unix_rw = REMOTE_AUTH_POLKIT; static int auth_unix_ro = REMOTE_AUTH_POLKIT; @@ -712,46 +716,75 @@ static int qemudInitPaths(struct qemud_server *server, int maxlen) { uid_t uid = geteuid(); + char *sock_dir; + char *dir_prefix = NULL; + int ret = -1; + char *sock_dir_prefix = NULL; + + if (unix_sock_dir) + sock_dir = unix_sock_dir; + else { + sock_dir = sockname; + if (uid == SYSTEM_UID) { + dir_prefix = strdup (LOCAL_STATE_DIR); + if (dir_prefix == NULL) { + virReportOOMError(NULL); + goto cleanup; + } + if (snprintf (sock_dir, maxlen, "%s/run/libvirt", + dir_prefix) >= maxlen) + goto snprintf_error; + } else { + dir_prefix = virGetUserDirectory(NULL, uid); + if (dir_prefix == NULL) { + /* Do not diagnose here; virGetUserDirectory does that. */ + goto snprintf_error; + } - if (uid == SYSTEM_UID) { - if (snprintf (sockname, maxlen, "%s/run/libvirt/libvirt-sock", - LOCAL_STATE_DIR) >= maxlen) - goto snprintf_error; + if (snprintf(sock_dir, maxlen, "%s/.libvirt", dir_prefix) >= maxlen) + goto snprintf_error; + } + } - unlink(sockname); + sock_dir_prefix = strdup (sock_dir); + if (!sock_dir_prefix) { + virReportOOMError(NULL); + goto cleanup; + } - if (snprintf (roSockname, maxlen, "%s/run/libvirt/libvirt-sock-ro", - LOCAL_STATE_DIR) >= maxlen) + if (uid == SYSTEM_UID) { + 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 (snprintf(server->logDir, PATH_MAX, "%s/log/libvirt/", LOCAL_STATE_DIR) >= PATH_MAX) - goto snprintf_error; } else { - char *userdir = virGetUserDirectory(NULL, uid); - if (userdir == NULL) { - /* Do not diagnose here; virGetUserDirectory does that. */ - return -1; - } - - if (snprintf(sockname, maxlen, "@%s/.libvirt/libvirt-sock", userdir) >= maxlen) { - VIR_FREE(userdir); + if (snprintf(sockname, maxlen, "@%s/libvirt-sock", + sock_dir_prefix) >= maxlen) goto snprintf_error; - } + } - if (snprintf(server->logDir, PATH_MAX, "%s/.libvirt/log", userdir) >= PATH_MAX) { - VIR_FREE(userdir); - goto snprintf_error; - } - VIR_FREE(userdir); - } /* !remote */ + if (uid == SYSTEM_UID) + server->logDir = strdup (LOCAL_STATE_DIR "/log/libvirt"); + else + virAsprintf(&server->logDir, "%s/.libvirt/log", dir_prefix); - return 0; + if (server->logDir == NULL) + virReportOOMError(NULL); + + ret = 0; snprintf_error: - VIR_ERROR("%s", _("Resulting path too long for buffer in qemudInitPaths()")); - return -1; + if (ret) + VIR_ERROR("%s", + _("Resulting path too long for buffer in qemudInitPaths()")); + + cleanup: + free (dir_prefix); + free (sock_dir_prefix); + return ret; } static struct qemud_server *qemudInitialize(int sigread) { @@ -2208,6 +2241,7 @@ static void qemudCleanup(struct qemud_server *server) { free(sock); sock = next; } + free(server->logDir); #ifdef HAVE_SASL if (server->saslUsernameWhitelist) { @@ -2556,6 +2590,8 @@ remoteReadConfigFile (struct qemud_server *server, const char *filename) unix_sock_rw_perms = NULL; } + GET_CONF_STR (conf, filename, unix_sock_dir); + GET_CONF_INT (conf, filename, mdns_adv); GET_CONF_STR (conf, filename, mdns_name); @@ -2846,11 +2882,10 @@ int main(int argc, char **argv) { goto error2; /* Change the group ownership of /var/run/libvirt to unix_sock_gid */ - if (getuid() == 0) { - const char *sockdirname = LOCAL_STATE_DIR "/run/libvirt"; - - if (chown(sockdirname, -1, unix_sock_gid) < 0) - VIR_ERROR(_("Failed to change group ownership of %s"), sockdirname); + if (unix_sock_dir && geteuid() == 0) { + if (chown(unix_sock_dir, -1, unix_sock_gid) < 0) + VIR_ERROR(_("Failed to change group ownership of %s"), + unix_sock_dir); } if (virEventAddHandleImpl(sigpipe[0], diff --git a/qemud/qemud.h b/qemud/qemud.h index 7938f89..4ddbc41 100644 --- a/qemud/qemud.h +++ b/qemud/qemud.h @@ -1,7 +1,7 @@ /* * qemud.h: daemon data structure definitions * - * Copyright (C) 2006-2008 Red Hat, Inc. + * Copyright (C) 2006-2009 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -181,7 +181,7 @@ struct qemud_server { struct qemud_client **clients; int sigread; - char logDir[PATH_MAX]; + char *logDir; unsigned int shutdown : 1; #ifdef HAVE_AVAHI struct libvirtd_mdns *mdns; -- 1.6.2.rc0.173.g5e148 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list