[libvirt] [PATCH 00/29] Split the libvirtd daemon into per-driver daemons

This is what all the driver refactoring I've done has been about enabling. We gain new daemons for each driver, for the primary virt drivers: virtlibxld virtlxcd virtqemud virtvboxd virtvzd And again for the secondary drivers virtinterfaced virtnetworkd virtnodedevd virtnwfilterd virtsecretd virtstoraged Finally to support IP connectivity, and also the legacy lbivirtd UNIX domain socket (for the old libvirt remote driver SSH tunnelling): virtproxyd The the sake of facilitating upgrades, the existing libvirtd still exists and works the same way it always has. You either run libvirtd, or you run the per-driver daemons, never both. The remote driver will look to see whether libvirtd is running to figure out whether to connect to libvirtd or the new per-driver daemons. When auto-spawning daemons for nonroot users, we default to spawning the per-driver daemons. This can be controlled with a UR parameter "?mode=direct|legacy|auto", where 'direct' means per-driver and 'legacy' means libvirtd (or indirect via virtproxyd if that's running). Still todo - Add systemd unit files for the new daemons - Make it possible to disable build of libvirtd, or of the per-driver daemons so downstream vendors can decide which to ship - Tuning of the daemon defaults for worker threads to better suit the fact that we have per-driver daemons - More work on RPM packaging to allow install of per-driver daemosn without pulling in libvirtd too - A bunch of stuff that doesn't occurr to me right now - Identify & fix more bugs I've created here Daniel P. Berrangé (29): rpc: add API for checking whether an auth scheme is in use on a server remote: simplify libvirtd code for deciding if SASL auth is needed logging: pass binary name not logfile name when enabling logging remote: conditionalize socket names in libvirtd daemon remote: conditionalize daemon name in libvirtd daemon remote: conditionalize driver loading in libvirtd daemon remote: conditionalize IP socket usage in libvirtd daemon remote: conditionalize IP socket config in libvirtd.conf remote: conditionalize IP socket config in augeas definitions remote: refactor & rename variables for building libvirtd secret: introduce virtsecretd daemon network: introduce virtnetworkd daemon interface: introduce virtinterfaced daemon storage: introduce virtstoraged daemon nodedev: introduce virtnodedevd daemon nwfilter: introduce virtnwfilterd daemon libxl: introduce virtlibxld daemon qemu: introduce virtqemud daemon lxc: introduce virtlxcd daemon vbox: introduce virtvboxd daemon bhyve: introduce virtbhyved daemon vz: introduce virtvzd daemon remote: introduce virtproxyd daemon to handle IP connectivity remote: open secondary drivers via remote driver if needed remote: use enum helpers for parsing remote driver transport remote: refactor the code for choosing the UNIX socket path remote: switch to connect to per-driver daemons by default all: don't wait for driver lock during startup interface: fix driver name in state directory path .gitignore | 12 + build-aux/augeas-gentest.pl | 2 +- libvirt.spec.in | 10 + src/bhyve/Makefile.inc.am | 14 + src/bhyve/bhyve_driver.c | 2 +- src/driver.h | 2 + src/interface/Makefile.inc.am | 14 + src/interface/interface_backend_netcf.c | 6 +- src/interface/interface_backend_udev.c | 6 +- src/libvirt.c | 24 ++ src/libvirt_remote.syms | 1 + src/libxl/Makefile.inc.am | 14 + src/libxl/libxl_driver.c | 2 +- src/locking/lock_daemon.c | 2 +- src/logging/log_daemon.c | 2 +- src/lxc/Makefile.inc.am | 15 + src/lxc/lxc_driver.c | 2 +- src/network/Makefile.inc.am | 14 + src/network/leaseshelper.c | 2 +- src/node_device/Makefile.inc.am | 14 + src/node_device/node_device_hal.c | 2 +- src/node_device/node_device_udev.c | 2 +- src/nwfilter/Makefile.inc.am | 14 + src/nwfilter/nwfilter_driver.c | 2 +- src/qemu/Makefile.inc.am | 14 + src/qemu/qemu_driver.c | 2 +- src/remote/Makefile.inc.am | 153 ++++--- src/remote/{libvirtd.aug => libvirtd.aug.in} | 24 +- .../{libvirtd.conf => libvirtd.conf.in} | 42 +- src/remote/remote_daemon.c | 221 +++++++--- src/remote/remote_daemon_config.c | 41 +- src/remote/remote_daemon_config.h | 9 +- src/remote/remote_daemon_dispatch.c | 82 +++- src/remote/remote_driver.c | 391 ++++++++++++------ src/remote/remote_driver.h | 4 - src/remote/test_libvirtd.aug.in | 16 +- src/rpc/virnetserver.c | 17 + src/rpc/virnetserver.h | 3 + src/secret/Makefile.inc.am | 14 + src/secret/secret_driver.c | 2 +- src/storage/Makefile.inc.am | 14 + src/util/virlog.c | 20 +- src/vbox/Makefile.inc.am | 14 + src/vz/Makefile.inc.am | 14 + src/vz/vz_driver.c | 2 +- 45 files changed, 938 insertions(+), 341 deletions(-) rename src/remote/{libvirtd.aug => libvirtd.aug.in} (88%) rename src/remote/{libvirtd.conf => libvirtd.conf.in} (95%) -- 2.21.0

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/libvirt_remote.syms | 1 + src/rpc/virnetserver.c | 17 +++++++++++++++++ src/rpc/virnetserver.h | 3 +++ 3 files changed, 21 insertions(+) diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms index 99fe3dd07c..17d656fb3f 100644 --- a/src/libvirt_remote.syms +++ b/src/libvirt_remote.syms @@ -124,6 +124,7 @@ virNetServerGetMaxUnauthClients; virNetServerGetName; virNetServerGetThreadPoolParameters; virNetServerHasClients; +virNetServerNeedsAuth; virNetServerNew; virNetServerNewPostExecRestart; virNetServerNextClientID; diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 0f3fa63fbb..19f49ba4c3 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -953,6 +953,23 @@ virNetServerGetCurrentUnauthClients(virNetServerPtr srv) return ret; } + +bool virNetServerNeedsAuth(virNetServerPtr srv, + int auth) +{ + bool ret = false; + size_t i; + + virObjectLock(srv); + for (i = 0; i < srv->nservices; i++) { + if (virNetServerServiceGetAuth(srv->services[i]) == auth) + ret = true; + } + virObjectUnlock(srv); + + return ret; +} + int virNetServerGetClients(virNetServerPtr srv, virNetServerClientPtr **clts) diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h index 6b2541588c..4d4afd51b4 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -96,6 +96,9 @@ unsigned long long virNetServerNextClientID(virNetServerPtr srv); virNetServerClientPtr virNetServerGetClient(virNetServerPtr srv, unsigned long long id); +bool virNetServerNeedsAuth(virNetServerPtr srv, + int auth); + int virNetServerGetClients(virNetServerPtr srv, virNetServerClientPtr **clients); -- 2.21.0

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_daemon.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index fdc9e4333a..0dabd3dff8 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -534,15 +534,10 @@ daemonSetupNetworking(virNetServerPtr srv, } #if WITH_SASL - if (config->auth_unix_rw == REMOTE_AUTH_SASL || - (sock_path_ro && config->auth_unix_ro == REMOTE_AUTH_SASL) || - (ipsock && config->listen_tls && config->auth_tls == REMOTE_AUTH_SASL) || - (ipsock && config->listen_tcp && config->auth_tcp == REMOTE_AUTH_SASL)) { - saslCtxt = virNetSASLContextNewServer( - (const char *const*)config->sasl_allowed_username_list); - if (!saslCtxt) + if (virNetServerNeedsAuth(srv, REMOTE_AUTH_SASL) && + !(saslCtxt = virNetSASLContextNewServer( + (const char *const*)config->sasl_allowed_username_list))) goto cleanup; - } #endif ret = 0; -- 2.21.0

Instead of having each caller pass in the desired logfile name, pass in the binary name instead. The logging code can then just derive a logfile name by appending ".log". Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/locking/lock_daemon.c | 2 +- src/logging/log_daemon.c | 2 +- src/remote/remote_daemon.c | 2 +- src/util/virlog.c | 20 ++++++++++---------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c index bc2fb4a7fb..7cdcd61722 100644 --- a/src/locking/lock_daemon.c +++ b/src/locking/lock_daemon.c @@ -532,7 +532,7 @@ virLockDaemonSetupLogging(virLockDaemonConfigPtr config, /* Define the default output. This is only applied if there was no setting * from either the config or the environment. */ - if (virLogSetDefaultOutput("virtlockd.log", godaemon, privileged) < 0) + if (virLogSetDefaultOutput("virtlockd", godaemon, privileged) < 0) return -1; if (virLogGetNbOutputs() == 0) diff --git a/src/logging/log_daemon.c b/src/logging/log_daemon.c index 014596b280..c8de7aa687 100644 --- a/src/logging/log_daemon.c +++ b/src/logging/log_daemon.c @@ -467,7 +467,7 @@ virLogDaemonSetupLogging(virLogDaemonConfigPtr config, /* Define the default output. This is only applied if there was no setting * from either the config or the environment. */ - if (virLogSetDefaultOutput("virtlogd.log", godaemon, privileged) < 0) + if (virLogSetDefaultOutput("virtlogd", godaemon, privileged) < 0) return -1; if (virLogGetNbOutputs() == 0) diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index 0dabd3dff8..574c50075f 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -605,7 +605,7 @@ daemonSetupLogging(struct daemonConfig *config, /* Define the default output. This is only applied if there was no setting * from either the config or the environment. */ - if (virLogSetDefaultOutput("libvirtd.log", godaemon, privileged) < 0) + if (virLogSetDefaultOutput("libvirtd", godaemon, privileged) < 0) return -1; if (virLogGetNbOutputs() == 0) diff --git a/src/util/virlog.c b/src/util/virlog.c index 248ce19902..da433878df 100644 --- a/src/util/virlog.c +++ b/src/util/virlog.c @@ -175,7 +175,7 @@ virLogSetDefaultOutputToJournald(void) static int -virLogSetDefaultOutputToFile(const char *filename, bool privileged) +virLogSetDefaultOutputToFile(const char *binary, bool privileged) { int ret = -1; char *logdir = NULL; @@ -183,8 +183,8 @@ virLogSetDefaultOutputToFile(const char *filename, bool privileged) if (privileged) { if (virAsprintf(&virLogDefaultOutput, - "%d:file:%s/log/libvirt/%s", virLogDefaultPriority, - LOCALSTATEDIR, filename) < 0) + "%d:file:%s/log/libvirt/%s.log", virLogDefaultPriority, + LOCALSTATEDIR, binary) < 0) goto cleanup; } else { if (!(logdir = virGetUserCacheDirectory())) @@ -197,8 +197,8 @@ virLogSetDefaultOutputToFile(const char *filename, bool privileged) } umask(old_umask); - if (virAsprintf(&virLogDefaultOutput, "%d:file:%s/%s", - virLogDefaultPriority, logdir, filename) < 0) + if (virAsprintf(&virLogDefaultOutput, "%d:file:%s/%s.log", + virLogDefaultPriority, logdir, binary) < 0) goto cleanup; } @@ -211,19 +211,19 @@ virLogSetDefaultOutputToFile(const char *filename, bool privileged) /* * virLogSetDefaultOutput: - * @filename: the file that the output should be redirected to (only needed - * when @godaemon equals true + * @binary: the binary for which logging is performed. The log file name + * will be derived from the binary name, with ".log" appended. * @godaemon: whether we're running daemonized * @privileged: whether we're running with root privileges or not (session) * * Decides on what the default output (journald, file, stderr) should be - * according to @filename, @godaemon, @privileged. This function should be run + * according to @binary, @godaemon, @privileged. This function should be run * exactly once at daemon startup, so no locks are used. * * Returns 0 on success, -1 in case of a failure. */ int -virLogSetDefaultOutput(const char *filename, bool godaemon, bool privileged) +virLogSetDefaultOutput(const char *binary, bool godaemon, bool privileged) { bool have_journald = access("/run/systemd/journal/socket", W_OK) >= 0; @@ -237,7 +237,7 @@ virLogSetDefaultOutput(const char *filename, bool godaemon, bool privileged) return virLogSetDefaultOutputToStderr(); } - return virLogSetDefaultOutputToFile(filename, privileged); + return virLogSetDefaultOutputToFile(binary, privileged); } -- 2.21.0

Prepare for reusing libvirtd source to create other daemons by making the socket names conditionally defined by the make rules. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/Makefile.inc.am | 3 +++ src/remote/remote_daemon.c | 27 ++++++++++++++------------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index 851ab903fd..b41f14222a 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -143,6 +143,9 @@ libvirtd_CFLAGS = \ -I$(srcdir)/access \ -I$(srcdir)/conf \ -I$(srcdir)/rpc \ + -DSOCK_NAME="\"libvirt-sock\"" \ + -DSOCK_NAME_RO="\"libvirt-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"libvirt-admin-sock\"" \ $(NULL) libvirtd_LDFLAGS = \ diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index 574c50075f..8ab3c21ef8 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -220,19 +220,19 @@ daemonUnixSocketPaths(struct daemonConfig *config, char *rundir = NULL; if (config->unix_sock_dir) { - if (virAsprintf(sockfile, "%s/libvirt-sock", config->unix_sock_dir) < 0) + if (virAsprintf(sockfile, "%s/" SOCK_NAME, config->unix_sock_dir) < 0) goto cleanup; if (privileged) { - if (virAsprintf(rosockfile, "%s/libvirt-sock-ro", config->unix_sock_dir) < 0 || - virAsprintf(admsockfile, "%s/libvirt-admin-sock", config->unix_sock_dir) < 0) + if (virAsprintf(rosockfile, "%s/" SOCK_NAME_RO, config->unix_sock_dir) < 0 || + virAsprintf(admsockfile, "%s/" SOCK_NAME_ADMIN, config->unix_sock_dir) < 0) goto cleanup; } } else { if (privileged) { - if (VIR_STRDUP(*sockfile, LOCALSTATEDIR "/run/libvirt/libvirt-sock") < 0 || - VIR_STRDUP(*rosockfile, LOCALSTATEDIR "/run/libvirt/libvirt-sock-ro") < 0 || - VIR_STRDUP(*admsockfile, LOCALSTATEDIR "/run/libvirt/libvirt-admin-sock") < 0) + if (VIR_STRDUP(*sockfile, LOCALSTATEDIR "/run/libvirt/" SOCK_NAME) < 0 || + VIR_STRDUP(*rosockfile, LOCALSTATEDIR "/run/libvirt/" SOCK_NAME_RO) < 0 || + VIR_STRDUP(*admsockfile, LOCALSTATEDIR "/run/libvirt/" SOCK_NAME_ADMIN) < 0) goto cleanup; } else { mode_t old_umask; @@ -247,8 +247,8 @@ daemonUnixSocketPaths(struct daemonConfig *config, } umask(old_umask); - if (virAsprintf(sockfile, "%s/libvirt-sock", rundir) < 0 || - virAsprintf(admsockfile, "%s/libvirt-admin-sock", rundir) < 0) + if (virAsprintf(sockfile, "%s/" SOCK_NAME, rundir) < 0 || + virAsprintf(admsockfile, "%s/" SOCK_NAME_ADMIN, rundir) < 0) goto cleanup; } } @@ -910,14 +910,14 @@ daemonUsage(const char *argv0, bool privileged) " %s/run/libvirtd.pid\n" "\n"), LIBVIRTD_CONFIGURATION_FILE, - LIBVIRTD_PRIV_UNIX_SOCKET, - LIBVIRTD_PRIV_UNIX_SOCKET_RO, + LOCALSTATEDIR "/run/libvirt/" SOCK_NAME, + LOCALSTATEDIR "/run/libvirt/" SOCK_NAME_RO, LIBVIRT_CACERT, LIBVIRT_SERVERCERT, LIBVIRT_SERVERKEY, LOCALSTATEDIR); } else { - fprintf(stderr, "%s", + fprintf(stderr, _("\n" " Default paths:\n" "\n" @@ -925,7 +925,7 @@ daemonUsage(const char *argv0, bool privileged) " $XDG_CONFIG_HOME/libvirt/libvirtd.conf\n" "\n" " Sockets:\n" - " $XDG_RUNTIME_DIR/libvirt/libvirt-sock\n" + " $XDG_RUNTIME_DIR/libvirt/%s\n" "\n" " TLS:\n" " CA certificate: $HOME/.pki/libvirt/cacert.pem\n" @@ -934,7 +934,8 @@ daemonUsage(const char *argv0, bool privileged) "\n" " PID file:\n" " $XDG_RUNTIME_DIR/libvirt/libvirtd.pid\n" - "\n")); + "\n"), + SOCK_NAME); } } -- 2.21.0

Prepare for reusing libvirtd source to create other daemons by making the daemon name conditionally defined by the make rules. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/Makefile.inc.am | 1 + src/remote/remote_daemon.c | 34 +++++++++++++++++-------------- src/remote/remote_daemon_config.c | 5 +++-- src/remote/remote_driver.h | 1 - 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index b41f14222a..ba385aac4d 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -146,6 +146,7 @@ libvirtd_CFLAGS = \ -DSOCK_NAME="\"libvirt-sock\"" \ -DSOCK_NAME_RO="\"libvirt-sock-ro\"" \ -DSOCK_NAME_ADMIN="\"libvirt-admin-sock\"" \ + -DDAEMON_NAME="\"libvirtd\"" \ $(NULL) libvirtd_LDFLAGS = \ diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index 8ab3c21ef8..1a301a1e14 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -63,7 +63,7 @@ #include "virdbus.h" -VIR_LOG_INIT("daemon.libvirtd"); +VIR_LOG_INIT("daemon." DAEMON_NAME); #if WITH_SASL virNetSASLContextPtr saslCtxt = NULL; @@ -564,7 +564,7 @@ daemonSetupNetDevOpenvswitch(struct daemonConfig *config) /* * Set up the logging environment - * By default if daemonized all errors go to the logfile libvirtd.log, + * By default if daemonized all errors go to journald/a logfile * but if verbose or error debugging is asked for then also output * informational and debug messages. Default size if 64 kB. */ @@ -577,7 +577,7 @@ daemonSetupLogging(struct daemonConfig *config, virLogReset(); /* - * Libvirtd's order of precedence is: + * Logging setup order of precedence is: * cmdline > environment > config * * Given the precedence, we must process the variables in the opposite @@ -605,7 +605,7 @@ daemonSetupLogging(struct daemonConfig *config, /* Define the default output. This is only applied if there was no setting * from either the config or the environment. */ - if (virLogSetDefaultOutput("libvirtd", godaemon, privileged) < 0) + if (virLogSetDefaultOutput(DAEMON_NAME, godaemon, privileged) < 0) return -1; if (virLogGetNbOutputs() == 0) @@ -717,7 +717,7 @@ static void daemonStopWorker(void *opaque) VIR_DEBUG("Completed stop dmn=%p", dmn); - /* Exit libvirtd cleanly */ + /* Exit daemon cleanly */ virNetDaemonQuit(dmn); } @@ -796,7 +796,7 @@ static void daemonRunStateInit(void *opaque) driversInitialized = true; #ifdef WITH_DBUS - /* Tie the non-privileged libvirtd to the session/shutdown lifecycle */ + /* Tie the non-privileged daemons to the session/shutdown lifecycle */ if (!virNetDaemonIsPrivileged(dmn)) { sessionBus = virDBusGetSessionBus(); @@ -895,7 +895,7 @@ daemonUsage(const char *argv0, bool privileged) " Default paths:\n" "\n" " Configuration file (unless overridden by -f):\n" - " %s\n" + " %s/libvirt/%s.conf\n" "\n" " Sockets:\n" " %s\n" @@ -907,22 +907,24 @@ daemonUsage(const char *argv0, bool privileged) " Server private key: %s\n" "\n" " PID file (unless overridden by -p):\n" - " %s/run/libvirtd.pid\n" + " %s/run/%s.pid\n" "\n"), - LIBVIRTD_CONFIGURATION_FILE, + SYSCONFDIR, + DAEMON_NAME, LOCALSTATEDIR "/run/libvirt/" SOCK_NAME, LOCALSTATEDIR "/run/libvirt/" SOCK_NAME_RO, LIBVIRT_CACERT, LIBVIRT_SERVERCERT, LIBVIRT_SERVERKEY, - LOCALSTATEDIR); + LOCALSTATEDIR, + DAEMON_NAME); } else { fprintf(stderr, _("\n" " Default paths:\n" "\n" " Configuration file (unless overridden by -f):\n" - " $XDG_CONFIG_HOME/libvirt/libvirtd.conf\n" + " $XDG_CONFIG_HOME/libvirt/%s.conf\n" "\n" " Sockets:\n" " $XDG_RUNTIME_DIR/libvirt/%s\n" @@ -933,9 +935,11 @@ daemonUsage(const char *argv0, bool privileged) " Server private key: $HOME/.pki/libvirt/serverkey.pem\n" "\n" " PID file:\n" - " $XDG_RUNTIME_DIR/libvirt/libvirtd.pid\n" + " $XDG_RUNTIME_DIR/libvirt/%s.pid\n" "\n"), - SOCK_NAME); + DAEMON_NAME, + SOCK_NAME, + DAEMON_NAME); } } @@ -1099,7 +1103,7 @@ int main(int argc, char **argv) { if (!pid_file && virPidFileConstructPath(privileged, LOCALSTATEDIR, - "libvirtd", + DAEMON_NAME, &pid_file) < 0) { VIR_ERROR(_("Can't determine pid file path.")); exit(EXIT_FAILURE); @@ -1179,7 +1183,7 @@ int main(int argc, char **argv) { goto cleanup; } - if (!(srv = virNetServerNew("libvirtd", 1, + if (!(srv = virNetServerNew(DAEMON_NAME, 1, config->min_workers, config->max_workers, config->prio_workers, diff --git a/src/remote/remote_daemon_config.c b/src/remote/remote_daemon_config.c index 537b90a855..3e62b4203f 100644 --- a/src/remote/remote_daemon_config.c +++ b/src/remote/remote_daemon_config.c @@ -77,7 +77,8 @@ int daemonConfigFilePath(bool privileged, char **configfile) { if (privileged) { - if (VIR_STRDUP(*configfile, SYSCONFDIR "/libvirt/libvirtd.conf") < 0) + if (VIR_STRDUP(*configfile, + SYSCONFDIR "/libvirt/" DAEMON_NAME ".conf") < 0) goto error; } else { char *configdir = NULL; @@ -85,7 +86,7 @@ daemonConfigFilePath(bool privileged, char **configfile) if (!(configdir = virGetUserConfigDirectory())) goto error; - if (virAsprintf(configfile, "%s/libvirtd.conf", configdir) < 0) { + if (virAsprintf(configfile, "%s/%s.conf", configdir, DAEMON_NAME) < 0) { VIR_FREE(configdir); goto error; } diff --git a/src/remote/remote_driver.h b/src/remote/remote_driver.h index 8c7da6b000..132e478ef3 100644 --- a/src/remote/remote_driver.h +++ b/src/remote/remote_driver.h @@ -34,7 +34,6 @@ unsigned long remoteVersion(void); #define LIBVIRTD_PRIV_UNIX_SOCKET LOCALSTATEDIR "/run/libvirt/libvirt-sock" #define LIBVIRTD_PRIV_UNIX_SOCKET_RO LOCALSTATEDIR "/run/libvirt/libvirt-sock-ro" #define LIBVIRTD_USER_UNIX_SOCKET "libvirt-sock" -#define LIBVIRTD_CONFIGURATION_FILE SYSCONFDIR "/libvirt/libvirtd.conf" /* Defaults for PKI directory. */ #define LIBVIRT_PKI_DIR SYSCONFDIR "/pki" -- 2.21.0

