
Jim Meyering <jim@meyering.net> wrote:
Jim Meyering <jim@meyering.net> wrote:
"Daniel P. Berrange" <berrange@redhat.com> wrote: ...
The QEMU driver runs as non-root too. This is what the qemu:///session URI is used for. Likewise with the UML driver. The existing tests that invoke libvirtd fail quite frequently for me already due to them activating the QEMU / UML drivers. We really need a way to explicitly say what drivers should be allowed by the daemon, overriding what's compiled in. THis could in fact be useful even for production deployment, allowing site admins to guarentee that Xen driver is never used in the daemon even if it is compiled in by default.
So perhaps a couple of config params like
allowed_drivers = [ "qemu", "xen", "test" ] unix_sock_dir = "/var/run/libvirt/"
Not sure how best to hook the first one up to libvirt.so though - the virInitialize/virStateInitize calls always activate all of them, with no easy way to disable.
Sounds good. I'm deferring "allowed_drivers" for now, and preparing a patch to add support for a new configuration parameter
unix_sock_dir
and also for
log_dir
I'll add only unix_sock_dir for starters:
I've rebased this and made some minor improvements, like calling virReportOOMError and having a single exit point.
From 907671319b056495eef1d146dc9260a1a2fcb64c Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering@redhat.com> 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.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. (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 | 98 +++++++++++++++++++++++++++++++++------------------ 3 files changed, 67 insertions(+), 36 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..f8c3c97 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,71 @@ 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 (snprintf(server->logDir, PATH_MAX, "%s/.libvirt/log", + dir_prefix) >= PATH_MAX) + goto snprintf_error; - return 0; + 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) { @@ -2556,6 +2585,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 +2877,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], -- 1.6.2.rc0.173.g5e148