Prepare for reusing libvirtd source to create other daemons by making the driver(s) to load conditionally defined by the make rules. If nothing is set, all drivers will be loaded, ignoring any missing ones as historically done. If MODULE_NAME is set only one driver will be loaded and that one must succeed. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_daemon.c | 51 +++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index 1a301a1e14..e1fb081bfe 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -298,6 +298,10 @@ static int daemonErrorLogFilter(virErrorPtr err, int priority) static int daemonInitialize(void) { +#ifdef MODULE_NAME + if (virDriverLoadModule(MODULE_NAME, MODULE_NAME "Register", true) < 0) + return -1; +#else /* * Note that the order is important: the first ones have a higher * priority when calling virStateInitialize. We must register the @@ -305,53 +309,54 @@ static int daemonInitialize(void) * driver, since their resources must be auto-started before any * domains can be auto-started. */ -#ifdef WITH_NETWORK +# ifdef WITH_NETWORK if (virDriverLoadModule("network", "networkRegister", false) < 0) return -1; -#endif -#ifdef WITH_INTERFACE +# endif +# ifdef WITH_INTERFACE if (virDriverLoadModule("interface", "interfaceRegister", false) < 0) return -1; -#endif -#ifdef WITH_SECRETS +# endif +# ifdef WITH_SECRETS if (virDriverLoadModule("secret", "secretRegister", false) < 0) return -1; -#endif -#ifdef WITH_STORAGE +# endif +# ifdef WITH_STORAGE if (virDriverLoadModule("storage", "storageRegister", false) < 0) return -1; -#endif -#ifdef WITH_NODE_DEVICES +# endif +# ifdef WITH_NODE_DEVICES if (virDriverLoadModule("nodedev", "nodedevRegister", false) < 0) return -1; -#endif -#ifdef WITH_NWFILTER +# endif +# ifdef WITH_NWFILTER if (virDriverLoadModule("nwfilter", "nwfilterRegister", false) < 0) return -1; -#endif -#ifdef WITH_LIBXL +# endif +# ifdef WITH_LIBXL if (virDriverLoadModule("libxl", "libxlRegister", false) < 0) return -1; -#endif -#ifdef WITH_QEMU +# endif +# ifdef WITH_QEMU if (virDriverLoadModule("qemu", "qemuRegister", false) < 0) return -1; -#endif -#ifdef WITH_LXC +# endif +# ifdef WITH_LXC if (virDriverLoadModule("lxc", "lxcRegister", false) < 0) return -1; -#endif -#ifdef WITH_VBOX +# endif +# ifdef WITH_VBOX if (virDriverLoadModule("vbox", "vboxRegister", false) < 0) return -1; -#endif -#ifdef WITH_BHYVE +# endif +# ifdef WITH_BHYVE if (virDriverLoadModule("bhyve", "bhyveRegister", false) < 0) return -1; -#endif -#ifdef WITH_VZ +# endif +# ifdef WITH_VZ if (virDriverLoadModule("vz", "vzRegister", false) < 0) return -1; +# endif #endif return 0; } -- 2.21.0

Prepare for reusing libvirtd source to create other daemons by making the use of IP sockets conditionally defined by the make rules. The main libvirtd daemon will retain IP listen ability, but all the driver specific daemons will be local UNIX sockets only. Apps needing IP connectivity will connect via the libvirtd daemon which will proxy to the driver specfic daemon. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/Makefile.inc.am | 1 + src/remote/remote_daemon.c | 90 ++++++++++++++++++++++++++++--- src/remote/remote_daemon_config.c | 36 +++++++++---- src/remote/remote_daemon_config.h | 9 +++- 4 files changed, 119 insertions(+), 17 deletions(-) diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index ba385aac4d..25921437e2 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -147,6 +147,7 @@ libvirtd_CFLAGS = \ -DSOCK_NAME_RO="\"libvirt-sock-ro\"" \ -DSOCK_NAME_ADMIN="\"libvirt-admin-sock\"" \ -DDAEMON_NAME="\"libvirtd\"" \ + -DENABLE_IP \ $(NULL) libvirtd_LDFLAGS = \ diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index e1fb081bfe..d01a303f70 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -366,11 +366,13 @@ static int ATTRIBUTE_NONNULL(3) daemonSetupNetworking(virNetServerPtr srv, virNetServerPtr srvAdm, struct daemonConfig *config, +#ifdef ENABLE_IP + bool ipsock, + bool privileged, +#endif /* ! ENABLE_IP */ const char *sock_path, const char *sock_path_ro, - const char *sock_path_adm, - bool ipsock, - bool privileged) + const char *sock_path_adm) { virNetServerServicePtr svc = NULL; virNetServerServicePtr svcAdm = NULL; @@ -457,6 +459,7 @@ daemonSetupNetworking(virNetServerPtr srv, goto cleanup; } +#ifdef ENABLE_IP if (ipsock) { if (config->listen_tcp) { VIR_DEBUG("Registering TCP socket %s:%s", @@ -537,6 +540,7 @@ daemonSetupNetworking(virNetServerPtr srv, virObjectUnref(ctxt); } } +#endif /* ! ENABLE_IP */ #if WITH_SASL if (virNetServerNeedsAuth(srv, REMOTE_AUTH_SASL) && @@ -876,6 +880,7 @@ daemonSetupHostUUID(const struct daemonConfig *config) static void daemonUsage(const char *argv0, bool privileged) { +#ifdef ENABLE_IP fprintf(stderr, _("\n" "Usage:\n" @@ -946,6 +951,64 @@ daemonUsage(const char *argv0, bool privileged) SOCK_NAME, DAEMON_NAME); } +#else + fprintf(stderr, + _("\n" + "Usage:\n" + " %s [options]\n" + "\n" + "Options:\n" + " -h | --help Display program help:\n" + " -v | --verbose Verbose messages.\n" + " -d | --daemon Run as a daemon & write PID file.\n" + " -t | --timeout <secs> Exit after timeout period.\n" + " -f | --config <file> Configuration file.\n" + " -V | --version Display version information.\n" + " -p | --pid-file <file> Change name of PID file.\n" + "\n" + "libvirt management daemon:\n"), + argv0); + + if (privileged) { + fprintf(stderr, + _("\n" + " Default paths:\n" + "\n" + " Configuration file (unless overridden by -f):\n" + " %s/libvirt/%s.conf\n" + "\n" + " Sockets:\n" + " %s\n" + " %s\n" + "\n" + " PID file (unless overridden by -p):\n" + " %s/run/%s.pid\n" + "\n"), + SYSCONFDIR, + DAEMON_NAME, + LOCALSTATEDIR "/run/libvirt/" SOCK_NAME, + LOCALSTATEDIR "/run/libvirt/" SOCK_NAME_RO, + LOCALSTATEDIR, + DAEMON_NAME); + } else { + fprintf(stderr, + _("\n" + " Default paths:\n" + "\n" + " Configuration file (unless overridden by -f):\n" + " $XDG_CONFIG_HOME/libvirt/%s.conf\n" + "\n" + " Sockets:\n" + " $XDG_RUNTIME_DIR/libvirt/%s\n" + "\n" + " PID file:\n" + " $XDG_RUNTIME_DIR/libvirt/%s.pid\n" + "\n"), + DAEMON_NAME, + SOCK_NAME, + DAEMON_NAME); + } +#endif } int main(int argc, char **argv) { @@ -965,7 +1028,9 @@ int main(int argc, char **argv) { int timeout = -1; /* -t: Shutdown timeout */ int verbose = 0; int godaemon = 0; +#ifdef ENABLE_IP int ipsock = 0; +#endif /* ! ENABLE_IP */ struct daemonConfig *config; bool privileged = geteuid() == 0 ? true : false; bool implicit_conf = false; @@ -975,7 +1040,9 @@ int main(int argc, char **argv) { struct option opts[] = { { "verbose", no_argument, &verbose, 'v'}, { "daemon", no_argument, &godaemon, 'd'}, +#ifdef ENABLE_IP { "listen", no_argument, &ipsock, 'l'}, +#endif /* ! ENABLE_IP */ { "config", required_argument, NULL, 'f'}, { "timeout", required_argument, NULL, 't'}, { "pid-file", required_argument, NULL, 'p'}, @@ -999,7 +1066,13 @@ int main(int argc, char **argv) { int c; char *tmp; - c = getopt_long(argc, argv, "ldf:p:t:vVh", opts, &optidx); + c = getopt_long(argc, argv, +#ifdef ENABLE_IP + "ldf:p:t:vVh", +#else /* ! ENABLE_IP */ + "df:p:t:vVh", +#endif /* ! ENABLE_IP */ + opts, &optidx); if (c == -1) break; @@ -1014,9 +1087,11 @@ int main(int argc, char **argv) { case 'd': godaemon = 1; break; +#ifdef ENABLE_IP case 'l': ipsock = 1; break; +#endif /* ! ENABLE_IP */ case 't': if (virStrToLong_i(optarg, &tmp, 10, &timeout) != 0 @@ -1330,10 +1405,13 @@ int main(int argc, char **argv) { if (daemonSetupNetworking(srv, srvAdm, config, +#ifdef ENABLE_IP + ipsock, + privileged, +#endif /* !ENABLE_IP */ sock_file, sock_file_ro, - sock_file_adm, - ipsock, privileged) < 0) { + sock_file_adm) < 0) { ret = VIR_DAEMON_ERR_NETWORK; goto cleanup; } diff --git a/src/remote/remote_daemon_config.c b/src/remote/remote_daemon_config.c index 3e62b4203f..3c5ccd5ba8 100644 --- a/src/remote/remote_daemon_config.c +++ b/src/remote/remote_daemon_config.c @@ -107,12 +107,14 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED) if (VIR_ALLOC(data) < 0) return NULL; +#ifdef ENABLE_IP data->listen_tls = 1; data->listen_tcp = 0; if (VIR_STRDUP(data->tls_port, LIBVIRTD_TLS_PORT) < 0 || VIR_STRDUP(data->tcp_port, LIBVIRTD_TCP_PORT) < 0) goto error; +#endif /* !ENABLE_IP */ /* Only default to PolicyKit if running as root */ #if WITH_POLKIT @@ -133,12 +135,14 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED) VIR_STRDUP(data->unix_sock_admin_perms, "0700") < 0) goto error; -#if WITH_SASL +#ifdef ENABLE_IP +# if WITH_SASL data->auth_tcp = REMOTE_AUTH_SASL; -#else +# else data->auth_tcp = REMOTE_AUTH_NONE; -#endif +# endif data->auth_tls = REMOTE_AUTH_NONE; +#endif /* ! ENABLE_IP */ data->min_workers = 5; data->max_workers = 20; @@ -182,9 +186,12 @@ daemonConfigFree(struct daemonConfig *data) if (!data) return; +#ifdef ENABLE_IP VIR_FREE(data->listen_addr); VIR_FREE(data->tls_port); VIR_FREE(data->tcp_port); +#endif /* ! ENABLE_IP */ + tmp = data->access_drivers; while (tmp && *tmp) { VIR_FREE(*tmp); @@ -198,25 +205,28 @@ daemonConfigFree(struct daemonConfig *data) VIR_FREE(data->unix_sock_group); VIR_FREE(data->unix_sock_dir); - tmp = data->tls_allowed_dn_list; + tmp = data->sasl_allowed_username_list; while (tmp && *tmp) { VIR_FREE(*tmp); tmp++; } - VIR_FREE(data->tls_allowed_dn_list); + VIR_FREE(data->sasl_allowed_username_list); - tmp = data->sasl_allowed_username_list; +#ifdef ENABLE_IP + tmp = data->tls_allowed_dn_list; while (tmp && *tmp) { VIR_FREE(*tmp); tmp++; } - VIR_FREE(data->sasl_allowed_username_list); + VIR_FREE(data->tls_allowed_dn_list); + VIR_FREE(data->tls_priority); VIR_FREE(data->key_file); VIR_FREE(data->ca_file); VIR_FREE(data->cert_file); VIR_FREE(data->crl_file); +#endif /* ! ENABLE_IP */ VIR_FREE(data->host_uuid); VIR_FREE(data->host_uuid_source); @@ -231,6 +241,7 @@ daemonConfigLoadOptions(struct daemonConfig *data, const char *filename, virConfPtr conf) { +#ifdef ENABLE_IP if (virConfGetValueBool(conf, "listen_tcp", &data->listen_tcp) < 0) goto error; if (virConfGetValueBool(conf, "listen_tls", &data->listen_tls) < 0) @@ -241,6 +252,7 @@ daemonConfigLoadOptions(struct daemonConfig *data, goto error; if (virConfGetValueString(conf, "listen_addr", &data->listen_addr) < 0) goto error; +#endif /* !ENABLE_IP */ if (remoteConfigGetAuth(conf, filename, "auth_unix_rw", &data->auth_unix_rw) < 0) goto error; @@ -256,10 +268,13 @@ daemonConfigLoadOptions(struct daemonConfig *data, #endif if (remoteConfigGetAuth(conf, filename, "auth_unix_ro", &data->auth_unix_ro) < 0) goto error; + +#ifdef ENABLE_IP if (remoteConfigGetAuth(conf, filename, "auth_tcp", &data->auth_tcp) < 0) goto error; if (remoteConfigGetAuth(conf, filename, "auth_tls", &data->auth_tls) < 0) goto error; +#endif /* ! ENABLE_IP */ if (virConfGetValueStringList(conf, "access_drivers", false, &data->access_drivers) < 0) @@ -277,6 +292,7 @@ daemonConfigLoadOptions(struct daemonConfig *data, if (virConfGetValueString(conf, "unix_sock_dir", &data->unix_sock_dir) < 0) goto error; +#ifdef ENABLE_IP if (virConfGetValueBool(conf, "tls_no_sanity_certificate", &data->tls_no_sanity_certificate) < 0) goto error; if (virConfGetValueBool(conf, "tls_no_verify_certificate", &data->tls_no_verify_certificate) < 0) @@ -295,14 +311,14 @@ daemonConfigLoadOptions(struct daemonConfig *data, &data->tls_allowed_dn_list) < 0) goto error; + if (virConfGetValueString(conf, "tls_priority", &data->tls_priority) < 0) + goto error; +#endif /* ! ENABLE_IP */ if (virConfGetValueStringList(conf, "sasl_allowed_username_list", false, &data->sasl_allowed_username_list) < 0) goto error; - if (virConfGetValueString(conf, "tls_priority", &data->tls_priority) < 0) - goto error; - if (virConfGetValueUInt(conf, "min_workers", &data->min_workers) < 0) goto error; if (virConfGetValueUInt(conf, "max_workers", &data->max_workers) < 0) diff --git a/src/remote/remote_daemon_config.h b/src/remote/remote_daemon_config.h index d580e7d49c..842ce98c60 100644 --- a/src/remote/remote_daemon_config.h +++ b/src/remote/remote_daemon_config.h @@ -27,11 +27,13 @@ struct daemonConfig { char *host_uuid; char *host_uuid_source; +#ifdef ENABLE_IP bool listen_tls; bool listen_tcp; char *listen_addr; char *tls_port; char *tcp_port; +#endif /* ! ENABLE_IP */ char *unix_sock_admin_perms; char *unix_sock_ro_perms; @@ -41,21 +43,26 @@ struct daemonConfig { int auth_unix_rw; int auth_unix_ro; +#ifdef ENABLE_IP int auth_tcp; int auth_tls; +#endif /* ! ENABLE_IP */ char **access_drivers; +#ifdef ENABLE_IP bool tls_no_verify_certificate; bool tls_no_sanity_certificate; char **tls_allowed_dn_list; - char **sasl_allowed_username_list; char *tls_priority; char *key_file; char *cert_file; char *ca_file; char *crl_file; +#endif /* ! ENABLE_IP */ + + char **sasl_allowed_username_list; unsigned int min_workers; unsigned int max_workers; -- 2.21.0

Prepare for reusing libvirtd config to create other daemons by making the config parameters for IP sockets conditionally defined by the make rules. The main libvirtd daemon will retain IP listen ability, but all the driver specific daemons will be local UNIX sockets only. Apps needing IP connectivity will connect via the libvirtd daemon which will proxy to the driver specfic daemon. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/Makefile.inc.am | 12 +++++- .../{libvirtd.conf => libvirtd.conf.in} | 42 +++++++++++-------- src/remote/test_libvirtd.aug.in | 2 +- 3 files changed, 37 insertions(+), 19 deletions(-) rename src/remote/{libvirtd.conf => libvirtd.conf.in} (95%) diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index 25921437e2..4bc71346f2 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -71,7 +71,7 @@ EXTRA_DIST += \ $(LIBVIRTD_SOURCES) \ remote/test_libvirtd.aug.in \ remote/libvirtd.aug \ - remote/libvirtd.conf \ + remote/libvirtd.conf.in \ remote/libvirtd.policy \ remote/libvirtd.rules \ remote/libvirtd.sasl \ @@ -88,6 +88,9 @@ MAINTAINERCLEANFILES += \ $(REMOTE_DRIVER_GENERATED) \ $(LIBVIRTD_GENERATED) \ $(NULL) +CLEANFILES += \ + remote/libvirtd.conf \ + $(NULL) if WITH_REMOTE noinst_LTLIBRARIES += libvirt_driver_remote.la @@ -178,6 +181,13 @@ libvirtd_LDADD += \ $(LIBSOCKET) \ $(NULL) +remote/libvirtd.conf: remote/libvirtd.conf.in + $(AM_V_GEN)sed \ + -e '/:: CUT ENABLE_IP ::/d' \ + -e '/:: END ::/d' \ + -e 's/:: DAEMON_NAME ::/libvirtd/' \ + < $^ > $@ + INSTALL_DATA_DIRS += remote install-data-remote: diff --git a/src/remote/libvirtd.conf b/src/remote/libvirtd.conf.in similarity index 95% rename from src/remote/libvirtd.conf rename to src/remote/libvirtd.conf.in index bbeb053495..39da576e68 100644 --- a/src/remote/libvirtd.conf +++ b/src/remote/libvirtd.conf.in @@ -1,13 +1,14 @@ # Master libvirt daemon configuration file # +:: CUT ENABLE_IP :: ################################################################# # # Network connectivity controls # # Flag listening for secure TLS connections on the public TCP/IP port. -# NB, must pass the --listen flag to the libvirtd process for this to +# NB, must pass the --listen flag to the :: DAEMON_NAME :: process for this to # have any effect. # # It is necessary to setup a CA and issue server certificates before @@ -17,7 +18,7 @@ #listen_tls = 0 # Listen for unencrypted TCP connections on the public TCP/IP port. -# NB, must pass the --listen flag to the libvirtd process for this to +# NB, must pass the --listen flag to the :: DAEMON_NAME :: process for this to # have any effect. # # Using the TCP socket requires SASL authentication by default. Only @@ -43,13 +44,14 @@ # Override the default configuration which binds to all network # interfaces. This can be a numeric IPv4/6 address, or hostname # -# If the libvirtd service is started in parallel with network +# If the :: DAEMON_NAME :: service is started in parallel with network # startup (e.g. with systemd), binding to addresses other than # the wildcards (0.0.0.0/::) might not be available yet. # #listen_addr = "192.168.0.1" +:: END :: ################################################################# # # UNIX socket access controls @@ -126,6 +128,7 @@ # If the unix_sock_rw_perms are changed you may wish to enable # an authentication mechanism here #auth_unix_rw = "none" +:: CUT ENABLE_IP :: # Change the authentication scheme for TCP sockets. # @@ -143,6 +146,7 @@ # It is possible to make use of any SASL authentication # mechanism as well, by using 'sasl' for this option #auth_tls = "none" +:: END :: # Change the API access control scheme @@ -151,10 +155,11 @@ # to all APIs. Access drivers can place restrictions # on this. By default the 'nop' driver is enabled, # meaning no access control checks are done once a -# client has authenticated with libvirtd +# client has authenticated with :: DAEMON_NAME :: # #access_drivers = [ "polkit" ] +:: CUT ENABLE_IP :: ################################################################# # # TLS x509 certificate configuration @@ -194,15 +199,17 @@ +:: END :: ################################################################# # # Authorization controls # +:: CUT ENABLE_IP :: # Flag to disable verification of our own server certificates # -# When libvirtd starts it performs some sanity checks against +# When :: DAEMON_NAME :: starts it performs some sanity checks against # its own certificates. # # Default is to always run sanity checks. Uncommenting this @@ -234,6 +241,15 @@ #tls_allowed_dn_list = ["DN1", "DN2"] +# Override the compile time default TLS priority string. The +# default is usually "NORMAL" unless overridden at build time. +# Only set this is it is desired for libvirt to deviate from +# the global default settings. +# +#tls_priority="NORMAL" + + +:: END :: # A whitelist of allowed SASL usernames. The format for username # depends on the SASL authentication mechanism. Kerberos usernames # look like username@REALM @@ -251,14 +267,6 @@ #sasl_allowed_username_list = ["joe@EXAMPLE.COM", "fred@EXAMPLE.COM" ] -# Override the compile time default TLS priority string. The -# default is usually "NORMAL" unless overridden at build time. -# Only set this is it is desired for libvirt to deviate from -# the global default settings. -# -#tls_priority="NORMAL" - - ################################################################# # # Processing controls @@ -386,8 +394,8 @@ # 4: ERROR # # Multiple outputs can be defined, they just need to be separated by spaces. -# e.g. to log all warnings and errors to syslog under the libvirtd ident: -#log_outputs="3:syslog:libvirtd" +# e.g. to log all warnings and errors to syslog under the :: DAEMON_NAME :: ident: +#log_outputs="3:syslog::: DAEMON_NAME ::" ################################################################## @@ -430,7 +438,7 @@ ################################################################### # Keepalive protocol: -# This allows libvirtd to detect broken client connections or even +# This allows :: DAEMON_NAME :: to detect broken client connections or even # dead clients. A keepalive message is sent to a client after # keepalive_interval seconds of inactivity to check if the client is # still responding; keepalive_count is a maximum number of keepalive @@ -439,7 +447,7 @@ # words, the connection is automatically closed approximately after # keepalive_interval * (keepalive_count + 1) seconds since the last # message received from the client. If keepalive_interval is set to -# -1, libvirtd will never send keepalive requests; however clients +# -1, :: DAEMON_NAME :: will never send keepalive requests; however clients # can still send them and the daemon will send responses. When # keepalive_count is set to 0, connections will be automatically # closed after keepalive_interval seconds of inactivity without diff --git a/src/remote/test_libvirtd.aug.in b/src/remote/test_libvirtd.aug.in index ad6450a569..a4c7b4afe8 100644 --- a/src/remote/test_libvirtd.aug.in +++ b/src/remote/test_libvirtd.aug.in @@ -29,11 +29,11 @@ module Test_libvirtd = { "1" = "DN1"} { "2" = "DN2"} } + { "tls_priority" = "NORMAL" } { "sasl_allowed_username_list" { "1" = "joe@EXAMPLE.COM" } { "2" = "fred@EXAMPLE.COM" } } - { "tls_priority" = "NORMAL" } { "max_clients" = "5000" } { "max_queued_clients" = "1000" } { "max_anonymous_clients" = "20" } -- 2.21.0

Prepare for reusing libvirtd augeas defintions with other daemons by making the config parameters for IP sockets conditionally defined by the make rules. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- build-aux/augeas-gentest.pl | 2 +- src/remote/Makefile.inc.am | 27 +++++++++++++++----- src/remote/{libvirtd.aug => libvirtd.aug.in} | 24 ++++++++++++----- src/remote/test_libvirtd.aug.in | 14 +++++++--- 4 files changed, 49 insertions(+), 18 deletions(-) rename src/remote/{libvirtd.aug => libvirtd.aug.in} (88%) diff --git a/build-aux/augeas-gentest.pl b/build-aux/augeas-gentest.pl index 567fc651f3..69d94e6a0f 100755 --- a/build-aux/augeas-gentest.pl +++ b/build-aux/augeas-gentest.pl @@ -37,7 +37,7 @@ open TEMPLATE, "<", $template or die "cannot read $template: $!"; my $group = 0; while (<TEMPLATE>) { - if (/::CONFIG::/) { + if (/::\s*CONFIG\s*::/) { my $group = 0; print AUGTEST " let conf = \""; while (<CONFIG>) { diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index 4bc71346f2..7732fa744c 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -124,11 +124,11 @@ sbin_PROGRAMS += libvirtd augeas_DATA += remote/libvirtd.aug -augeastest_DATA += test_libvirtd.aug +augeastest_DATA += remote/test_libvirtd.aug conf_DATA += remote/libvirtd.conf -CLEANFILES += test_libvirtd.aug +CLEANFILES += remote/libvirtd.aug remote/test_libvirtd.aug man8_MANS += libvirtd.8 @@ -198,13 +198,28 @@ uninstall-data-remote: AUGEAS_DIRS += remote -test_libvirtd.aug: remote/test_libvirtd.aug.in \ +remote/libvirtd.aug: remote/libvirtd.aug.in + $(AM_V_GEN)$(SED) \ + -e '/:: CUT ENABLE_IP ::/d' \ + -e '/:: END ::/d' \ + -e 's/:: DAEMON_NAME ::/libvirtd/' \ + -e 's/:: DAEMON_NAME_UC ::/Libvirtd/' \ + $< > $@ + +remote/test_libvirtd.aug.tmp: remote/test_libvirtd.aug.in \ remote/libvirtd.conf $(AUG_GENTEST) - $(AM_V_GEN)$(AUG_GENTEST) $(srcdir)/remote/libvirtd.conf $< $@ + $(AM_V_GEN)$(AUG_GENTEST) remote/libvirtd.conf remote/test_libvirtd.aug.in $@ + +remote/test_libvirtd.aug: remote/test_libvirtd.aug.tmp + $(AM_V_GEN)$(SED) -e '/:: CUT ENABLE_IP ::/d' \ + -e '/:: END ::/d' \ + -e 's/:: DAEMON_NAME ::/libvirtd/' \ + -e 's/:: DAEMON_NAME_UC ::/Libvirtd/' \ + < $^ > $@ || rm -f $@ -check-augeas-remote: test_libvirtd.aug +check-augeas-remote: remote/test_libvirtd.aug $(AM_V_GEN)if test -x '$(AUGPARSE)'; then \ - '$(AUGPARSE)' -I $(srcdir)/remote test_libvirtd.aug; \ + '$(AUGPARSE)' -I $(srcdir)/remote remote/test_libvirtd.aug; \ fi if WITH_SYSCTL diff --git a/src/remote/libvirtd.aug b/src/remote/libvirtd.aug.in similarity index 88% rename from src/remote/libvirtd.aug rename to src/remote/libvirtd.aug.in index 0188c23dd7..54a45e438a 100644 --- a/src/remote/libvirtd.aug +++ b/src/remote/libvirtd.aug.in @@ -1,6 +1,6 @@ -(* /etc/libvirt/libvirtd.conf *) +(* /etc/libvirt/:: DAEMON_NAME ::.conf *) -module Libvirtd = +module :: DAEMON_NAME_UC :: = autoload xfm let eol = del /[ \t]*\n/ "\n" @@ -24,11 +24,13 @@ module Libvirtd = (* Config entry grouped by function - same order as example config *) +:: CUT ENABLE_IP :: let network_entry = bool_entry "listen_tls" | bool_entry "listen_tcp" | str_entry "tls_port" | str_entry "tcp_port" | str_entry "listen_addr" +:: END:: let sock_acl_entry = str_entry "unix_sock_group" | str_entry "unix_sock_ro_perms" @@ -38,6 +40,7 @@ module Libvirtd = let authentication_entry = str_entry "auth_unix_ro" | str_entry "auth_unix_rw" +:: CUT ENABLE_IP :: | str_entry "auth_tcp" | str_entry "auth_tls" @@ -46,12 +49,16 @@ module Libvirtd = | str_entry "ca_file" | str_entry "crl_file" - let authorization_entry = bool_entry "tls_no_verify_certificate" + let tls_authorization_entry = bool_entry "tls_no_verify_certificate" | bool_entry "tls_no_sanity_certificate" | str_array_entry "tls_allowed_dn_list" | str_array_entry "sasl_allowed_username_list" | str_array_entry "access_drivers" | str_entry "tls_priority" +:: END :: + + let misc_authorization_entry = str_array_entry "sasl_allowed_username_list" + | str_array_entry "access_drivers" let processing_entry = int_entry "min_workers" | int_entry "max_workers" @@ -87,11 +94,14 @@ module Libvirtd = | int_entry "ovs_timeout" (* Each enty in the config is one of the following three ... *) - let entry = network_entry - | sock_acl_entry + let entry = sock_acl_entry | authentication_entry +:: CUT ENABLE_IP :: + | network_entry | certificate_entry - | authorization_entry + | tls_authorization_entry +:: END :: + | misc_authorization_entry | processing_entry | admin_processing_entry | logging_entry @@ -106,7 +116,7 @@ module Libvirtd = let lns = ( record | comment | empty ) * - let filter = incl "/etc/libvirt/libvirtd.conf" + let filter = incl "/etc/libvirt/:: DAEMON_NAME ::.conf" . Util.stdexcl let xfm = transform lns filter diff --git a/src/remote/test_libvirtd.aug.in b/src/remote/test_libvirtd.aug.in index a4c7b4afe8..ac3e0493b6 100644 --- a/src/remote/test_libvirtd.aug.in +++ b/src/remote/test_libvirtd.aug.in @@ -1,12 +1,14 @@ -module Test_libvirtd = - ::CONFIG:: +module Test_:: DAEMON_NAME :: = + :: CONFIG :: - test Libvirtd.lns get conf = + test :: DAEMON_NAME_UC ::.lns get conf = +:: CUT ENABLE_IP :: { "listen_tls" = "0" } { "listen_tcp" = "1" } { "tls_port" = "16514" } { "tcp_port" = "16509" } { "listen_addr" = "192.168.0.1" } +:: END :: { "unix_sock_group" = "libvirt" } { "unix_sock_ro_perms" = "0777" } { "unix_sock_rw_perms" = "0770" } @@ -14,11 +16,14 @@ module Test_libvirtd = { "unix_sock_dir" = "/var/run/libvirt" } { "auth_unix_ro" = "none" } { "auth_unix_rw" = "none" } +:: CUT ENABLE_IP :: { "auth_tcp" = "sasl" } { "auth_tls" = "none" } +:: END :: { "access_drivers" { "1" = "polkit" } } +:: CUT ENABLE_IP :: { "key_file" = "/etc/pki/libvirt/private/serverkey.pem" } { "cert_file" = "/etc/pki/libvirt/servercert.pem" } { "ca_file" = "/etc/pki/CA/cacert.pem" } @@ -30,6 +35,7 @@ module Test_libvirtd = { "2" = "DN2"} } { "tls_priority" = "NORMAL" } +:: END :: { "sasl_allowed_username_list" { "1" = "joe@EXAMPLE.COM" } { "2" = "fred@EXAMPLE.COM" } @@ -48,7 +54,7 @@ module Test_libvirtd = { "admin_max_client_requests" = "5" } { "log_level" = "3" } { "log_filters" = "1:qemu 1:libvirt 4:object 4:json 4:event 1:util" } - { "log_outputs" = "3:syslog:libvirtd" } + { "log_outputs" = "3:syslog::: DAEMON_NAME ::" } { "audit_level" = "2" } { "audit_logging" = "1" } { "host_uuid" = "00000000-0000-0000-0000-000000000000" } -- 2.21.0

On 7/11/19 6:04 PM, Daniel P. Berrangé wrote:
Prepare for reusing libvirtd augeas defintions with other daemons by making the config parameters for IP sockets conditionally defined by the make rules.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- build-aux/augeas-gentest.pl | 2 +- src/remote/Makefile.inc.am | 27 +++++++++++++++----- src/remote/{libvirtd.aug => libvirtd.aug.in} | 24 ++++++++++++----- src/remote/test_libvirtd.aug.in | 14 +++++++--- 4 files changed, 49 insertions(+), 18 deletions(-) rename src/remote/{libvirtd.aug => libvirtd.aug.in} (88%)
diff --git a/build-aux/augeas-gentest.pl b/build-aux/augeas-gentest.pl index 567fc651f3..69d94e6a0f 100755 --- a/build-aux/augeas-gentest.pl +++ b/build-aux/augeas-gentest.pl @@ -37,7 +37,7 @@ open TEMPLATE, "<", $template or die "cannot read $template: $!";
my $group = 0; while (<TEMPLATE>) { - if (/::CONFIG::/) { + if (/::\s*CONFIG\s*::/) { my $group = 0; print AUGTEST " let conf = \""; while (<CONFIG>) { diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index 4bc71346f2..7732fa744c 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -124,11 +124,11 @@ sbin_PROGRAMS += libvirtd
augeas_DATA += remote/libvirtd.aug
In order to generate this, we need to distribute libvirtd.aug.in: --- i/src/remote/Makefile.inc.am +++ w/src/remote/Makefile.inc.am @@ -70,7 +70,7 @@ EXTRA_DIST += \ $(REMOTE_DRIVER_SOURCES) \ $(LIBVIRTD_SOURCES) \ remote/test_libvirtd.aug.in \ - remote/libvirtd.aug \ + remote/libvirtd.aug.in \ remote/libvirtd.conf.in \ remote/libvirtd.policy \ remote/libvirtd.rules \
-augeastest_DATA += test_libvirtd.aug +augeastest_DATA += remote/test_libvirtd.aug
conf_DATA += remote/libvirtd.conf
-CLEANFILES += test_libvirtd.aug +CLEANFILES += remote/libvirtd.aug remote/test_libvirtd.aug
man8_MANS += libvirtd.8
@@ -198,13 +198,28 @@ uninstall-data-remote:
AUGEAS_DIRS += remote
-test_libvirtd.aug: remote/test_libvirtd.aug.in \ +remote/libvirtd.aug: remote/libvirtd.aug.in + $(AM_V_GEN)$(SED) \ + -e '/:: CUT ENABLE_IP ::/d' \ + -e '/:: END ::/d' \ + -e 's/:: DAEMON_NAME ::/libvirtd/' \ + -e 's/:: DAEMON_NAME_UC ::/Libvirtd/' \ + $< > $@ + +remote/test_libvirtd.aug.tmp: remote/test_libvirtd.aug.in \ remote/libvirtd.conf $(AUG_GENTEST) - $(AM_V_GEN)$(AUG_GENTEST) $(srcdir)/remote/libvirtd.conf $< $@ + $(AM_V_GEN)$(AUG_GENTEST) remote/libvirtd.conf remote/test_libvirtd.aug.in $@ + +remote/test_libvirtd.aug: remote/test_libvirtd.aug.tmp + $(AM_V_GEN)$(SED) -e '/:: CUT ENABLE_IP ::/d' \ + -e '/:: END ::/d' \ + -e 's/:: DAEMON_NAME ::/libvirtd/' \ + -e 's/:: DAEMON_NAME_UC ::/Libvirtd/' \ + < $^ > $@ || rm -f $@
-check-augeas-remote: test_libvirtd.aug +check-augeas-remote: remote/test_libvirtd.aug $(AM_V_GEN)if test -x '$(AUGPARSE)'; then \ - '$(AUGPARSE)' -I $(srcdir)/remote test_libvirtd.aug; \ + '$(AUGPARSE)' -I $(srcdir)/remote remote/test_libvirtd.aug; \ fi
if WITH_SYSCTL diff --git a/src/remote/libvirtd.aug b/src/remote/libvirtd.aug.in similarity index 88% rename from src/remote/libvirtd.aug rename to src/remote/libvirtd.aug.in index 0188c23dd7..54a45e438a 100644 --- a/src/remote/libvirtd.aug +++ b/src/remote/libvirtd.aug.in @@ -1,6 +1,6 @@ -(* /etc/libvirt/libvirtd.conf *) +(* /etc/libvirt/:: DAEMON_NAME ::.conf *)
-module Libvirtd = +module :: DAEMON_NAME_UC :: = autoload xfm
let eol = del /[ \t]*\n/ "\n" @@ -24,11 +24,13 @@ module Libvirtd =
(* Config entry grouped by function - same order as example config *) +:: CUT ENABLE_IP :: let network_entry = bool_entry "listen_tls" | bool_entry "listen_tcp" | str_entry "tls_port" | str_entry "tcp_port" | str_entry "listen_addr" +:: END::
s/END::/END ::/
let sock_acl_entry = str_entry "unix_sock_group" | str_entry "unix_sock_ro_perms" @@ -38,6 +40,7 @@ module Libvirtd =
let authentication_entry = str_entry "auth_unix_ro" | str_entry "auth_unix_rw" +:: CUT ENABLE_IP :: | str_entry "auth_tcp" | str_entry "auth_tls"
@@ -46,12 +49,16 @@ module Libvirtd = | str_entry "ca_file" | str_entry "crl_file"
- let authorization_entry = bool_entry "tls_no_verify_certificate" + let tls_authorization_entry = bool_entry "tls_no_verify_certificate" | bool_entry "tls_no_sanity_certificate" | str_array_entry "tls_allowed_dn_list" | str_array_entry "sasl_allowed_username_list" | str_array_entry "access_drivers" | str_entry "tls_priority" +:: END :: + + let misc_authorization_entry = str_array_entry "sasl_allowed_username_list" + | str_array_entry "access_drivers"
You need to remove these two variables from tls_authorization_entry then: @@ -52,8 +52,6 @@ module :: DAEMON_NAME_UC :: = let tls_authorization_entry = bool_entry "tls_no_verify_certificate" | bool_entry "tls_no_sanity_certificate" | str_array_entry "tls_allowed_dn_list" - | str_array_entry "sasl_allowed_username_list" - | str_array_entry "access_drivers" | str_entry "tls_priority" :: END ::
let processing_entry = int_entry "min_workers" | int_entry "max_workers"
Surprisingly, 'distcheck' fails for me after this because augeas-gentest.pl is unable to find libvirtd.conf. What is surprising is that you're not touching libvirtd.conf in this patch but the previous one and distcheck just works there. Michal

On Fri, Jul 12, 2019 at 03:37:14PM +0200, Michal Privoznik wrote:
On 7/11/19 6:04 PM, Daniel P. Berrangé wrote:
Prepare for reusing libvirtd augeas defintions with other daemons by making the config parameters for IP sockets conditionally defined by the make rules.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- build-aux/augeas-gentest.pl | 2 +- src/remote/Makefile.inc.am | 27 +++++++++++++++----- src/remote/{libvirtd.aug => libvirtd.aug.in} | 24 ++++++++++++----- src/remote/test_libvirtd.aug.in | 14 +++++++--- 4 files changed, 49 insertions(+), 18 deletions(-) rename src/remote/{libvirtd.aug => libvirtd.aug.in} (88%)
diff --git a/build-aux/augeas-gentest.pl b/build-aux/augeas-gentest.pl index 567fc651f3..69d94e6a0f 100755 --- a/build-aux/augeas-gentest.pl +++ b/build-aux/augeas-gentest.pl @@ -37,7 +37,7 @@ open TEMPLATE, "<", $template or die "cannot read $template: $!";
my $group = 0; while (<TEMPLATE>) { - if (/::CONFIG::/) { + if (/::\s*CONFIG\s*::/) { my $group = 0; print AUGTEST " let conf = \""; while (<CONFIG>) { diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index 4bc71346f2..7732fa744c 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -124,11 +124,11 @@ sbin_PROGRAMS += libvirtd
augeas_DATA += remote/libvirtd.aug
[snip]
Surprisingly, 'distcheck' fails for me after this because augeas-gentest.pl is unable to find libvirtd.conf. What is surprising is that you're not touching libvirtd.conf in this patch but the previous one and distcheck just works there.
I actually find distcheck failing in the previous patch too. The problem is that conf_DATA is added to extra dist, to the libvirtd.conf and the libvirtd.conf.in both get into the tarball. Fixed by using nodist_conf_DATA instead. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On 7/11/19 6:04 PM, Daniel P. Berrangé wrote:
Prepare for reusing libvirtd augeas defintions with other daemons by making the config parameters for IP sockets conditionally defined by the make rules.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- build-aux/augeas-gentest.pl | 2 +- src/remote/Makefile.inc.am | 27 +++++++++++++++----- src/remote/{libvirtd.aug => libvirtd.aug.in} | 24 ++++++++++++----- src/remote/test_libvirtd.aug.in | 14 +++++++--- 4 files changed, 49 insertions(+), 18 deletions(-) rename src/remote/{libvirtd.aug => libvirtd.aug.in} (88%)
diff --git a/build-aux/augeas-gentest.pl b/build-aux/augeas-gentest.pl index 567fc651f3..69d94e6a0f 100755 --- a/build-aux/augeas-gentest.pl +++ b/build-aux/augeas-gentest.pl @@ -37,7 +37,7 @@ open TEMPLATE, "<", $template or die "cannot read $template: $!";
my $group = 0; while (<TEMPLATE>) { - if (/::CONFIG::/) { + if (/::\s*CONFIG\s*::/) { my $group = 0; print AUGTEST " let conf = \""; while (<CONFIG>) { diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index 4bc71346f2..7732fa744c 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -124,11 +124,11 @@ sbin_PROGRAMS += libvirtd
augeas_DATA += remote/libvirtd.aug
-augeastest_DATA += test_libvirtd.aug +augeastest_DATA += remote/test_libvirtd.aug
conf_DATA += remote/libvirtd.conf
-CLEANFILES += test_libvirtd.aug +CLEANFILES += remote/libvirtd.aug remote/test_libvirtd.aug
man8_MANS += libvirtd.8
@@ -198,13 +198,28 @@ uninstall-data-remote:
AUGEAS_DIRS += remote
-test_libvirtd.aug: remote/test_libvirtd.aug.in \ +remote/libvirtd.aug: remote/libvirtd.aug.in + $(AM_V_GEN)$(SED) \ + -e '/:: CUT ENABLE_IP ::/d' \ + -e '/:: END ::/d' \ + -e 's/:: DAEMON_NAME ::/libvirtd/' \ + -e 's/:: DAEMON_NAME_UC ::/Libvirtd/' \ + $< > $@ + +remote/test_libvirtd.aug.tmp: remote/test_libvirtd.aug.in \ remote/libvirtd.conf $(AUG_GENTEST) - $(AM_V_GEN)$(AUG_GENTEST) $(srcdir)/remote/libvirtd.conf $< $@ + $(AM_V_GEN)$(AUG_GENTEST) remote/libvirtd.conf remote/test_libvirtd.aug.in $@
To support VPATH builds I had to change the line above to $(AM_V_GEN)$(AUG_GENTEST) remote/libvirtd.conf $(srcdir)/remote/test_libvirtd.aug.in $@
+ +remote/test_libvirtd.aug: remote/test_libvirtd.aug.tmp + $(AM_V_GEN)$(SED) -e '/:: CUT ENABLE_IP ::/d' \ + -e '/:: END ::/d' \ + -e 's/:: DAEMON_NAME ::/libvirtd/' \ + -e 's/:: DAEMON_NAME_UC ::/Libvirtd/' \ + < $^ > $@ || rm -f $@
-check-augeas-remote: test_libvirtd.aug +check-augeas-remote: remote/test_libvirtd.aug $(AM_V_GEN)if test -x '$(AUGPARSE)'; then \ - '$(AUGPARSE)' -I $(srcdir)/remote test_libvirtd.aug; \ + '$(AUGPARSE)' -I $(srcdir)/remote remote/test_libvirtd.aug; \
and here '$(AUGPARSE)' -I remote remote/test_libvirtd.aug; \
fi
if WITH_SYSCTL diff --git a/src/remote/libvirtd.aug b/src/remote/libvirtd.aug.in similarity index 88% rename from src/remote/libvirtd.aug rename to src/remote/libvirtd.aug.in index 0188c23dd7..54a45e438a 100644 --- a/src/remote/libvirtd.aug +++ b/src/remote/libvirtd.aug.in @@ -1,6 +1,6 @@ -(* /etc/libvirt/libvirtd.conf *) +(* /etc/libvirt/:: DAEMON_NAME ::.conf *)
-module Libvirtd = +module :: DAEMON_NAME_UC :: = autoload xfm
let eol = del /[ \t]*\n/ "\n" @@ -24,11 +24,13 @@ module Libvirtd =
(* Config entry grouped by function - same order as example config *) +:: CUT ENABLE_IP :: let network_entry = bool_entry "listen_tls" | bool_entry "listen_tcp" | str_entry "tls_port" | str_entry "tcp_port" | str_entry "listen_addr" +:: END::
let sock_acl_entry = str_entry "unix_sock_group" | str_entry "unix_sock_ro_perms" @@ -38,6 +40,7 @@ module Libvirtd =
let authentication_entry = str_entry "auth_unix_ro" | str_entry "auth_unix_rw" +:: CUT ENABLE_IP :: | str_entry "auth_tcp" | str_entry "auth_tls"
@@ -46,12 +49,16 @@ module Libvirtd = | str_entry "ca_file" | str_entry "crl_file"
- let authorization_entry = bool_entry "tls_no_verify_certificate" + let tls_authorization_entry = bool_entry "tls_no_verify_certificate" | bool_entry "tls_no_sanity_certificate" | str_array_entry "tls_allowed_dn_list" | str_array_entry "sasl_allowed_username_list" | str_array_entry "access_drivers" | str_entry "tls_priority" +:: END :: + + let misc_authorization_entry = str_array_entry "sasl_allowed_username_list" + | str_array_entry "access_drivers"
let processing_entry = int_entry "min_workers" | int_entry "max_workers" @@ -87,11 +94,14 @@ module Libvirtd = | int_entry "ovs_timeout"
(* Each enty in the config is one of the following three ... *) - let entry = network_entry - | sock_acl_entry + let entry = sock_acl_entry | authentication_entry +:: CUT ENABLE_IP :: + | network_entry | certificate_entry - | authorization_entry + | tls_authorization_entry +:: END :: + | misc_authorization_entry | processing_entry | admin_processing_entry | logging_entry @@ -106,7 +116,7 @@ module Libvirtd =
let lns = ( record | comment | empty ) *
- let filter = incl "/etc/libvirt/libvirtd.conf" + let filter = incl "/etc/libvirt/:: DAEMON_NAME ::.conf" . Util.stdexcl
let xfm = transform lns filter diff --git a/src/remote/test_libvirtd.aug.in b/src/remote/test_libvirtd.aug.in index a4c7b4afe8..ac3e0493b6 100644 --- a/src/remote/test_libvirtd.aug.in +++ b/src/remote/test_libvirtd.aug.in @@ -1,12 +1,14 @@ -module Test_libvirtd = - ::CONFIG:: +module Test_:: DAEMON_NAME :: = + :: CONFIG ::
- test Libvirtd.lns get conf = + test :: DAEMON_NAME_UC ::.lns get conf = +:: CUT ENABLE_IP :: { "listen_tls" = "0" } { "listen_tcp" = "1" } { "tls_port" = "16514" } { "tcp_port" = "16509" } { "listen_addr" = "192.168.0.1" } +:: END :: { "unix_sock_group" = "libvirt" } { "unix_sock_ro_perms" = "0777" } { "unix_sock_rw_perms" = "0770" } @@ -14,11 +16,14 @@ module Test_libvirtd = { "unix_sock_dir" = "/var/run/libvirt" } { "auth_unix_ro" = "none" } { "auth_unix_rw" = "none" } +:: CUT ENABLE_IP :: { "auth_tcp" = "sasl" } { "auth_tls" = "none" } +:: END :: { "access_drivers" { "1" = "polkit" } } +:: CUT ENABLE_IP :: { "key_file" = "/etc/pki/libvirt/private/serverkey.pem" } { "cert_file" = "/etc/pki/libvirt/servercert.pem" } { "ca_file" = "/etc/pki/CA/cacert.pem" } @@ -30,6 +35,7 @@ module Test_libvirtd = { "2" = "DN2"} } { "tls_priority" = "NORMAL" } +:: END :: { "sasl_allowed_username_list" { "1" = "joe@EXAMPLE.COM" } { "2" = "fred@EXAMPLE.COM" } @@ -48,7 +54,7 @@ module Test_libvirtd = { "admin_max_client_requests" = "5" } { "log_level" = "3" } { "log_filters" = "1:qemu 1:libvirt 4:object 4:json 4:event 1:util" } - { "log_outputs" = "3:syslog:libvirtd" } + { "log_outputs" = "3:syslog::: DAEMON_NAME ::" } { "audit_level" = "2" } { "audit_logging" = "1" } { "host_uuid" = "00000000-0000-0000-0000-000000000000" }
-- Mit freundlichen Grüßen/Kind regards Boris Fiuczynski IBM Deutschland Research & Development GmbH Vorsitzender des Aufsichtsrats: Matthias Hartmann Geschäftsführung: Dirk Wittkopp Sitz der Gesellschaft: Böblingen Registergericht: Amtsgericht Stuttgart, HRB 243294

The same make variables will be useful for building both libvirtd and the split daemons, so refactor & rename variables to facilitate reuse. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/Makefile.inc.am | 95 ++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index 7732fa744c..43ad53bedb 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -18,13 +18,13 @@ REMOTE_DRIVER_SOURCES = \ $(REMOTE_DRIVER_GENERATED) \ $(NULL) -LIBVIRTD_GENERATED = \ +REMOTE_DAEMON_GENERATED = \ remote/remote_daemon_dispatch_stubs.h \ remote/remote_daemon_dispatch_lxc_stubs.h \ remote/remote_daemon_dispatch_qemu_stubs.h \ $(NULL) -LIBVIRTD_SOURCES = \ +REMOTE_DAEMON_SOURCES = \ remote/remote_daemon.c \ remote/remote_daemon.h \ remote/remote_daemon_config.c \ @@ -33,9 +33,50 @@ LIBVIRTD_SOURCES = \ remote/remote_daemon_dispatch.h \ remote/remote_daemon_stream.c \ remote/remote_daemon_stream.h \ - $(LIBVIRTD_GENERATED) \ + $(REMOTE_DAEMON_GENERATED) \ $(NULL) +REMOTE_DAEMON_CFLAGS = \ + $(LIBXML_CFLAGS) \ + $(GNUTLS_CFLAGS) \ + $(SASL_CFLAGS) \ + $(XDR_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(WARN_CFLAGS) \ + $(PIE_CFLAGS) \ + -I$(srcdir)/access \ + -I$(srcdir)/conf \ + -I$(srcdir)/rpc \ + $(NULL) + +REMOTE_DAEMON_LDFLAGS = \ + $(RELRO_LDFLAGS) \ + $(PIE_LDFLAGS) \ + $(NO_INDIRECT_LDFLAGS) \ + $(NO_UNDEFINED_LDFLAGS) \ + $(NULL) + +REMOTE_DAEMON_LDADD = \ + libvirt_driver_admin.la \ + libvirt-lxc.la \ + libvirt-qemu.la \ + libvirt.la \ + $(LIBXML_LIBS) \ + $(GNUTLS_LIBS) \ + $(SASL_LIBS) \ + $(DBUS_LIBS) \ + $(LIBNL_LIBS) \ + $(NULL) + +if WITH_DTRACE_PROBES +REMOTE_DAEMON_LDADD += ../src/libvirt_probes.lo +endif WITH_DTRACE_PROBES + +REMOTE_DAEMON_LDADD += \ + ../gnulib/lib/libgnu.la \ + $(LIBSOCKET) \ + $(NULL) LOGROTATE_FILES_IN += \ remote/libvirtd.qemu.logrotate.in \ @@ -68,7 +109,7 @@ DRIVER_SOURCE_FILES += $(REMOTE_DRIVER_SOURCES) EXTRA_DIST += \ $(REMOTE_DRIVER_PROTOCOL) \ $(REMOTE_DRIVER_SOURCES) \ - $(LIBVIRTD_SOURCES) \ + $(REMOTE_DAEMON_SOURCES) \ remote/test_libvirtd.aug.in \ remote/libvirtd.aug \ remote/libvirtd.conf.in \ @@ -82,11 +123,11 @@ EXTRA_DIST += \ # the WITH_REMOTE/WITH_LIBVIRTD conditionals BUILT_SOURCES += \ $(REMOTE_DRIVER_GENERATED) \ - $(LIBVIRTD_GENERATED) \ + $(REMOTE_DAEMON_GENERATED) \ $(NULL) MAINTAINERCLEANFILES += \ $(REMOTE_DRIVER_GENERATED) \ - $(LIBVIRTD_GENERATED) \ + $(REMOTE_DAEMON_GENERATED) \ $(NULL) CLEANFILES += \ remote/libvirtd.conf \ @@ -132,20 +173,10 @@ CLEANFILES += remote/libvirtd.aug remote/test_libvirtd.aug man8_MANS += libvirtd.8 -libvirtd_SOURCES = $(LIBVIRTD_SOURCES) +libvirtd_SOURCES = $(REMOTE_DAEMON_SOURCES) libvirtd_CFLAGS = \ - $(LIBXML_CFLAGS) \ - $(GNUTLS_CFLAGS) \ - $(SASL_CFLAGS) \ - $(XDR_CFLAGS) \ - $(DBUS_CFLAGS) \ - $(LIBNL_CFLAGS) \ - $(WARN_CFLAGS) \ - $(PIE_CFLAGS) \ - -I$(srcdir)/access \ - -I$(srcdir)/conf \ - -I$(srcdir)/rpc \ + $(REMOTE_DAEMON_CFLAGS) \ -DSOCK_NAME="\"libvirt-sock\"" \ -DSOCK_NAME_RO="\"libvirt-sock-ro\"" \ -DSOCK_NAME_ADMIN="\"libvirt-admin-sock\"" \ @@ -153,33 +184,9 @@ libvirtd_CFLAGS = \ -DENABLE_IP \ $(NULL) -libvirtd_LDFLAGS = \ - $(RELRO_LDFLAGS) \ - $(PIE_LDFLAGS) \ - $(NO_INDIRECT_LDFLAGS) \ - $(NO_UNDEFINED_LDFLAGS) \ - $(NULL) - -libvirtd_LDADD = \ - libvirt_driver_admin.la \ - libvirt-lxc.la \ - libvirt-qemu.la \ - libvirt.la \ - $(LIBXML_LIBS) \ - $(GNUTLS_LIBS) \ - $(SASL_LIBS) \ - $(DBUS_LIBS) \ - $(LIBNL_LIBS) \ - $(NULL) - -if WITH_DTRACE_PROBES -libvirtd_LDADD += ../src/libvirt_probes.lo -endif WITH_DTRACE_PROBES +libvirtd_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) -libvirtd_LDADD += \ - ../gnulib/lib/libgnu.la \ - $(LIBSOCKET) \ - $(NULL) +libvirtd_LDADD = $(REMOTE_DAEMON_LDADD) remote/libvirtd.conf: remote/libvirtd.conf.in $(AM_V_GEN)sed \ -- 2.21.0

On 7/11/19 6:04 PM, Daniel P. Berrangé wrote:
The same make variables will be useful for building both libvirtd and the split daemons, so refactor & rename variables to facilitate reuse.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/Makefile.inc.am | 95 ++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 44 deletions(-)
diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index 7732fa744c..43ad53bedb 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -18,13 +18,13 @@ REMOTE_DRIVER_SOURCES = \ $(REMOTE_DRIVER_GENERATED) \ $(NULL)
-LIBVIRTD_GENERATED = \ +REMOTE_DAEMON_GENERATED = \ remote/remote_daemon_dispatch_stubs.h \ remote/remote_daemon_dispatch_lxc_stubs.h \ remote/remote_daemon_dispatch_qemu_stubs.h \ $(NULL)
-LIBVIRTD_SOURCES = \ +REMOTE_DAEMON_SOURCES = \ remote/remote_daemon.c \ remote/remote_daemon.h \ remote/remote_daemon_config.c \ @@ -33,9 +33,50 @@ LIBVIRTD_SOURCES = \ remote/remote_daemon_dispatch.h \ remote/remote_daemon_stream.c \ remote/remote_daemon_stream.h \ - $(LIBVIRTD_GENERATED) \ + $(REMOTE_DAEMON_GENERATED) \ $(NULL)
+REMOTE_DAEMON_CFLAGS = \ + $(LIBXML_CFLAGS) \ + $(GNUTLS_CFLAGS) \ + $(SASL_CFLAGS) \ + $(XDR_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(WARN_CFLAGS) \ + $(PIE_CFLAGS) \ + -I$(srcdir)/access \ + -I$(srcdir)/conf \ + -I$(srcdir)/rpc \ + $(NULL) + +REMOTE_DAEMON_LDFLAGS = \ + $(RELRO_LDFLAGS) \ + $(PIE_LDFLAGS) \ + $(NO_INDIRECT_LDFLAGS) \ + $(NO_UNDEFINED_LDFLAGS) \ + $(NULL) + +REMOTE_DAEMON_LDADD = \ + libvirt_driver_admin.la \ + libvirt-lxc.la \ + libvirt-qemu.la \ + libvirt.la \ + $(LIBXML_LIBS) \ + $(GNUTLS_LIBS) \ + $(SASL_LIBS) \ + $(DBUS_LIBS) \ + $(LIBNL_LIBS) \ + $(NULL)
These variables need to be moved to src/Makefile.am because other Makefiles will use it. For instance the very next patch uses REMOTE_DAEMON_LDFLAGS which is not declared for src/secret/Makefile.inc.am Also, automake complains about the following (after I've moved the variable): src/Makefile.am:56: warning: variable 'REMOTE_DAEMON_LDFLAGS' is defined but no program or src/Makefile.am:56: library has 'REMOTE_DAEMON' as canonical name (possible typo) Michal

On Fri, Jul 12, 2019 at 03:36:58PM +0200, Michal Privoznik wrote:
On 7/11/19 6:04 PM, Daniel P. Berrangé wrote:
The same make variables will be useful for building both libvirtd and the split daemons, so refactor & rename variables to facilitate reuse.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/Makefile.inc.am | 95 ++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 44 deletions(-)
diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index 7732fa744c..43ad53bedb 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -18,13 +18,13 @@ REMOTE_DRIVER_SOURCES = \ $(REMOTE_DRIVER_GENERATED) \ $(NULL) -LIBVIRTD_GENERATED = \ +REMOTE_DAEMON_GENERATED = \ remote/remote_daemon_dispatch_stubs.h \ remote/remote_daemon_dispatch_lxc_stubs.h \ remote/remote_daemon_dispatch_qemu_stubs.h \ $(NULL) -LIBVIRTD_SOURCES = \ +REMOTE_DAEMON_SOURCES = \ remote/remote_daemon.c \ remote/remote_daemon.h \ remote/remote_daemon_config.c \ @@ -33,9 +33,50 @@ LIBVIRTD_SOURCES = \ remote/remote_daemon_dispatch.h \ remote/remote_daemon_stream.c \ remote/remote_daemon_stream.h \ - $(LIBVIRTD_GENERATED) \ + $(REMOTE_DAEMON_GENERATED) \ $(NULL) +REMOTE_DAEMON_CFLAGS = \ + $(LIBXML_CFLAGS) \ + $(GNUTLS_CFLAGS) \ + $(SASL_CFLAGS) \ + $(XDR_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(LIBNL_CFLAGS) \ + $(WARN_CFLAGS) \ + $(PIE_CFLAGS) \ + -I$(srcdir)/access \ + -I$(srcdir)/conf \ + -I$(srcdir)/rpc \ + $(NULL) + +REMOTE_DAEMON_LDFLAGS = \ + $(RELRO_LDFLAGS) \ + $(PIE_LDFLAGS) \ + $(NO_INDIRECT_LDFLAGS) \ + $(NO_UNDEFINED_LDFLAGS) \ + $(NULL) + +REMOTE_DAEMON_LDADD = \ + libvirt_driver_admin.la \ + libvirt-lxc.la \ + libvirt-qemu.la \ + libvirt.la \ + $(LIBXML_LIBS) \ + $(GNUTLS_LIBS) \ + $(SASL_LIBS) \ + $(DBUS_LIBS) \ + $(LIBNL_LIBS) \ + $(NULL)
These variables need to be moved to src/Makefile.am because other Makefiles will use it. For instance the very next patch uses REMOTE_DAEMON_LDFLAGS which is not declared for src/secret/Makefile.inc.am
That's not a problem actually. The src/*/Makefile.inc.am files are included into the top level src/Makefile, so whatever variables are defined in src/remote/Makefile.in.am, are visible to all other src/*/Makefile.in.am files that get included afterwards.
Also, automake complains about the following (after I've moved the variable):
src/Makefile.am:56: warning: variable 'REMOTE_DAEMON_LDFLAGS' is defined but no program or src/Makefile.am:56: library has 'REMOTE_DAEMON' as canonical name (possible typo)
Oh yes, that's one of the things I needed to figure out a solution for. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

The virtsecretd daemon will be responsible for providing the secret API driver functionality. The secret driver is still loaded by the main libvirtd daemon at this stage, so virtsecretd must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + libvirt.spec.in | 1 + src/secret/Makefile.inc.am | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index 727bfdb6ec..29473c4889 100644 --- a/.gitignore +++ b/.gitignore @@ -164,6 +164,7 @@ /src/virt-aa-helper /src/virtlockd /src/virtlogd +/src/virtsecretd /src/virt-guest-shutdown.target /tests/*.log /tests/*.pid diff --git a/libvirt.spec.in b/libvirt.spec.in index d54f58f1d4..e2c4bbef5d 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1602,6 +1602,7 @@ exit 0 %{_libdir}/%{name}/connection-driver/libvirt_driver_nwfilter.so %files daemon-driver-secret +%attr(0755, root, root) %{_sbindir}/virtsecretd %{_libdir}/%{name}/connection-driver/libvirt_driver_secret.so %files daemon-driver-storage diff --git a/src/secret/Makefile.inc.am b/src/secret/Makefile.inc.am index 7a1c8f8e1a..88a8b80658 100644 --- a/src/secret/Makefile.inc.am +++ b/src/secret/Makefile.inc.am @@ -37,4 +37,18 @@ libvirt_driver_secret_la_LIBADD = \ $(NULL) libvirt_driver_secret_la_LDFLAGS = $(AM_LDFLAGS_MOD_NOUNDEF) libvirt_driver_secret_la_SOURCES = $(SECRET_DRIVER_SOURCES) + +sbin_PROGRAMS += virtsecretd + +virtsecretd_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtsecretd_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtsecretd-sock\"" \ + -DSOCK_NAME_RO="\"virtsecretd-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtsecretd-admin-sock\"" \ + -DDAEMON_NAME="\"virtsecretd\"" \ + -DMODULE_NAME="\"secret\"" \ + $(NULL) +virtsecretd_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtsecretd_LDADD = $(REMOTE_DAEMON_LDADD) endif WITH_SECRETS -- 2.21.0

The virtnetworkd daemon will be responsible for providing the network API driver functionality. The network driver is still loaded by the main libvirtd daemon at this stage, so virtnetworkd must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + libvirt.spec.in | 1 + src/network/Makefile.inc.am | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index 29473c4889..6270a7418a 100644 --- a/.gitignore +++ b/.gitignore @@ -164,6 +164,7 @@ /src/virt-aa-helper /src/virtlockd /src/virtlogd +/src/virtnetworkd /src/virtsecretd /src/virt-guest-shutdown.target /tests/*.log diff --git a/libvirt.spec.in b/libvirt.spec.in index e2c4bbef5d..43f22c7858 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1580,6 +1580,7 @@ exit 0 %{_libdir}/%{name}/connection-driver/libvirt_driver_interface.so %files daemon-driver-network +%attr(0755, root, root) %{_sbindir}/virtnetworkd %dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/ %dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/ %dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/networks/autostart diff --git a/src/network/Makefile.inc.am b/src/network/Makefile.inc.am index 52270049d5..dbd6137279 100644 --- a/src/network/Makefile.inc.am +++ b/src/network/Makefile.inc.am @@ -49,6 +49,20 @@ libvirt_driver_network_impl_la_CFLAGS = \ libvirt_driver_network_impl_la_SOURCES = $(NETWORK_DRIVER_SOURCES) libvirt_driver_network_impl_la_LIBADD = $(DBUS_LIBS) +sbin_PROGRAMS += virtnetworkd + +virtnetworkd_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtnetworkd_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtnetworkd-sock\"" \ + -DSOCK_NAME_RO="\"virtnetworkd-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtnetworkd-admin-sock\"" \ + -DDAEMON_NAME="\"virtnetworkd\"" \ + -DMODULE_NAME="\"network\"" \ + $(NULL) +virtnetworkd_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtnetworkd_LDADD = $(REMOTE_DAEMON_LDADD) + libexec_PROGRAMS += libvirt_leaseshelper libvirt_leaseshelper_SOURCES = $(NETWORK_LEASES_HELPER_SOURCES) libvirt_leaseshelper_LDFLAGS = \ -- 2.21.0

The virtinterfaced daemon will be responsible for providing the interface API driver functionality. The interface driver is still loaded by the main libvirtd daemon at this stage, so virtinterfaced must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + libvirt.spec.in | 1 + src/interface/Makefile.inc.am | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index 6270a7418a..c92400b7d8 100644 --- a/.gitignore +++ b/.gitignore @@ -162,6 +162,7 @@ /src/util/virkeycodetable*.h /src/util/virkeynametable*.h /src/virt-aa-helper +/src/virtinterfaced /src/virtlockd /src/virtlogd /src/virtnetworkd diff --git a/libvirt.spec.in b/libvirt.spec.in index 43f22c7858..78a9965b52 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1577,6 +1577,7 @@ exit 0 %ghost %{_sysconfdir}/libvirt/nwfilter/*.xml %files daemon-driver-interface +%attr(0755, root, root) %{_sbindir}/virtinterfaced %{_libdir}/%{name}/connection-driver/libvirt_driver_interface.so %files daemon-driver-network diff --git a/src/interface/Makefile.inc.am b/src/interface/Makefile.inc.am index 339a92786b..41874a0408 100644 --- a/src/interface/Makefile.inc.am +++ b/src/interface/Makefile.inc.am @@ -41,4 +41,18 @@ libvirt_driver_interface_la_LIBADD += $(UDEV_LIBS) libvirt_driver_interface_la_SOURCES += $(INTERFACE_DRIVER_UDEV_SOURCES) endif WITH_UDEV libvirt_driver_interface_la_LIBADD += ../gnulib/lib/libgnu.la + +sbin_PROGRAMS += virtinterfaced + +virtinterfaced_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtinterfaced_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtinterfaced-sock\"" \ + -DSOCK_NAME_RO="\"virtinterfaced-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtinterfaced-admin-sock\"" \ + -DDAEMON_NAME="\"virtinterfaced\"" \ + -DMODULE_NAME="\"interface\"" \ + $(NULL) +virtinterfaced_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtinterfaced_LDADD = $(REMOTE_DAEMON_LDADD) endif WITH_INTERFACE -- 2.21.0

The virtstoraged daemon will be responsible for providing the storage API driver functionality. The storage driver is still loaded by the main libvirtd daemon at this stage, so virtstoraged must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + libvirt.spec.in | 1 + src/storage/Makefile.inc.am | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index c92400b7d8..4c5c0ba732 100644 --- a/.gitignore +++ b/.gitignore @@ -167,6 +167,7 @@ /src/virtlogd /src/virtnetworkd /src/virtsecretd +/src/virtstoraged /src/virt-guest-shutdown.target /tests/*.log /tests/*.pid diff --git a/libvirt.spec.in b/libvirt.spec.in index 78a9965b52..453c640b5e 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1610,6 +1610,7 @@ exit 0 %files daemon-driver-storage %files daemon-driver-storage-core +%attr(0755, root, root) %{_sbindir}/virtstoraged %attr(0755, root, root) %{_libexecdir}/libvirt_parthelper %{_libdir}/%{name}/connection-driver/libvirt_driver_storage.so %{_libdir}/%{name}/storage-backend/libvirt_storage_backend_fs.so diff --git a/src/storage/Makefile.inc.am b/src/storage/Makefile.inc.am index 538709256d..9e58bccbe4 100644 --- a/src/storage/Makefile.inc.am +++ b/src/storage/Makefile.inc.am @@ -368,6 +368,20 @@ libvirt_storage_backend_vstorage_la_LIBADD = \ $(NULL) endif WITH_STORAGE_VSTORAGE +sbin_PROGRAMS += virtstoraged + +virtstoraged_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtstoraged_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtstoraged-sock\"" \ + -DSOCK_NAME_RO="\"virtstoraged-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtstoraged-admin-sock\"" \ + -DDAEMON_NAME="\"virtstoraged\"" \ + -DMODULE_NAME="\"storage\"" \ + $(NULL) +virtstoraged_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtstoraged_LDADD = $(REMOTE_DAEMON_LDADD) + if WITH_STORAGE_DISK libexec_PROGRAMS += libvirt_parthelper -- 2.21.0

The virtnodedevd daemon will be responsible for providing the nodedev API driver functionality. The nodedev driver is still loaded by the main libvirtd daemon at this stage, so virtnodedevd must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + libvirt.spec.in | 1 + src/node_device/Makefile.inc.am | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index 4c5c0ba732..d8dd7ab5e4 100644 --- a/.gitignore +++ b/.gitignore @@ -166,6 +166,7 @@ /src/virtlockd /src/virtlogd /src/virtnetworkd +/src/virtnodedevd /src/virtsecretd /src/virtstoraged /src/virt-guest-shutdown.target diff --git a/libvirt.spec.in b/libvirt.spec.in index 453c640b5e..8904d1a28f 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1596,6 +1596,7 @@ exit 0 %endif %files daemon-driver-nodedev +%attr(0755, root, root) %{_sbindir}/virtnodedevd %{_libdir}/%{name}/connection-driver/libvirt_driver_nodedev.so %files daemon-driver-nwfilter diff --git a/src/node_device/Makefile.inc.am b/src/node_device/Makefile.inc.am index 3e04651e8c..8265fbb0c2 100644 --- a/src/node_device/Makefile.inc.am +++ b/src/node_device/Makefile.inc.am @@ -64,4 +64,18 @@ libvirt_driver_nodedev_la_LIBADD += \ endif WITH_UDEV libvirt_driver_nodedev_la_LIBADD += ../gnulib/lib/libgnu.la + +sbin_PROGRAMS += virtnodedevd + +virtnodedevd_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtnodedevd_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtnodedevd-sock\"" \ + -DSOCK_NAME_RO="\"virtnodedevd-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtnodedevd-admin-sock\"" \ + -DDAEMON_NAME="\"virtnodedevd\"" \ + -DMODULE_NAME="\"nodedev\"" \ + $(NULL) +virtnodedevd_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtnodedevd_LDADD = $(REMOTE_DAEMON_LDADD) endif WITH_NODE_DEVICES -- 2.21.0

The virtnwfilterd daemon will be responsible for providing the nwfilter API driver functionality. The nwfilter driver is still loaded by the main libvirtd daemon at this stage, so virtnwfilterd must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + libvirt.spec.in | 1 + src/nwfilter/Makefile.inc.am | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index d8dd7ab5e4..6c46e8ae19 100644 --- a/.gitignore +++ b/.gitignore @@ -167,6 +167,7 @@ /src/virtlogd /src/virtnetworkd /src/virtnodedevd +/src/virtnwfilterd /src/virtsecretd /src/virtstoraged /src/virt-guest-shutdown.target diff --git a/libvirt.spec.in b/libvirt.spec.in index 8904d1a28f..8e31588001 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1600,6 +1600,7 @@ exit 0 %{_libdir}/%{name}/connection-driver/libvirt_driver_nodedev.so %files daemon-driver-nwfilter +%attr(0755, root, root) %{_sbindir}/virtnwfilterd %dir %attr(0700, root, root) %{_sysconfdir}/libvirt/nwfilter/ %ghost %dir %{_localstatedir}/run/libvirt/network/ %{_libdir}/%{name}/connection-driver/libvirt_driver_nwfilter.so diff --git a/src/nwfilter/Makefile.inc.am b/src/nwfilter/Makefile.inc.am index 810ca54bcc..c5ada0d420 100644 --- a/src/nwfilter/Makefile.inc.am +++ b/src/nwfilter/Makefile.inc.am @@ -41,4 +41,18 @@ libvirt_driver_nwfilter_impl_la_LIBADD = \ ../gnulib/lib/libgnu.la \ $(NULL) libvirt_driver_nwfilter_impl_la_SOURCES = $(NWFILTER_DRIVER_SOURCES) + +sbin_PROGRAMS += virtnwfilterd + +virtnwfilterd_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtnwfilterd_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtnwfilterd-sock\"" \ + -DSOCK_NAME_RO="\"virtnwfilterd-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtnwfilterd-admin-sock\"" \ + -DDAEMON_NAME="\"virtnwfilterd\"" \ + -DMODULE_NAME="\"nwfilter\"" \ + $(NULL) +virtnwfilterd_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtnwfilterd_LDADD = $(REMOTE_DAEMON_LDADD) endif WITH_NWFILTER -- 2.21.0

The virtlibxld daemon will be responsible for providing the libxl API driver functionality. The libxl driver is still loaded by the main libvirtd daemon at this stage, so virtlibxld must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + libvirt.spec.in | 1 + src/libxl/Makefile.inc.am | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index 6c46e8ae19..0821363e94 100644 --- a/.gitignore +++ b/.gitignore @@ -163,6 +163,7 @@ /src/util/virkeynametable*.h /src/virt-aa-helper /src/virtinterfaced +/src/virtlibxld /src/virtlockd /src/virtlogd /src/virtnetworkd diff --git a/libvirt.spec.in b/libvirt.spec.in index 8e31588001..8dc11393b3 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1691,6 +1691,7 @@ exit 0 %if %{with_libxl} %files daemon-driver-libxl +%attr(0755, root, root) %{_sbindir}/virtlibxld %config(noreplace) %{_sysconfdir}/libvirt/libxl.conf %config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.libxl %config(noreplace) %{_sysconfdir}/libvirt/libxl-lockd.conf diff --git a/src/libxl/Makefile.inc.am b/src/libxl/Makefile.inc.am index 7f60b449d8..0ad22a0e80 100644 --- a/src/libxl/Makefile.inc.am +++ b/src/libxl/Makefile.inc.am @@ -65,6 +65,20 @@ libvirt_driver_libxl_impl_la_LIBADD = \ $(NULL) libvirt_driver_libxl_impl_la_SOURCES = $(LIBXL_DRIVER_SOURCES) +sbin_PROGRAMS += virtlibxld + +virtlibxld_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtlibxld_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtlibxld-sock\"" \ + -DSOCK_NAME_RO="\"virtlibxld-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtlibxld-admin-sock\"" \ + -DDAEMON_NAME="\"virtlibxld\"" \ + -DMODULE_NAME="\"libxl\"" \ + $(NULL) +virtlibxld_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtlibxld_LDADD = $(REMOTE_DAEMON_LDADD) + conf_DATA += libxl/libxl.conf augeas_DATA += libxl/libvirtd_libxl.aug augeastest_DATA += test_libvirtd_libxl.aug -- 2.21.0

The virtqemud daemon will be responsible for providing the qemu API driver functionality. The qemu driver is still loaded by the main libvirtd daemon at this stage, so virtqemud must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + libvirt.spec.in | 1 + src/qemu/Makefile.inc.am | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index 0821363e94..e53f098288 100644 --- a/.gitignore +++ b/.gitignore @@ -169,6 +169,7 @@ /src/virtnetworkd /src/virtnodedevd /src/virtnwfilterd +/src/virtqemud /src/virtsecretd /src/virtstoraged /src/virt-guest-shutdown.target diff --git a/libvirt.spec.in b/libvirt.spec.in index 8dc11393b3..bb373ea370 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1661,6 +1661,7 @@ exit 0 %if %{with_qemu} %files daemon-driver-qemu +%attr(0755, root, root) %{_sbindir}/virtqemud %dir %attr(0700, root, root) %{_sysconfdir}/libvirt/qemu/ %dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/qemu/ %config(noreplace) %{_sysconfdir}/libvirt/qemu.conf diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am index 254ba07dc0..ea10a4c565 100644 --- a/src/qemu/Makefile.inc.am +++ b/src/qemu/Makefile.inc.am @@ -112,6 +112,20 @@ CLEANFILES += \ endif WITH_DTRACE_PROBES +sbin_PROGRAMS += virtqemud + +virtqemud_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtqemud_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtqemud-sock\"" \ + -DSOCK_NAME_RO="\"virtqemud-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtqemud-admin-sock\"" \ + -DDAEMON_NAME="\"virtqemud\"" \ + -DMODULE_NAME="\"qemu\"" \ + $(NULL) +virtqemud_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtqemud_LDADD = $(REMOTE_DAEMON_LDADD) + conf_DATA += qemu/qemu.conf augeas_DATA += qemu/libvirtd_qemu.aug -- 2.21.0

The virtlxcd daemon will be responsible for providing the lxc API driver functionality. The lxc driver is still loaded by the main libvirtd daemon at this stage, so virtlxcd must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + libvirt.spec.in | 1 + src/lxc/Makefile.inc.am | 15 +++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/.gitignore b/.gitignore index e53f098288..f828835863 100644 --- a/.gitignore +++ b/.gitignore @@ -166,6 +166,7 @@ /src/virtlibxld /src/virtlockd /src/virtlogd +/src/virtlxcd /src/virtnetworkd /src/virtnodedevd /src/virtnwfilterd diff --git a/libvirt.spec.in b/libvirt.spec.in index bb373ea370..68729b8349 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1679,6 +1679,7 @@ exit 0 %if %{with_lxc} %files daemon-driver-lxc +%attr(0755, root, root) %{_sbindir}/virtlxcd %dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/lxc/ %config(noreplace) %{_sysconfdir}/libvirt/lxc.conf %config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.lxc diff --git a/src/lxc/Makefile.inc.am b/src/lxc/Makefile.inc.am index f27827c1e9..23a53f747b 100644 --- a/src/lxc/Makefile.inc.am +++ b/src/lxc/Makefile.inc.am @@ -110,6 +110,21 @@ endif WITH_BLKID libvirt_driver_lxc_impl_la_LIBADD += $(SECDRIVER_LIBS) libvirt_driver_lxc_impl_la_SOURCES = $(LXC_DRIVER_SOURCES) + +sbin_PROGRAMS += virtlxcd + +virtlxcd_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtlxcd_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtlxcd-sock\"" \ + -DSOCK_NAME_RO="\"virtlxcd-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtlxcd-admin-sock\"" \ + -DDAEMON_NAME="\"virtlxcd\"" \ + -DMODULE_NAME="\"lxc\"" \ + $(NULL) +virtlxcd_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtlxcd_LDADD = $(REMOTE_DAEMON_LDADD) + libexec_PROGRAMS += libvirt_lxc libvirt_lxc_SOURCES = \ -- 2.21.0

The virtvboxd daemon will be responsible for providing the vbox API driver functionality. The vbox driver is still loaded by the main libvirtd daemon at this stage, so virtvboxd must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + libvirt.spec.in | 1 + src/vbox/Makefile.inc.am | 14 ++++++++++++++ 3 files changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index f828835863..d697e9f750 100644 --- a/.gitignore +++ b/.gitignore @@ -173,6 +173,7 @@ /src/virtqemud /src/virtsecretd /src/virtstoraged +/src/virtvboxd /src/virt-guest-shutdown.target /tests/*.log /tests/*.pid diff --git a/libvirt.spec.in b/libvirt.spec.in index 68729b8349..7757e25247 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1707,6 +1707,7 @@ exit 0 %if %{with_vbox} %files daemon-driver-vbox +%attr(0755, root, root) %{_sbindir}/virtvboxd %{_libdir}/%{name}/connection-driver/libvirt_driver_vbox.so %endif diff --git a/src/vbox/Makefile.inc.am b/src/vbox/Makefile.inc.am index 95407778f7..609bbee3cc 100644 --- a/src/vbox/Makefile.inc.am +++ b/src/vbox/Makefile.inc.am @@ -63,4 +63,18 @@ libvirt_driver_vbox_impl_la_LIBADD = \ $(LIBXML_LIBS) \ $(NULL) libvirt_driver_vbox_impl_la_SOURCES = $(VBOX_DRIVER_SOURCES) + +sbin_PROGRAMS += virtvboxd + +virtvboxd_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtvboxd_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtvboxd-sock\"" \ + -DSOCK_NAME_RO="\"virtvboxd-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtvboxd-admin-sock\"" \ + -DDAEMON_NAME="\"virtvboxd\"" \ + -DMODULE_NAME="\"vbox\"" \ + $(NULL) +virtvboxd_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtvboxd_LDADD = $(REMOTE_DAEMON_LDADD) endif WITH_VBOX -- 2.21.0

The virtbhyved daemon will be responsible for providing the bhyve API driver functionality. The bhyve driver is still loaded by the main libvirtd daemon at this stage, so virtbhyved must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + src/bhyve/Makefile.inc.am | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/.gitignore b/.gitignore index d697e9f750..74d88015c8 100644 --- a/.gitignore +++ b/.gitignore @@ -162,6 +162,7 @@ /src/util/virkeycodetable*.h /src/util/virkeynametable*.h /src/virt-aa-helper +/src/virtbhyved /src/virtinterfaced /src/virtlibxld /src/virtlockd diff --git a/src/bhyve/Makefile.inc.am b/src/bhyve/Makefile.inc.am index 36af5d7504..8f51bd017e 100644 --- a/src/bhyve/Makefile.inc.am +++ b/src/bhyve/Makefile.inc.am @@ -47,6 +47,20 @@ libvirt_driver_bhyve_impl_la_CFLAGS = \ libvirt_driver_bhyve_impl_la_LDFLAGS = $(AM_LDFLAGS) libvirt_driver_bhyve_impl_la_SOURCES = $(BHYVE_DRIVER_SOURCES) +sbin_PROGRAMS += virtbhyved + +virtbhyved_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtbhyved_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtbhyved-sock\"" \ + -DSOCK_NAME_RO="\"virtbhyved-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtbhyved-admin-sock\"" \ + -DDAEMON_NAME="\"virtbhyved\"" \ + -DMODULE_NAME="\"bhyve\"" \ + $(NULL) +virtbhyved_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtbhyved_LDADD = $(REMOTE_DAEMON_LDADD) + conf_DATA += bhyve/bhyve.conf augeas_DATA += bhyve/libvirtd_bhyve.aug augeastest_DATA += test_libvirtd_bhyve.aug -- 2.21.0

The virtvzd daemon will be responsible for providing the vz API driver functionality. The vz driver is still loaded by the main libvirtd daemon at this stage, so virtvzd must not be running at the same time. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- .gitignore | 1 + src/vz/Makefile.inc.am | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/.gitignore b/.gitignore index 74d88015c8..aa7d0c19c8 100644 --- a/.gitignore +++ b/.gitignore @@ -175,6 +175,7 @@ /src/virtsecretd /src/virtstoraged /src/virtvboxd +/src/virtvzd /src/virt-guest-shutdown.target /tests/*.log /tests/*.pid diff --git a/src/vz/Makefile.inc.am b/src/vz/Makefile.inc.am index a3a146c627..7e1ab1bf17 100644 --- a/src/vz/Makefile.inc.am +++ b/src/vz/Makefile.inc.am @@ -37,4 +37,18 @@ libvirt_driver_vz_impl_la_LIBADD = \ $(PARALLELS_SDK_LIBS) \ $(LIBNL_LIBS) \ $(NULL) + +sbin_PROGRAMS += virtvzd + +virtvzd_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtvzd_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"virtvzd-sock\"" \ + -DSOCK_NAME_RO="\"virtvzd-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"virtvzd-admin-sock\"" \ + -DDAEMON_NAME="\"virtvzd\"" \ + -DMODULE_NAME="\"vz\"" \ + $(NULL) +virtvzd_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtvzd_LDADD = $(REMOTE_DAEMON_LDADD) endif WITH_VZ -- 2.21.0

The libvirtd daemon provides the traditional libvirt experience where all the drivers are in a single daemon, and is accessible over both local UNIX sockets and remote IP sockets. In the new world we're having a set of per-driver daemons which will primarily be accessed locally via their own UNIX sockets. We still, however, need to allow for case of applications which will connect to libvirt remotely. These remote connections can be done as TCP/TLS sockets, or by SSH tunnelling to the UNIX socket. In the later case, the old libvirt.so clients will only know about the path to the old libvirtd socket /var/run/libvirt/libvirt-sock, and not the new driver sockets /var/run/libvirt/virtqemud-sock. It is also not desirable to expose the main driver specific daemons over IP directly to minimize their attack service. Thus the virtproxyd daemon steps into place, to provide TCP/TLS sockets, and back compat for the old libvirtd UNIX socket path(s). It will then forward all RPC calls made to the appropriate driver specific daemon. Essentially it is equivalent to the old libvirtd with absolutely no drivers registered except for the remote driver (and other stateless drivers in libvirt.so). We could have modified libvirtd so none of the drivers are registed to get the same end result. We could even add a libvirtd.conf parameter to control whether the drivers are loaded to enable users to switch back to the old world if we discover bugs in the split-daemon model. Using a new daemon though has some advantages - We can make virtproxyd and the virtXXXd per-driver daemons all have "Conflicts: libvirtd.service" in their systemd unit files. This will guarantee that libvirtd is never started at the same time, as this would result in two daemons running the same driver, which will lead to exciting failure modes. - It allows us to break CLI compat to remove the --listen parameter. Both listen_tcp and listen_tls parameters in /etc/libvirtd/virtd.conf will default to zero. Either TLS or TCP can be enabled exclusively though virtd.conf without requiring the extra step of adding --listen. - It allows us to set a strict SELinux policy over virtproxyd. For back compat the libvirtd policy must continue to allow all drivers to run. We can't easily give a second policy to libvirtd which locks it down. By introducing a new virtproxyd we can set a strict policy for that daemon only. - It gets rid of the wierd naming of having a daemon with "lib" in its name. Now all normal daemons libvirt ships will have "virt" as their prefix not "libvirt". - Distros can more easily choose their upgrade path. They can ship both sets of daemons in their packages, and choose to either enable libvirtd, or enable the per-driver daemons and virtproxyd out of the box. Users can easily override this if desired by just tweaking which systemd units are active. After some time we can deprecate use of libvirtd and after some more time delete it entirely, leaving us in a pretty world filled with prancing unicorns. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/Makefile.inc.am | 18 ++++++++++++++---- src/remote/remote_daemon.c | 12 ++++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index 43ad53bedb..316c7ea0b6 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -161,7 +161,7 @@ endif ! WITH_REMOTE if WITH_LIBVIRTD -sbin_PROGRAMS += libvirtd +sbin_PROGRAMS += libvirtd virtproxyd augeas_DATA += remote/libvirtd.aug @@ -174,7 +174,6 @@ CLEANFILES += remote/libvirtd.aug remote/test_libvirtd.aug man8_MANS += libvirtd.8 libvirtd_SOURCES = $(REMOTE_DAEMON_SOURCES) - libvirtd_CFLAGS = \ $(REMOTE_DAEMON_CFLAGS) \ -DSOCK_NAME="\"libvirt-sock\"" \ @@ -182,12 +181,23 @@ libvirtd_CFLAGS = \ -DSOCK_NAME_ADMIN="\"libvirt-admin-sock\"" \ -DDAEMON_NAME="\"libvirtd\"" \ -DENABLE_IP \ + -DLIBVIRTD \ $(NULL) - libvirtd_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) - libvirtd_LDADD = $(REMOTE_DAEMON_LDADD) +virtproxyd_SOURCES = $(REMOTE_DAEMON_SOURCES) +virtproxyd_CFLAGS = \ + $(REMOTE_DAEMON_CFLAGS) \ + -DSOCK_NAME="\"libvirt-sock\"" \ + -DSOCK_NAME_RO="\"libvirt-sock-ro\"" \ + -DSOCK_NAME_ADMIN="\"libvirt-admin-sock\"" \ + -DDAEMON_NAME="\"virtproxyd\"" \ + -DENABLE_IP \ + $(NULL) +virtproxyd_LDFLAGS = $(REMOTE_DAEMON_LDFLAGS) +virtproxyd_LDADD = $(REMOTE_DAEMON_LDADD) + remote/libvirtd.conf: remote/libvirtd.conf.in $(AM_V_GEN)sed \ -e '/:: CUT ENABLE_IP ::/d' \ diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index d01a303f70..36e8acfca8 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -298,11 +298,19 @@ static int daemonErrorLogFilter(virErrorPtr err, int priority) static int daemonInitialize(void) { -#ifdef MODULE_NAME +#ifndef LIBVIRTD +# ifdef MODULE_NAME + /* This a dedicated per-driver daemon build */ if (virDriverLoadModule(MODULE_NAME, MODULE_NAME "Register", true) < 0) return -1; +# else + /* This is virtproxyd which merely proxies to the per-driver + * daemons for back compat, and also allows IP connectivity. + */ +# endif #else - /* + /* This is the legacy monolithic libvirtd built with all drivers + * * Note that the order is important: the first ones have a higher * priority when calling virStateInitialize. We must register the * network, storage and nodedev drivers before any stateful domain -- 2.21.0

When the client has a connection to one of the hypervisor specific daemons (eg virtqemud), the app may still expect to use the secondary driver APIs (storage, network, etc). None of these will be registered in the hypervisor daemon, so we must explicitly open a connection to each of the daemons for the secondary drivers we need. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_daemon_dispatch.c | 82 ++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 13 deletions(-) diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index 856c5e48e7..c8a605c709 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -1954,6 +1954,9 @@ remoteDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED, unsigned int flags; struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); int rv = -1; +#ifndef LIBVIRTD + const char *type = NULL; +#endif VIR_DEBUG("priv=%p conn=%p", priv, priv->conn); virMutexLock(&priv->lock); @@ -1972,20 +1975,73 @@ remoteDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED, if (virNetServerClientGetReadonly(client)) flags |= VIR_CONNECT_RO; - priv->conn = - flags & VIR_CONNECT_RO - ? virConnectOpenReadOnly(name) - : virConnectOpen(name); - - if (priv->conn == NULL) - goto cleanup; +#define OPEN_DRIVER(var, uri) \ + do { \ + VIR_DEBUG("Opening driver %s", uri); \ + if (!(priv->var = flags & VIR_CONNECT_RO \ + ? virConnectOpenReadOnly(uri) \ + : virConnectOpen(uri))) \ + goto cleanup; \ + VIR_DEBUG("Opened %p", priv->var); \ + } while (0) - priv->interfaceConn = virObjectRef(priv->conn); - priv->networkConn = virObjectRef(priv->conn); - priv->nodedevConn = virObjectRef(priv->conn); - priv->nwfilterConn = virObjectRef(priv->conn); - priv->secretConn = virObjectRef(priv->conn); - priv->storageConn = virObjectRef(priv->conn); + OPEN_DRIVER(conn, name); + +#ifndef LIBVIRTD + if (!(type = virConnectGetType(priv->conn))) + goto cleanup; + + VIR_DEBUG("Primary driver type is '%s'", type); + if (STREQ(type, "QEMU") || + STREQ(type, "LIBXL") || + STREQ(type, "LXC") || + STREQ(type, "VBOX") || + STREQ(type, "bhyve") || + STREQ(type, "vz") || + STREQ(type, "Parallels")) { + VIR_DEBUG("Hypervisor driver found, opening connections to secondary drivers"); + OPEN_DRIVER(interfaceConn, getuid() == 0 ? "interface:///system" : "interface:///session"); + OPEN_DRIVER(networkConn, getuid() == 0 ? "network:///system" : "network:///session"); + OPEN_DRIVER(nodedevConn, getuid() == 0 ? "nodedev:///system" : "nodedev:///session"); + if (getuid() == 0) + OPEN_DRIVER(nwfilterConn, "nwfilter:///system"); + OPEN_DRIVER(secretConn, getuid() == 0 ? "secret:///system" : "secret:///session"); + OPEN_DRIVER(storageConn, getuid() == 0 ? "storage:///system" : "storage:///session"); + } else if (STREQ(type, "interface")) { + VIR_DEBUG("Interface driver found"); + priv->interfaceConn = virObjectRef(priv->conn); + } else if (STREQ(type, "network")) { + VIR_DEBUG("Network driver found"); + priv->networkConn = virObjectRef(priv->conn); + } else if (STREQ(type, "nodedev")) { + VIR_DEBUG("Nodedev driver found"); + priv->nodedevConn = virObjectRef(priv->conn); + } else if (STREQ(type, "nwfilter")) { + VIR_DEBUG("NWFilter driver found"); + priv->nwfilterConn = virObjectRef(priv->conn); + } else if (STREQ(type, "secret")) { + VIR_DEBUG("Secret driver found"); + priv->secretConn = virObjectRef(priv->conn); + } else if (STREQ(type, "storage")) { + VIR_DEBUG("Storage driver found"); + priv->storageConn = virObjectRef(priv->conn); + + /* Co-open the secret driver, as apps using the storage driver may well + * need access to secrets for storage auth + */ + OPEN_DRIVER(secretConn, getuid == 0 ? "secret:///system" : "secret:///session"); + } else { +#endif /* LIBVIRTD */ + VIR_DEBUG("Pointing secondary drivers to primary"); + priv->interfaceConn = virObjectRef(priv->conn); + priv->networkConn = virObjectRef(priv->conn); + priv->nodedevConn = virObjectRef(priv->conn); + priv->nwfilterConn = virObjectRef(priv->conn); + priv->secretConn = virObjectRef(priv->conn); + priv->storageConn = virObjectRef(priv->conn); +#ifndef LIBVIRTD + } +#endif /* LIBVIRTD */ /* force update the @readonly attribute which was inherited from the * virNetServerService object - this is important for sockets that are RW -- 2.21.0

On 7/11/19 6:05 PM, Daniel P. Berrangé wrote:
When the client has a connection to one of the hypervisor specific daemons (eg virtqemud), the app may still expect to use the secondary driver APIs (storage, network, etc). None of these will be registered in the hypervisor daemon, so we must explicitly open a connection to each of the daemons for the secondary drivers we need.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_daemon_dispatch.c | 82 ++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 13 deletions(-)
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index 856c5e48e7..c8a605c709 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -1954,6 +1954,9 @@ remoteDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED, unsigned int flags; struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); int rv = -1; +#ifndef LIBVIRTD + const char *type = NULL; +#endif
VIR_DEBUG("priv=%p conn=%p", priv, priv->conn); virMutexLock(&priv->lock); @@ -1972,20 +1975,73 @@ remoteDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED, if (virNetServerClientGetReadonly(client)) flags |= VIR_CONNECT_RO;
- priv->conn = - flags & VIR_CONNECT_RO - ? virConnectOpenReadOnly(name) - : virConnectOpen(name); - - if (priv->conn == NULL) - goto cleanup; +#define OPEN_DRIVER(var, uri) \ + do { \ + VIR_DEBUG("Opening driver %s", uri); \ + if (!(priv->var = flags & VIR_CONNECT_RO \ + ? virConnectOpenReadOnly(uri) \ + : virConnectOpen(uri))) \ + goto cleanup; \ + VIR_DEBUG("Opened %p", priv->var); \ + } while (0)
This breaks syntax-check. Michal

On Fri, Jul 12, 2019 at 15:37:12 +0200, Michal Privoznik wrote:
On 7/11/19 6:05 PM, Daniel P. Berrangé wrote:
When the client has a connection to one of the hypervisor specific daemons (eg virtqemud), the app may still expect to use the secondary driver APIs (storage, network, etc). None of these will be registered in the hypervisor daemon, so we must explicitly open a connection to each of the daemons for the secondary drivers we need.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_daemon_dispatch.c | 82 ++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 13 deletions(-)
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index 856c5e48e7..c8a605c709 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c @@ -1954,6 +1954,9 @@ remoteDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED, unsigned int flags; struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); int rv = -1; +#ifndef LIBVIRTD + const char *type = NULL; +#endif VIR_DEBUG("priv=%p conn=%p", priv, priv->conn); virMutexLock(&priv->lock); @@ -1972,20 +1975,73 @@ remoteDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED, if (virNetServerClientGetReadonly(client)) flags |= VIR_CONNECT_RO; - priv->conn = - flags & VIR_CONNECT_RO - ? virConnectOpenReadOnly(name) - : virConnectOpen(name); - - if (priv->conn == NULL) - goto cleanup; +#define OPEN_DRIVER(var, uri) \ + do { \ + VIR_DEBUG("Opening driver %s", uri); \ + if (!(priv->var = flags & VIR_CONNECT_RO \ + ? virConnectOpenReadOnly(uri) \ + : virConnectOpen(uri))) \ + goto cleanup; \ + VIR_DEBUG("Opened %p", priv->var); \ + } while (0)
This breaks syntax-check.
Also I'd strongly suggest getting rid of the ternary operator and just expand the code for readability.

On Thu, Jul 11, 2019 at 05:05:11PM +0100, Daniel P. Berrangé wrote:
When the client has a connection to one of the hypervisor specific daemons (eg virtqemud), the app may still expect to use the secondary driver APIs (storage, network, etc). None of these will be registered in the hypervisor daemon, so we must explicitly open a connection to each of the daemons for the secondary drivers we need.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_daemon_dispatch.c | 82 ++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 13 deletions(-)
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index 856c5e48e7..c8a605c709 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c
[...]
+ VIR_DEBUG("Secret driver found"); + priv->secretConn = virObjectRef(priv->conn); + } else if (STREQ(type, "storage")) { + VIR_DEBUG("Storage driver found"); + priv->storageConn = virObjectRef(priv->conn); + + /* Co-open the secret driver, as apps using the storage driver may well + * need access to secrets for storage auth + */ + OPEN_DRIVER(secretConn, getuid == 0 ? "secret:///system" : "secret:///session");
getuid()
+ } else { +#endif /* LIBVIRTD */ + VIR_DEBUG("Pointing secondary drivers to primary"); + priv->interfaceConn = virObjectRef(priv->conn); + priv->networkConn = virObjectRef(priv->conn); + priv->nodedevConn = virObjectRef(priv->conn); + priv->nwfilterConn = virObjectRef(priv->conn); + priv->secretConn = virObjectRef(priv->conn); + priv->storageConn = virObjectRef(priv->conn); +#ifndef LIBVIRTD
Jano

On Fri, Jul 12, 2019 at 03:58:12PM +0200, Ján Tomko wrote:
On Thu, Jul 11, 2019 at 05:05:11PM +0100, Daniel P. Berrangé wrote:
When the client has a connection to one of the hypervisor specific daemons (eg virtqemud), the app may still expect to use the secondary driver APIs (storage, network, etc). None of these will be registered in the hypervisor daemon, so we must explicitly open a connection to each of the daemons for the secondary drivers we need.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_daemon_dispatch.c | 82 ++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 13 deletions(-)
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c index 856c5e48e7..c8a605c709 100644 --- a/src/remote/remote_daemon_dispatch.c +++ b/src/remote/remote_daemon_dispatch.c
[...]
+ VIR_DEBUG("Secret driver found"); + priv->secretConn = virObjectRef(priv->conn); + } else if (STREQ(type, "storage")) { + VIR_DEBUG("Storage driver found"); + priv->storageConn = virObjectRef(priv->conn); + + /* Co-open the secret driver, as apps using the storage driver may well + * need access to secrets for storage auth + */ + OPEN_DRIVER(secretConn, getuid == 0 ? "secret:///system" : "secret:///session");
getuid()
Yep, fixed locally shortly after posting this. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

Instead of open-coding a string -> enum conversion, use the enum helpers for the remote driver transport. The old code uses STRCASEEQ, so we must force the URI transport to lowercase for sake of back-compatibility. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_driver.c | 112 ++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 925ada1cac..87c184720c 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -49,11 +49,29 @@ #include "virauth.h" #include "virauthconfig.h" #include "virstring.h" +#include "c-ctype.h" #define VIR_FROM_THIS VIR_FROM_REMOTE VIR_LOG_INIT("remote.remote_driver"); +typedef enum { + REMOTE_DRIVER_TRANSPORT_TLS, + REMOTE_DRIVER_TRANSPORT_UNIX, + REMOTE_DRIVER_TRANSPORT_SSH, + REMOTE_DRIVER_TRANSPORT_LIBSSH2, + REMOTE_DRIVER_TRANSPORT_EXT, + REMOTE_DRIVER_TRANSPORT_TCP, + REMOTE_DRIVER_TRANSPORT_LIBSSH, + + REMOTE_DRIVER_TRANSPORT_LAST, +} remoteDriverTransport; + +VIR_ENUM_DECL(remoteDriverTransport); +VIR_ENUM_IMPL(remoteDriverTransport, + REMOTE_DRIVER_TRANSPORT_LAST, + "tls", "unix", "ssh", "libssh2", "ext", "tcp", "libssh"); + #if SIZEOF_LONG < 8 # define HYPER_TO_TYPE(_type, _to, _from) \ do { \ @@ -174,10 +192,17 @@ static int remoteSplitURIScheme(virURIPtr uri, if (VIR_STRNDUP(*driver, uri->scheme, p ? p - uri->scheme : -1) < 0) return -1; - if (p && - VIR_STRDUP(*transport, p + 1) < 0) { - VIR_FREE(*driver); - return -1; + if (p) { + if (VIR_STRDUP(*transport, p + 1) < 0) { + VIR_FREE(*driver); + return -1; + } + + p = *transport; + while (*p) { + *p = c_tolower(*p); + p++; + } } return 0; @@ -776,15 +801,7 @@ doRemoteOpen(virConnectPtr conn, virConfPtr conf, unsigned int flags) { - enum { - trans_tls, - trans_unix, - trans_ssh, - trans_libssh2, - trans_ext, - trans_tcp, - trans_libssh, - } transport; + int transport; #ifndef WIN32 VIR_AUTOFREE(char *) daemonPath = NULL; #endif @@ -813,42 +830,25 @@ doRemoteOpen(virConnectPtr conn, if (conn->uri) { if (!transport_str) { if (conn->uri->server) - transport = trans_tls; + transport = REMOTE_DRIVER_TRANSPORT_TLS; else - transport = trans_unix; + transport = REMOTE_DRIVER_TRANSPORT_UNIX; } else { - if (STRCASEEQ(transport_str, "tls")) { - transport = trans_tls; - } else if (STRCASEEQ(transport_str, "unix")) { - if (conn->uri->server) { - virReportError(VIR_ERR_INVALID_ARG, - _("using unix socket and remote " - "server '%s' is not supported."), - conn->uri->server); - return VIR_DRV_OPEN_ERROR; - } else { - transport = trans_unix; - } - } else if (STRCASEEQ(transport_str, "ssh")) { - transport = trans_ssh; - } else if (STRCASEEQ(transport_str, "libssh2")) { - transport = trans_libssh2; - } else if (STRCASEEQ(transport_str, "ext")) { - transport = trans_ext; - } else if (STRCASEEQ(transport_str, "tcp")) { - transport = trans_tcp; - } else if (STRCASEEQ(transport_str, "libssh")) { - transport = trans_libssh; - } else { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("remote_open: transport in URL not recognised " - "(should be tls|unix|ssh|ext|tcp|libssh2|libssh)")); + if ((transport = remoteDriverTransportTypeFromString(transport_str)) < 0) + return VIR_DRV_OPEN_ERROR; + + if (transport == REMOTE_DRIVER_TRANSPORT_UNIX && + conn->uri->server) { + virReportError(VIR_ERR_INVALID_ARG, + _("using unix socket and remote " + "server '%s' is not supported."), + conn->uri->server); return VIR_DRV_OPEN_ERROR; } } } else { /* No URI, then must be probing so use UNIX socket */ - transport = trans_unix; + transport = REMOTE_DRIVER_TRANSPORT_UNIX; } /* @@ -859,7 +859,7 @@ doRemoteOpen(virConnectPtr conn, * not require any external libraries or command execution */ if (virIsSUID() && - transport != trans_unix) { + transport != REMOTE_DRIVER_TRANSPORT_UNIX) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Only Unix socket URI transport is allowed in setuid mode")); return VIR_DRV_OPEN_ERROR; @@ -870,10 +870,10 @@ doRemoteOpen(virConnectPtr conn, if (conn->uri && conn->uri->port != 0) { if (virAsprintf(&port, "%d", conn->uri->port) < 0) goto failed; - } else if (transport == trans_tls) { + } else if (transport == REMOTE_DRIVER_TRANSPORT_TLS) { if (VIR_STRDUP(port, LIBVIRTD_TLS_PORT) < 0) goto failed; - } else if (transport == trans_tcp) { + } else if (transport == REMOTE_DRIVER_TRANSPORT_TCP) { if (VIR_STRDUP(port, LIBVIRTD_TCP_PORT) < 0) goto failed; } /* Port not used for unix, ext., default for ssh */ @@ -957,7 +957,7 @@ doRemoteOpen(virConnectPtr conn, VIR_DEBUG("proceeding with name = %s", name); /* For ext transport, command is required. */ - if (transport == trans_ext && !command) { + if (transport == REMOTE_DRIVER_TRANSPORT_EXT && !command) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("remote_open: for 'ext' transport, command is required")); goto failed; @@ -966,7 +966,7 @@ doRemoteOpen(virConnectPtr conn, VIR_DEBUG("Connecting with transport %d", transport); /* Connect to the remote service. */ switch (transport) { - case trans_tls: + case REMOTE_DRIVER_TRANSPORT_TLS: if (conf && !tls_priority && virConfGetValueString(conf, "tls_priority", &tls_priority) < 0) goto failed; @@ -989,7 +989,7 @@ doRemoteOpen(virConnectPtr conn, goto failed; #endif - case trans_tcp: + case REMOTE_DRIVER_TRANSPORT_TCP: priv->client = virNetClientNewTCP(priv->hostname, port, AF_UNSPEC); if (!priv->client) goto failed; @@ -1004,7 +1004,7 @@ doRemoteOpen(virConnectPtr conn, break; - case trans_libssh2: + case REMOTE_DRIVER_TRANSPORT_LIBSSH2: if (!sockname) { /* Right now we don't support default session connections */ if (flags & VIR_DRV_OPEN_REMOTE_USER) { @@ -1039,7 +1039,7 @@ doRemoteOpen(virConnectPtr conn, priv->is_secure = 1; break; - case trans_libssh: + case REMOTE_DRIVER_TRANSPORT_LIBSSH: if (!sockname) { /* Right now we don't support default session connections */ if (flags & VIR_DRV_OPEN_REMOTE_USER) { @@ -1075,7 +1075,7 @@ doRemoteOpen(virConnectPtr conn, break; #ifndef WIN32 - case trans_unix: + case REMOTE_DRIVER_TRANSPORT_UNIX: if (!sockname) { if (flags & VIR_DRV_OPEN_REMOTE_USER) sockname = remoteGetUNIXSocketNonRoot(); @@ -1101,7 +1101,7 @@ doRemoteOpen(virConnectPtr conn, priv->is_secure = 1; break; - case trans_ssh: + case REMOTE_DRIVER_TRANSPORT_SSH: if (!command && VIR_STRDUP(command, "ssh") < 0) goto failed; @@ -1133,7 +1133,7 @@ doRemoteOpen(virConnectPtr conn, priv->is_secure = 1; break; - case trans_ext: { + case REMOTE_DRIVER_TRANSPORT_EXT: { char const *cmd_argv[] = { command, NULL }; if (!(priv->client = virNetClientNewExternal(cmd_argv))) goto failed; @@ -1145,9 +1145,9 @@ doRemoteOpen(virConnectPtr conn, #else /* WIN32 */ - case trans_unix: - case trans_ssh: - case trans_ext: + case REMOTE_DRIVER_TRANSPORT_UNIX: + case REMOTE_DRIVER_TRANSPORT_SSH: + case REMOTE_DRIVER_TRANSPORT_EXT: virReportError(VIR_ERR_INVALID_ARG, "%s", _("transport methods unix, ssh and ext are not supported " "under Windows")); -- 2.21.0

The ssh, libssh, libssh2 & unix transports all need to use a UNIX socket path, and duplicate some of the same logic for error checking. Pull this out into a separate method to increase code sharing. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_driver.c | 111 ++++++++++++------------------------- 1 file changed, 36 insertions(+), 75 deletions(-) diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 87c184720c..c6905dffff 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -739,34 +739,35 @@ remoteConnectSupportsFeatureUnlocked(virConnectPtr conn, } -#ifndef WIN32 -static char *remoteGetUNIXSocketNonRoot(void) +static char * +remoteGetUNIXSocket(remoteDriverTransport transport, + unsigned int flags) { char *sockname = NULL; - char *userdir = virGetUserRuntimeDirectory(); - - if (!userdir) - return NULL; + VIR_AUTOFREE(char *userdir); + + if (flags & VIR_DRV_OPEN_REMOTE_USER) { + if (transport != REMOTE_DRIVER_TRANSPORT_UNIX) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("Connecting to session instance without " + "socket path is not supported by the %s " + "transport"), + remoteDriverTransportTypeToString(transport)); + return NULL; + } + if (!(userdir = virGetUserRuntimeDirectory())) + return NULL; - if (virAsprintf(&sockname, "%s/" LIBVIRTD_USER_UNIX_SOCKET, userdir) < 0) { - VIR_FREE(userdir); - return NULL; + if (virAsprintf(&sockname, + "%s/" LIBVIRTD_USER_UNIX_SOCKET, userdir) < 0) + return NULL; + } else { + if (VIR_STRDUP(sockname, + flags & VIR_DRV_OPEN_REMOTE_RO ? + LIBVIRTD_PRIV_UNIX_SOCKET_RO : + LIBVIRTD_PRIV_UNIX_SOCKET) < 0) + return NULL; } - VIR_FREE(userdir); - - VIR_DEBUG("Chosen UNIX sockname %s", sockname); - return sockname; -} -#endif /* WIN32 */ - -static char *remoteGetUNIXSocketRoot(unsigned int flags) -{ - char *sockname = NULL; - - if (VIR_STRDUP(sockname, - flags & VIR_DRV_OPEN_REMOTE_RO ? - LIBVIRTD_PRIV_UNIX_SOCKET_RO : LIBVIRTD_PRIV_UNIX_SOCKET) < 0) - return NULL; VIR_DEBUG("Chosen UNIX sockname %s", sockname); return sockname; @@ -964,6 +965,17 @@ doRemoteOpen(virConnectPtr conn, } VIR_DEBUG("Connecting with transport %d", transport); + + if ((transport == REMOTE_DRIVER_TRANSPORT_UNIX || + transport == REMOTE_DRIVER_TRANSPORT_SSH || + transport == REMOTE_DRIVER_TRANSPORT_LIBSSH || + transport == REMOTE_DRIVER_TRANSPORT_LIBSSH2) && + !sockname && + !(sockname = remoteGetUNIXSocket(transport, flags))) + goto failed; + + VIR_DEBUG("Chosen UNIX socket %s", NULLSTR(sockname)); + /* Connect to the remote service. */ switch (transport) { case REMOTE_DRIVER_TRANSPORT_TLS: @@ -1005,20 +1017,6 @@ doRemoteOpen(virConnectPtr conn, break; case REMOTE_DRIVER_TRANSPORT_LIBSSH2: - if (!sockname) { - /* Right now we don't support default session connections */ - if (flags & VIR_DRV_OPEN_REMOTE_USER) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("Connecting to session instance without " - "socket path is not supported by the libssh2 " - "connection driver")); - goto failed; - } - - if (!(sockname = remoteGetUNIXSocketRoot(flags))) - goto failed; - } - VIR_DEBUG("Starting LibSSH2 session"); priv->client = virNetClientNewLibSSH2(priv->hostname, @@ -1040,20 +1038,6 @@ doRemoteOpen(virConnectPtr conn, break; case REMOTE_DRIVER_TRANSPORT_LIBSSH: - if (!sockname) { - /* Right now we don't support default session connections */ - if (flags & VIR_DRV_OPEN_REMOTE_USER) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("Connecting to session instance without " - "socket path is not supported by the libssh " - "connection driver")); - goto failed; - } - - if (!(sockname = remoteGetUNIXSocketRoot(flags))) - goto failed; - } - VIR_DEBUG("Starting libssh session"); priv->client = virNetClientNewLibssh(priv->hostname, @@ -1076,15 +1060,6 @@ doRemoteOpen(virConnectPtr conn, #ifndef WIN32 case REMOTE_DRIVER_TRANSPORT_UNIX: - if (!sockname) { - if (flags & VIR_DRV_OPEN_REMOTE_USER) - sockname = remoteGetUNIXSocketNonRoot(); - else - sockname = remoteGetUNIXSocketRoot(flags); - if (!sockname) - goto failed; - } - if ((flags & VIR_DRV_OPEN_REMOTE_AUTOSTART) && !(daemonPath = virFileFindResourceFull("libvirtd", NULL, NULL, @@ -1105,20 +1080,6 @@ doRemoteOpen(virConnectPtr conn, if (!command && VIR_STRDUP(command, "ssh") < 0) goto failed; - if (!sockname) { - /* Right now we don't support default session connections */ - if (flags & VIR_DRV_OPEN_REMOTE_USER) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", - _("Connecting to session instance without " - "socket path is not supported by the ssh " - "connection driver")); - goto failed; - } - - if (!(sockname = remoteGetUNIXSocketRoot(flags))) - goto failed; - } - if (!(priv->client = virNetClientNewSSH(priv->hostname, port, command, -- 2.21.0

On 7/11/19 6:05 PM, Daniel P. Berrangé wrote:
The ssh, libssh, libssh2 & unix transports all need to use a UNIX socket path, and duplicate some of the same logic for error checking. Pull this out into a separate method to increase code sharing.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_driver.c | 111 ++++++++++++------------------------- 1 file changed, 36 insertions(+), 75 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 87c184720c..c6905dffff 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -739,34 +739,35 @@ remoteConnectSupportsFeatureUnlocked(virConnectPtr conn, }
-#ifndef WIN32 -static char *remoteGetUNIXSocketNonRoot(void) +static char * +remoteGetUNIXSocket(remoteDriverTransport transport, + unsigned int flags) { char *sockname = NULL; - char *userdir = virGetUserRuntimeDirectory(); - - if (!userdir) - return NULL; + VIR_AUTOFREE(char *userdir);
Ouch, how does this even compile? VIR_AUTOFREE(char *) userdir = NULL; Michal

On Fri, Jul 12, 2019 at 03:36:56PM +0200, Michal Privoznik wrote:
On 7/11/19 6:05 PM, Daniel P. Berrangé wrote:
The ssh, libssh, libssh2 & unix transports all need to use a UNIX socket path, and duplicate some of the same logic for error checking. Pull this out into a separate method to increase code sharing.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_driver.c | 111 ++++++++++++------------------------- 1 file changed, 36 insertions(+), 75 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 87c184720c..c6905dffff 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -739,34 +739,35 @@ remoteConnectSupportsFeatureUnlocked(virConnectPtr conn, } -#ifndef WIN32 -static char *remoteGetUNIXSocketNonRoot(void) +static char * +remoteGetUNIXSocket(remoteDriverTransport transport, + unsigned int flags) { char *sockname = NULL; - char *userdir = virGetUserRuntimeDirectory(); - - if (!userdir) - return NULL; + VIR_AUTOFREE(char *userdir);
Ouch, how does this even compile?
VIR_AUTOFREE(char *) userdir = NULL;
syntax-check should have caught it. Erik

On Fri, Jul 12, 2019 at 03:36:56PM +0200, Michal Privoznik wrote:
On 7/11/19 6:05 PM, Daniel P. Berrangé wrote:
The ssh, libssh, libssh2 & unix transports all need to use a UNIX socket path, and duplicate some of the same logic for error checking. Pull this out into a separate method to increase code sharing.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/remote/remote_driver.c | 111 ++++++++++++------------------------- 1 file changed, 36 insertions(+), 75 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 87c184720c..c6905dffff 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -739,34 +739,35 @@ remoteConnectSupportsFeatureUnlocked(virConnectPtr conn, } -#ifndef WIN32 -static char *remoteGetUNIXSocketNonRoot(void) +static char * +remoteGetUNIXSocket(remoteDriverTransport transport, + unsigned int flags) { char *sockname = NULL; - char *userdir = virGetUserRuntimeDirectory(); - - if (!userdir) - return NULL; + VIR_AUTOFREE(char *userdir);
Ouch, how does this even compile?
Quite easily #define VIR_AUTOFREE(type) __attribute__((cleanup(virFree))) type will expand correctly regardless :)
VIR_AUTOFREE(char *) userdir = NULL;
but yes that's right. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

Historically URIs handled by the remote driver will always connect to the libvirtd UNIX socket. There will now be one daemon per driver, and each of these has its own UNIX sockets to connect to. It will still be possible to run the traditional monolithic libvirtd too which will have the original UNIX socket path. In addition there is a virproxyd daemon that doesn't run any drivers, but provides proxying for clients accessing libvirt over IP sockets, or tunnelling to the legacy libvirtd UNIX socket path. Finally when running inside a daemon, the remote driver must not reject connections unconditionally. For example, the QEMU driver needs to be able to connect to the network driver. The remote driver must thus be willing to handle connections even when inside the daemon, provided no local driver is registered. This refactoring causes the remote driver to prefer connecting to the per-driver daemons. The URI parameter "no_direct=1" can be used to force connecting to the legacy libvirtd UNIX socket. The remote driver will only ever spawn the per-driver daemons, or the legacy libvirtd. It won't ever try to spawn virtproxyd, as that is only there for IP based connectivity, or for access from legacy remote clients. The $HOME/.config/libvirt/libvirt.conf can also be set to have a parameter 'remote_direct=0|1' to hardcode the behaviour for all clients. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/driver.h | 2 + src/libvirt.c | 24 +++++ src/remote/remote_driver.c | 202 +++++++++++++++++++++++++++++++++---- src/remote/remote_driver.h | 3 - 4 files changed, 207 insertions(+), 24 deletions(-) diff --git a/src/driver.h b/src/driver.h index 898fb96df4..f7d667a03c 100644 --- a/src/driver.h +++ b/src/driver.h @@ -108,6 +108,8 @@ int virSetSharedNWFilterDriver(virNWFilterDriverPtr driver) ATTRIBUTE_RETURN_CHE int virSetSharedSecretDriver(virSecretDriverPtr driver) ATTRIBUTE_RETURN_CHECK; int virSetSharedStorageDriver(virStorageDriverPtr driver) ATTRIBUTE_RETURN_CHECK; +bool virHasDriverForURIScheme(const char *scheme); + int virDriverLoadModule(const char *name, const char *regfunc, bool required); diff --git a/src/libvirt.c b/src/libvirt.c index 7e665b6cba..e21cad0e2e 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -601,6 +601,30 @@ virRegisterConnectDriver(virConnectDriverPtr driver, } +/** + * virHasDriverForURIScheme: + * @scheme: the URI scheme + * + * Determine if there is a driver registered that explicitly + * handles URIs with the scheme @scheme. + * + * Returns: true if a driver is registered + */ +bool virHasDriverForURIScheme(const char *scheme) +{ + size_t i, j; + for (i = 0; i < virConnectDriverTabCount; i++) { + if (!virConnectDriverTab[i]->uriSchemes) + continue; + for (j = 0; virConnectDriverTab[i]->uriSchemes[j]; j++) { + if (STREQ(virConnectDriverTab[i]->uriSchemes[j], scheme)) + return true; + } + } + + return false; +} + /** * virRegisterStateDriver: * @driver: pointer to a driver block diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index c6905dffff..98a165e163 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -72,6 +72,22 @@ VIR_ENUM_IMPL(remoteDriverTransport, REMOTE_DRIVER_TRANSPORT_LAST, "tls", "unix", "ssh", "libssh2", "ext", "tcp", "libssh"); +typedef enum { + /* Prefer per-driver virt*d daemons, but fallback to legacy libvirtd */ + REMOTE_DRIVER_MODE_AUTO, + /* Always use the legacy libvirtd */ + REMOTE_DRIVER_MODE_LEGACY, + /* Always use the per-driver virt*d daemons */ + REMOTE_DRIVER_MODE_DIRECT, + + REMOTE_DRIVER_MODE_LAST +} remoteDriverMode; + +VIR_ENUM_DECL(remoteDriverMode); +VIR_ENUM_IMPL(remoteDriverMode, + REMOTE_DRIVER_MODE_LAST, + "auto", "legacy", "direct"); + #if SIZEOF_LONG < 8 # define HYPER_TO_TYPE(_type, _to, _from) \ do { \ @@ -92,6 +108,7 @@ VIR_ENUM_IMPL(remoteDriverTransport, static bool inside_daemon; + struct private_data { virMutex lock; @@ -740,8 +757,9 @@ remoteConnectSupportsFeatureUnlocked(virConnectPtr conn, static char * -remoteGetUNIXSocket(remoteDriverTransport transport, - unsigned int flags) +remoteGetUNIXSocketHelper(remoteDriverTransport transport, + const char *sock_prefix, + unsigned int flags) { char *sockname = NULL; VIR_AUTOFREE(char *userdir); @@ -758,21 +776,125 @@ remoteGetUNIXSocket(remoteDriverTransport transport, if (!(userdir = virGetUserRuntimeDirectory())) return NULL; - if (virAsprintf(&sockname, - "%s/" LIBVIRTD_USER_UNIX_SOCKET, userdir) < 0) + if (virAsprintf(&sockname, "%s/%s-sock", + userdir, sock_prefix) < 0) return NULL; } else { - if (VIR_STRDUP(sockname, - flags & VIR_DRV_OPEN_REMOTE_RO ? - LIBVIRTD_PRIV_UNIX_SOCKET_RO : - LIBVIRTD_PRIV_UNIX_SOCKET) < 0) + if (virAsprintf(&sockname, "%s/run/libvirt/%s-%s", + LOCALSTATEDIR, sock_prefix, + flags & VIR_DRV_OPEN_REMOTE_RO ? + "sock-ro" : "sock") < 0) return NULL; } - VIR_DEBUG("Chosen UNIX sockname %s", sockname); + VIR_DEBUG("Built UNIX sockname %s for transport %s prefix %s flags=0x%x", + sockname, remoteDriverTransportTypeToString(transport), + sock_prefix, flags); return sockname; } + +#define DRIVER_SCHEME_CHRS "abcdefghijklmnopqrstuvwxyz" +static char * +remoteGetUNIXSocket(remoteDriverTransport transport, + remoteDriverMode mode, + const char *driver, + char **daemon, + unsigned int flags) +{ + char *sock_name = NULL; + VIR_AUTOFREE(char *) direct_daemon = NULL; + VIR_AUTOFREE(char *) legacy_daemon = NULL; + VIR_AUTOFREE(char *) direct_sock_name = NULL; + VIR_AUTOFREE(char *) legacy_sock_name = NULL; + + if (strspn(driver, DRIVER_SCHEME_CHRS) < strlen(driver)) { + virReportError(VIR_ERR_INVALID_ARG, + _("Invalid character in driver '%s'"), driver); + return NULL; + } + + switch (mode) { + case REMOTE_DRIVER_MODE_AUTO: + if (virAsprintf(&direct_daemon, "virt%sd", driver) < 0) + return NULL; + + if (VIR_STRDUP(legacy_daemon, "libvirtd") < 0) + return NULL; + + if (!(direct_sock_name = remoteGetUNIXSocketHelper(transport, direct_daemon, flags))) + return NULL; + + if (!(legacy_sock_name = remoteGetUNIXSocketHelper(transport, "libvirt", flags))) + return NULL; + + if (!virFileExists(direct_sock_name) && + virFileExists(legacy_sock_name)) { + sock_name = legacy_sock_name; + legacy_sock_name = NULL; + *daemon = legacy_daemon; + legacy_daemon = NULL; + } else { + sock_name = direct_sock_name; + direct_sock_name = NULL; + *daemon = direct_daemon; + direct_daemon = NULL; + } + break; + + case REMOTE_DRIVER_MODE_DIRECT: + if (virAsprintf(&direct_daemon, "virt%sd", driver) < 0) + return NULL; + + if (!(sock_name = remoteGetUNIXSocketHelper(transport, direct_daemon, flags))) + return NULL; + + *daemon = direct_daemon; + direct_daemon = NULL; + break; + + case REMOTE_DRIVER_MODE_LEGACY: + if (VIR_STRDUP(legacy_daemon, "libvirtd") < 0) + return NULL; + + if (!(sock_name = remoteGetUNIXSocketHelper(transport, "libvirt", flags))) + return NULL; + + *daemon = legacy_daemon; + legacy_daemon = NULL; + break; + + case REMOTE_DRIVER_MODE_LAST: + default: + virReportEnumRangeError(remoteDriverMode, mode); + return NULL; + } + + VIR_DEBUG("Chosen UNIX sockname %s daemon %s " + "for mode %s transport %s flags=0x%x", + sock_name, NULLSTR(*daemon), + remoteDriverModeTypeToString(mode), + remoteDriverTransportTypeToString(transport), + flags); + return sock_name; +} + + +static const char * +remoteGetDaemonPathEnv(void) +{ + /* We prefer a VIRTD_PATH env var to use for all daemons, + * but if it is not set we will fallback to LIBVIRTD_PATH + * for previous behaviour + */ + if (virGetEnvBlockSUID("VIRTD_PATH") != NULL) { + return "VIRTD_PATH"; + } else { + return "LIBVIRTD_PATH"; + } +} + + /* * URIs that this driver needs to handle: * @@ -819,11 +941,20 @@ doRemoteOpen(virConnectPtr conn, VIR_AUTOFREE(char *) sshauth = NULL; VIR_AUTOFREE(char *) knownHostsVerify = NULL; VIR_AUTOFREE(char *) knownHosts = NULL; + VIR_AUTOFREE(char *) mode_str = NULL; + VIR_AUTOFREE(char *) daemon_name = NULL; bool sanity = true; bool verify = true; #ifndef WIN32 bool tty = true; #endif + int mode; + + if (inside_daemon && !conn->uri->server) { + mode = REMOTE_DRIVER_MODE_DIRECT; + } else { + mode = REMOTE_DRIVER_MODE_AUTO; + } /* We handle *ALL* URIs here. The caller has rejected any * URIs we don't care about */ @@ -908,7 +1039,7 @@ doRemoteOpen(virConnectPtr conn, EXTRACT_URI_ARG_STR("known_hosts", knownHosts); EXTRACT_URI_ARG_STR("known_hosts_verify", knownHostsVerify); EXTRACT_URI_ARG_STR("tls_priority", tls_priority); - + EXTRACT_URI_ARG_STR("mode", mode_str); EXTRACT_URI_ARG_BOOL("no_sanity", sanity); EXTRACT_URI_ARG_BOOL("no_verify", verify); #ifndef WIN32 @@ -955,6 +1086,21 @@ doRemoteOpen(virConnectPtr conn, goto failed; } + if (conf && !mode_str && + virConfGetValueString(conf, "remote_mode", &mode_str) < 0) + goto failed; + + if (mode_str && + (mode = remoteDriverModeTypeFromString(mode_str)) < 0) + goto failed; + + /* Sanity check that nothing requested !direct mode by mistake */ + if (inside_daemon && !conn->uri->server && mode != REMOTE_DRIVER_MODE_DIRECT) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("Connections from inside daemon must be direct")); + return VIR_DRV_OPEN_ERROR; + } + VIR_DEBUG("proceeding with name = %s", name); /* For ext transport, command is required. */ @@ -971,7 +1117,8 @@ doRemoteOpen(virConnectPtr conn, transport == REMOTE_DRIVER_TRANSPORT_LIBSSH || transport == REMOTE_DRIVER_TRANSPORT_LIBSSH2) && !sockname && - !(sockname = remoteGetUNIXSocket(transport, flags))) + !(sockname = remoteGetUNIXSocket(transport, mode, driver_str, + &daemon_name, flags))) goto failed; VIR_DEBUG("Chosen UNIX socket %s", NULLSTR(sockname)); @@ -1060,13 +1207,15 @@ doRemoteOpen(virConnectPtr conn, #ifndef WIN32 case REMOTE_DRIVER_TRANSPORT_UNIX: - if ((flags & VIR_DRV_OPEN_REMOTE_AUTOSTART) && - !(daemonPath = virFileFindResourceFull("libvirtd", - NULL, NULL, - abs_top_builddir "/src", - SBINDIR, - "LIBVIRTD_PATH"))) - goto failed; + if (flags & VIR_DRV_OPEN_REMOTE_AUTOSTART) { + const char *env_name = remoteGetDaemonPathEnv(); + if (!(daemonPath = virFileFindResourceFull(daemon_name, + NULL, NULL, + abs_top_builddir "/src", + SBINDIR, + env_name))) + goto failed; + } if (!(priv->client = virNetClientNewUNIX(sockname, flags & VIR_DRV_OPEN_REMOTE_AUTOSTART, @@ -1279,9 +1428,20 @@ remoteConnectOpen(virConnectPtr conn, remoteSplitURIScheme(conn->uri, &driver, &transport) < 0) goto cleanup; - if (inside_daemon && (!conn->uri || !conn->uri->server)) { - ret = VIR_DRV_OPEN_DECLINED; - goto cleanup; + if (inside_daemon) { + if (!conn->uri) { + ret = VIR_DRV_OPEN_DECLINED; + goto cleanup; + } + + /* If there's a driver registered we must defer to that. + * If there isn't a driver, we must connect in "direct" + * mode - see doRemoteOpen */ + if (!conn->uri->server && + virHasDriverForURIScheme(driver)) { + ret = VIR_DRV_OPEN_DECLINED; + goto cleanup; + } } if (!(priv = remoteAllocPrivateData())) diff --git a/src/remote/remote_driver.h b/src/remote/remote_driver.h index 132e478ef3..1fab5a6cc4 100644 --- a/src/remote/remote_driver.h +++ b/src/remote/remote_driver.h @@ -31,9 +31,6 @@ unsigned long remoteVersion(void); #define LIBVIRTD_LISTEN_ADDR NULL #define LIBVIRTD_TLS_PORT "16514" #define LIBVIRTD_TCP_PORT "16509" -#define LIBVIRTD_PRIV_UNIX_SOCKET LOCALSTATEDIR "/run/libvirt/libvirt-sock" -#define LIBVIRTD_PRIV_UNIX_SOCKET_RO LOCALSTATEDIR "/run/libvirt/libvirt-sock-ro" -#define LIBVIRTD_USER_UNIX_SOCKET "libvirt-sock" /* Defaults for PKI directory. */ #define LIBVIRT_PKI_DIR SYSCONFDIR "/pki" -- 2.21.0

On 7/11/19 6:05 PM, Daniel P. Berrangé wrote:
Historically URIs handled by the remote driver will always connect to the libvirtd UNIX socket. There will now be one daemon per driver, and each of these has its own UNIX sockets to connect to.
It will still be possible to run the traditional monolithic libvirtd too which will have the original UNIX socket path.
In addition there is a virproxyd daemon that doesn't run any drivers, but provides proxying for clients accessing libvirt over IP sockets, or tunnelling to the legacy libvirtd UNIX socket path.
Finally when running inside a daemon, the remote driver must not reject connections unconditionally. For example, the QEMU driver needs to be able to connect to the network driver. The remote driver must thus be willing to handle connections even when inside the daemon, provided no local driver is registered.
This refactoring causes the remote driver to prefer connecting to the per-driver daemons. The URI parameter "no_direct=1" can be used to force connecting to the legacy libvirtd UNIX socket.
The remote driver will only ever spawn the per-driver daemons, or the legacy libvirtd. It won't ever try to spawn virtproxyd, as that is only there for IP based connectivity, or for access from legacy remote clients.
The $HOME/.config/libvirt/libvirt.conf can also be set to have a parameter 'remote_direct=0|1' to hardcode the behaviour for all clients.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/driver.h | 2 + src/libvirt.c | 24 +++++ src/remote/remote_driver.c | 202 +++++++++++++++++++++++++++++++++---- src/remote/remote_driver.h | 3 - 4 files changed, 207 insertions(+), 24 deletions(-)
diff --git a/src/driver.h b/src/driver.h index 898fb96df4..f7d667a03c 100644 --- a/src/driver.h +++ b/src/driver.h @@ -108,6 +108,8 @@ int virSetSharedNWFilterDriver(virNWFilterDriverPtr driver) ATTRIBUTE_RETURN_CHE int virSetSharedSecretDriver(virSecretDriverPtr driver) ATTRIBUTE_RETURN_CHECK; int virSetSharedStorageDriver(virStorageDriverPtr driver) ATTRIBUTE_RETURN_CHECK;
+bool virHasDriverForURIScheme(const char *scheme); + int virDriverLoadModule(const char *name, const char *regfunc, bool required); diff --git a/src/libvirt.c b/src/libvirt.c index 7e665b6cba..e21cad0e2e 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -601,6 +601,30 @@ virRegisterConnectDriver(virConnectDriverPtr driver, }
+/** + * virHasDriverForURIScheme: + * @scheme: the URI scheme + * + * Determine if there is a driver registered that explicitly + * handles URIs with the scheme @scheme. + * + * Returns: true if a driver is registered + */ +bool virHasDriverForURIScheme(const char *scheme) +{ + size_t i, j; + for (i = 0; i < virConnectDriverTabCount; i++) { + if (!virConnectDriverTab[i]->uriSchemes) + continue; + for (j = 0; virConnectDriverTab[i]->uriSchemes[j]; j++) { + if (STREQ(virConnectDriverTab[i]->uriSchemes[j], scheme)) + return true; + } + } + + return false; +} + /** * virRegisterStateDriver: * @driver: pointer to a driver block diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index c6905dffff..98a165e163 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -72,6 +72,22 @@ VIR_ENUM_IMPL(remoteDriverTransport, REMOTE_DRIVER_TRANSPORT_LAST, "tls", "unix", "ssh", "libssh2", "ext", "tcp", "libssh");
+typedef enum { + /* Prefer per-driver virt*d daemons, but fallback to legacy libvirtd */ + REMOTE_DRIVER_MODE_AUTO, + /* Always use the legacy libvirtd */ + REMOTE_DRIVER_MODE_LEGACY, + /* Always use the per-driver virt*d daemons */ + REMOTE_DRIVER_MODE_DIRECT, + + REMOTE_DRIVER_MODE_LAST +} remoteDriverMode; + +VIR_ENUM_DECL(remoteDriverMode); +VIR_ENUM_IMPL(remoteDriverMode, + REMOTE_DRIVER_MODE_LAST, + "auto", "legacy", "direct"); + #if SIZEOF_LONG < 8 # define HYPER_TO_TYPE(_type, _to, _from) \ do { \ @@ -92,6 +108,7 @@ VIR_ENUM_IMPL(remoteDriverTransport,
static bool inside_daemon;
+ struct private_data { virMutex lock;
@@ -740,8 +757,9 @@ remoteConnectSupportsFeatureUnlocked(virConnectPtr conn,
static char * -remoteGetUNIXSocket(remoteDriverTransport transport, - unsigned int flags) +remoteGetUNIXSocketHelper(remoteDriverTransport transport, + const char *sock_prefix, + unsigned int flags) { char *sockname = NULL; VIR_AUTOFREE(char *userdir); @@ -758,21 +776,125 @@ remoteGetUNIXSocket(remoteDriverTransport transport, if (!(userdir = virGetUserRuntimeDirectory())) return NULL;
- if (virAsprintf(&sockname, - "%s/" LIBVIRTD_USER_UNIX_SOCKET, userdir) < 0) + if (virAsprintf(&sockname, "%s/%s-sock", + userdir, sock_prefix) < 0) return NULL; } else { - if (VIR_STRDUP(sockname, - flags & VIR_DRV_OPEN_REMOTE_RO ? - LIBVIRTD_PRIV_UNIX_SOCKET_RO : - LIBVIRTD_PRIV_UNIX_SOCKET) < 0) + if (virAsprintf(&sockname, "%s/run/libvirt/%s-%s", + LOCALSTATEDIR, sock_prefix, + flags & VIR_DRV_OPEN_REMOTE_RO ? + "sock-ro" : "sock") < 0) return NULL; }
- VIR_DEBUG("Chosen UNIX sockname %s", sockname); + VIR_DEBUG("Built UNIX sockname %s for transport %s prefix %s flags=0x%x", + sockname, remoteDriverTransportTypeToString(transport), + sock_prefix, flags); return sockname; }
+ +#define DRIVER_SCHEME_CHRS "abcdefghijklmnopqrstuvwxyz" +static char * +remoteGetUNIXSocket(remoteDriverTransport transport, + remoteDriverMode mode, + const char *driver, + char **daemon, + unsigned int flags) +{ + char *sock_name = NULL; + VIR_AUTOFREE(char *) direct_daemon = NULL; + VIR_AUTOFREE(char *) legacy_daemon = NULL; + VIR_AUTOFREE(char *) direct_sock_name = NULL; + VIR_AUTOFREE(char *) legacy_sock_name = NULL; + + if (strspn(driver, DRIVER_SCHEME_CHRS) < strlen(driver)) {
Note that if no connection URI was provided then @driver is going to be NULL here and thus calling strlen() over it is going to crash.
+ virReportError(VIR_ERR_INVALID_ARG, + _("Invalid character in driver '%s'"), driver); + return NULL; + }
Michal

When the drivers acquire their pidfile lock we don't want to wait if the lock is already held. We need the driver to immediately report error, causing the daemon to exit. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/bhyve/bhyve_driver.c | 2 +- src/interface/interface_backend_netcf.c | 2 +- src/interface/interface_backend_udev.c | 2 +- src/libxl/libxl_driver.c | 2 +- src/lxc/lxc_driver.c | 2 +- src/network/leaseshelper.c | 2 +- src/node_device/node_device_hal.c | 2 +- src/node_device/node_device_udev.c | 2 +- src/nwfilter/nwfilter_driver.c | 2 +- src/qemu/qemu_driver.c | 2 +- src/secret/secret_driver.c | 2 +- src/vz/vz_driver.c | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index cfcf4e1fba..5387ac5570 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -1280,7 +1280,7 @@ bhyveStateInitialize(bool privileged, } if ((bhyve_driver->lockFD = - virPidFileAcquire(BHYVE_STATE_DIR, "driver", true, getpid())) < 0) + virPidFileAcquire(BHYVE_STATE_DIR, "driver", false, getpid())) < 0) goto cleanup; if (virDomainObjListLoadAllConfigs(bhyve_driver->domains, diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c index 868e49c56e..f575768c4c 100644 --- a/src/interface/interface_backend_netcf.c +++ b/src/interface/interface_backend_netcf.c @@ -120,7 +120,7 @@ netcfStateInitialize(bool privileged, } if ((driver->lockFD = - virPidFileAcquire(driver->stateDir, "driver", true, getpid())) < 0) + virPidFileAcquire(driver->stateDir, "driver", false, getpid())) < 0) goto error; /* open netcf */ diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c index fcd7f1c04a..2feaeb95b7 100644 --- a/src/interface/interface_backend_udev.c +++ b/src/interface/interface_backend_udev.c @@ -1199,7 +1199,7 @@ udevStateInitialize(bool privileged, } if ((driver->lockFD = - virPidFileAcquire(driver->stateDir, "driver", true, getpid())) < 0) + virPidFileAcquire(driver->stateDir, "driver", false, getpid())) < 0) goto cleanup; driver->udev = udev_new(); diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index a99c7471bb..492028c487 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -747,7 +747,7 @@ libxlStateInitialize(bool privileged, } if ((libxl_driver->lockFD = - virPidFileAcquire(cfg->stateDir, "driver", true, getpid())) < 0) + virPidFileAcquire(cfg->stateDir, "driver", false, getpid())) < 0) goto error; if (!(libxl_driver->lockManager = diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 3982c24f34..d0b6703101 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1607,7 +1607,7 @@ static int lxcStateInitialize(bool privileged, } if ((lxc_driver->lockFD = - virPidFileAcquire(cfg->stateDir, "driver", true, getpid())) < 0) + virPidFileAcquire(cfg->stateDir, "driver", false, getpid())) < 0) goto cleanup; /* Get all the running persistent or transient configs first */ diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c index 89d9a003e2..2a10fbf33a 100644 --- a/src/network/leaseshelper.c +++ b/src/network/leaseshelper.c @@ -164,7 +164,7 @@ main(int argc, char **argv) goto cleanup; /* Try to claim the pidfile, exiting if we can't */ - if ((pid_file_fd = virPidFileAcquirePath(pid_file, true, getpid())) < 0) + if ((pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0) goto cleanup; /* Since interfaces can be hot plugged, we need to make sure that the diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c index 1920f4566e..1f3f867599 100644 --- a/src/node_device/node_device_hal.c +++ b/src/node_device/node_device_hal.c @@ -637,7 +637,7 @@ nodeStateInitialize(bool privileged ATTRIBUTE_UNUSED, } if ((driver->lockFD = - virPidFileAcquire(driver->stateDir, "driver", true, getpid())) < 0) + virPidFileAcquire(driver->stateDir, "driver", false, getpid())) < 0) goto failure; if (!(driver->devs = virNodeDeviceObjListNew())) diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index d883462948..8bc63c506c 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -1848,7 +1848,7 @@ nodeStateInitialize(bool privileged, } if ((driver->lockFD = - virPidFileAcquire(driver->stateDir, "driver", true, getpid())) < 0) + virPidFileAcquire(driver->stateDir, "driver", false, getpid())) < 0) goto cleanup; if (!(driver->devs = virNodeDeviceObjListNew()) || diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c index 43561241f6..530e4f5872 100644 --- a/src/nwfilter/nwfilter_driver.c +++ b/src/nwfilter/nwfilter_driver.c @@ -215,7 +215,7 @@ nwfilterStateInitialize(bool privileged, } if ((driver->lockFD = - virPidFileAcquire(driver->stateDir, "driver", true, getpid())) < 0) + virPidFileAcquire(driver->stateDir, "driver", false, getpid())) < 0) goto error; if (virNWFilterIPAddrMapInit() < 0) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a52b54b9d8..9793ada367 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -677,7 +677,7 @@ qemuStateInitialize(bool privileged, } if ((qemu_driver->lockFD = - virPidFileAcquire(cfg->stateDir, "driver", true, getpid())) < 0) + virPidFileAcquire(cfg->stateDir, "driver", false, getpid())) < 0) goto error; qemu_driver->qemuImgBinary = virFindFileInPath("qemu-img"); diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c index 9344948db4..0af2bcef96 100644 --- a/src/secret/secret_driver.c +++ b/src/secret/secret_driver.c @@ -504,7 +504,7 @@ secretStateInitialize(bool privileged, } if ((driver->lockFD = - virPidFileAcquire(driver->stateDir, "driver", true, getpid())) < 0) + virPidFileAcquire(driver->stateDir, "driver", false, getpid())) < 0) goto error; if (!(driver->secrets = virSecretObjListNew())) diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c index 75430fb0d9..f5d05a7f43 100644 --- a/src/vz/vz_driver.c +++ b/src/vz/vz_driver.c @@ -4129,7 +4129,7 @@ vzStateInitialize(bool privileged, } if ((vz_driver_lock_fd = - virPidFileAcquire(VZ_STATEDIR, "driver", true, getpid())) < 0) + virPidFileAcquire(VZ_STATEDIR, "driver", false, getpid())) < 0) return -1; if (prlsdkInit() < 0) { -- 2.21.0

Typo meant we use 'nodedev' instead of 'interface'. This doesn't hurt libvirtd because if a process tries to acquire a lock it already holds it will succeed. It fails when nodedev & interface drivers are in separate daemons though. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- src/interface/interface_backend_netcf.c | 4 ++-- src/interface/interface_backend_udev.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c index f575768c4c..0000587cee 100644 --- a/src/interface/interface_backend_netcf.c +++ b/src/interface/interface_backend_netcf.c @@ -102,14 +102,14 @@ netcfStateInitialize(bool privileged, if (privileged) { if (virAsprintf(&driver->stateDir, - "%s/run/libvirt/nodedev", LOCALSTATEDIR) < 0) + "%s/run/libvirt/interface", LOCALSTATEDIR) < 0) goto error; } else { VIR_AUTOFREE(char *) rundir = NULL; if (!(rundir = virGetUserRuntimeDirectory())) goto error; - if (virAsprintf(&driver->stateDir, "%s/nodedev/run", rundir) < 0) + if (virAsprintf(&driver->stateDir, "%s/interface/run", rundir) < 0) goto error; } diff --git a/src/interface/interface_backend_udev.c b/src/interface/interface_backend_udev.c index 2feaeb95b7..fea5108dbc 100644 --- a/src/interface/interface_backend_udev.c +++ b/src/interface/interface_backend_udev.c @@ -1181,14 +1181,14 @@ udevStateInitialize(bool privileged, if (privileged) { if (virAsprintf(&driver->stateDir, - "%s/run/libvirt/nodedev", LOCALSTATEDIR) < 0) + "%s/run/libvirt/interface", LOCALSTATEDIR) < 0) goto cleanup; } else { VIR_AUTOFREE(char *) rundir = NULL; if (!(rundir = virGetUserRuntimeDirectory())) goto cleanup; - if (virAsprintf(&driver->stateDir, "%s/nodedev/run", rundir) < 0) + if (virAsprintf(&driver->stateDir, "%s/interface/run", rundir) < 0) goto cleanup; } -- 2.21.0

On 7/11/19 6:04 PM, Daniel P. Berrangé wrote:
This is what all the driver refactoring I've done has been about enabling.
We gain new daemons for each driver, for the primary virt drivers:
virtlibxld virtlxcd virtqemud virtvboxd virtvzd
And again for the secondary drivers
virtinterfaced virtnetworkd virtnodedevd virtnwfilterd virtsecretd virtstoraged
Finally to support IP connectivity, and also the legacy lbivirtd UNIX domain socket (for the old libvirt remote driver SSH tunnelling):
virtproxyd
The the sake of facilitating upgrades, the existing libvirtd still exists and works the same way it always has.
You either run libvirtd, or you run the per-driver daemons, never both.
The remote driver will look to see whether libvirtd is running to figure out whether to connect to libvirtd or the new per-driver daemons.
When auto-spawning daemons for nonroot users, we default to spawning the per-driver daemons.
This can be controlled with a UR parameter "?mode=direct|legacy|auto", where 'direct' means per-driver and 'legacy' means libvirtd (or indirect via virtproxyd if that's running).
Still todo
- Add systemd unit files for the new daemons - Make it possible to disable build of libvirtd, or of the per-driver daemons so downstream vendors can decide which to ship - Tuning of the daemon defaults for worker threads to better suit the fact that we have per-driver daemons - More work on RPM packaging to allow install of per-driver daemosn without pulling in libvirtd too - A bunch of stuff that doesn't occurr to me right now - Identify & fix more bugs I've created here
Teach virt-admin how to connect to individual daemons.
Daniel P. Berrangé (29): rpc: add API for checking whether an auth scheme is in use on a server remote: simplify libvirtd code for deciding if SASL auth is needed logging: pass binary name not logfile name when enabling logging remote: conditionalize socket names in libvirtd daemon remote: conditionalize daemon name in libvirtd daemon remote: conditionalize driver loading in libvirtd daemon remote: conditionalize IP socket usage in libvirtd daemon remote: conditionalize IP socket config in libvirtd.conf remote: conditionalize IP socket config in augeas definitions remote: refactor & rename variables for building libvirtd secret: introduce virtsecretd daemon network: introduce virtnetworkd daemon interface: introduce virtinterfaced daemon storage: introduce virtstoraged daemon nodedev: introduce virtnodedevd daemon nwfilter: introduce virtnwfilterd daemon libxl: introduce virtlibxld daemon qemu: introduce virtqemud daemon lxc: introduce virtlxcd daemon vbox: introduce virtvboxd daemon bhyve: introduce virtbhyved daemon vz: introduce virtvzd daemon remote: introduce virtproxyd daemon to handle IP connectivity remote: open secondary drivers via remote driver if needed remote: use enum helpers for parsing remote driver transport remote: refactor the code for choosing the UNIX socket path remote: switch to connect to per-driver daemons by default all: don't wait for driver lock during startup interface: fix driver name in state directory path
.gitignore | 12 + build-aux/augeas-gentest.pl | 2 +- libvirt.spec.in | 10 + src/bhyve/Makefile.inc.am | 14 + src/bhyve/bhyve_driver.c | 2 +- src/driver.h | 2 + src/interface/Makefile.inc.am | 14 + src/interface/interface_backend_netcf.c | 6 +- src/interface/interface_backend_udev.c | 6 +- src/libvirt.c | 24 ++ src/libvirt_remote.syms | 1 + src/libxl/Makefile.inc.am | 14 + src/libxl/libxl_driver.c | 2 +- src/locking/lock_daemon.c | 2 +- src/logging/log_daemon.c | 2 +- src/lxc/Makefile.inc.am | 15 + src/lxc/lxc_driver.c | 2 +- src/network/Makefile.inc.am | 14 + src/network/leaseshelper.c | 2 +- src/node_device/Makefile.inc.am | 14 + src/node_device/node_device_hal.c | 2 +- src/node_device/node_device_udev.c | 2 +- src/nwfilter/Makefile.inc.am | 14 + src/nwfilter/nwfilter_driver.c | 2 +- src/qemu/Makefile.inc.am | 14 + src/qemu/qemu_driver.c | 2 +- src/remote/Makefile.inc.am | 153 ++++--- src/remote/{libvirtd.aug => libvirtd.aug.in} | 24 +- .../{libvirtd.conf => libvirtd.conf.in} | 42 +- src/remote/remote_daemon.c | 221 +++++++--- src/remote/remote_daemon_config.c | 41 +- src/remote/remote_daemon_config.h | 9 +- src/remote/remote_daemon_dispatch.c | 82 +++- src/remote/remote_driver.c | 391 ++++++++++++------ src/remote/remote_driver.h | 4 - src/remote/test_libvirtd.aug.in | 16 +- src/rpc/virnetserver.c | 17 + src/rpc/virnetserver.h | 3 + src/secret/Makefile.inc.am | 14 + src/secret/secret_driver.c | 2 +- src/storage/Makefile.inc.am | 14 + src/util/virlog.c | 20 +- src/vbox/Makefile.inc.am | 14 + src/vz/Makefile.inc.am | 14 + src/vz/vz_driver.c | 2 +- 45 files changed, 938 insertions(+), 341 deletions(-) rename src/remote/{libvirtd.aug => libvirtd.aug.in} (88%) rename src/remote/{libvirtd.conf => libvirtd.conf.in} (95%)
Patches look good, but they have couple of small flaws. I don't want to make you post v2, so you can count on my ACK if you fix all issues I've raised. But if you'd like to post v2 feel free to do so. Michal
participants (6)
-
Boris Fiuczynski
-
Daniel P. Berrangé
-
Erik Skultety
-
Ján Tomko
-
Michal Privoznik
-
Peter Krempa