[PATCH 0/4] Introduce shared daemon startup code

Libvirt ships several daemons (libvirtd, virtlogd, virtlockd) that all have similar code around general daemon startup. Right now the code is duplicated for each daemon, but it could be shared, like in a new file src/util/virdaemon.c. Rafael Fonseca (4): util: introduce shared daemon startup code locking: use shared daemon startup code logging: use shared daemon startup code remote: use shared daemon startup code src/libvirt_private.syms | 6 + src/locking/lock_daemon.c | 251 ++++------------------------------- src/logging/log_daemon.c | 239 ++++----------------------------- src/remote/remote_daemon.c | 263 +++---------------------------------- src/util/Makefile.inc.am | 2 + src/util/virdaemon.c | 255 +++++++++++++++++++++++++++++++++++ src/util/virdaemon.h | 74 +++++++++++ 7 files changed, 410 insertions(+), 680 deletions(-) create mode 100644 src/util/virdaemon.c create mode 100644 src/util/virdaemon.h -- 2.25.1

Several daemons have similar code around general daemon startup code. Let's move it into a file and share it among them. Signed-off-by: Rafael Fonseca <r4f4rfs@gmail.com> --- src/libvirt_private.syms | 6 + src/util/Makefile.inc.am | 2 + src/util/virdaemon.c | 255 +++++++++++++++++++++++++++++++++++++++ src/util/virdaemon.h | 74 ++++++++++++ 4 files changed, 337 insertions(+) create mode 100644 src/util/virdaemon.c create mode 100644 src/util/virdaemon.h diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 3f032c7963..e276f55bb1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1906,6 +1906,12 @@ virCryptoHashString; virCryptoHaveCipher; +# util/virdaemon.h +virDaemonForkIntoBackground; +virDaemonSetupLogging; +virDaemonUnixSocketPaths; + + # util/virdbus.h virDBusCallMethod; virDBusCloseSystemBus; diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am index 718b11a5f4..5bc60cb5ea 100644 --- a/src/util/Makefile.inc.am +++ b/src/util/Makefile.inc.am @@ -42,6 +42,8 @@ UTIL_SOURCES = \ util/virconf.h \ util/vircrypto.c \ util/vircrypto.h \ + util/virdaemon.c \ + util/virdaemon.h \ util/virdbus.c \ util/virdbus.h \ util/virdbuspriv.h \ diff --git a/src/util/virdaemon.c b/src/util/virdaemon.c new file mode 100644 index 0000000000..4b63b44d66 --- /dev/null +++ b/src/util/virdaemon.c @@ -0,0 +1,255 @@ +/* + * virdaemon.c: shared daemon setup code + * + * Copyright (C) 2020 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdbool.h> + +#include "virdaemon.h" +#include "virutil.h" +#include "virfile.h" +#include "virlog.h" +#include "viralloc.h" + +#include "configmake.h" + +int +virDaemonForkIntoBackground(const char *argv0) +{ + int statuspipe[2]; + if (virPipeQuiet(statuspipe) < 0) + return -1; + + pid_t pid = fork(); + switch (pid) { + case 0: + { + /* intermediate child */ + int stdinfd = -1; + int stdoutfd = -1; + int nextpid; + + VIR_FORCE_CLOSE(statuspipe[0]); + + if ((stdinfd = open("/dev/null", O_RDONLY)) <= STDERR_FILENO) + goto cleanup; + if ((stdoutfd = open("/dev/null", O_WRONLY)) <= STDERR_FILENO) + goto cleanup; + if (dup2(stdinfd, STDIN_FILENO) != STDIN_FILENO) + goto cleanup; + if (dup2(stdoutfd, STDOUT_FILENO) != STDOUT_FILENO) + goto cleanup; + if (dup2(stdoutfd, STDERR_FILENO) != STDERR_FILENO) + goto cleanup; + if (VIR_CLOSE(stdinfd) < 0) + goto cleanup; + if (VIR_CLOSE(stdoutfd) < 0) + goto cleanup; + + if (setsid() < 0) + goto cleanup; + + nextpid = fork(); + switch (nextpid) { + case 0: /* grandchild */ + return statuspipe[1]; + case -1: /* error */ + goto cleanup; + default: /* intermediate child succeeded */ + _exit(EXIT_SUCCESS); + } + + cleanup: + VIR_FORCE_CLOSE(stdoutfd); + VIR_FORCE_CLOSE(stdinfd); + VIR_FORCE_CLOSE(statuspipe[1]); + _exit(EXIT_FAILURE); + + } + + case -1: /* error in parent */ + goto error; + + default: + { + /* parent */ + int got, exitstatus = 0; + int ret; + char status; + + VIR_FORCE_CLOSE(statuspipe[1]); + + /* We wait to make sure the first child forked successfully */ + if ((got = waitpid(pid, &exitstatus, 0)) < 0 || + got != pid || + exitstatus != 0) { + goto error; + } + + /* If we got here, then the grandchild was spawned, so we + * must exit. Block until the second child initializes + * successfully */ + again: + ret = read(statuspipe[0], &status, 1); + if (ret == -1 && errno == EINTR) + goto again; + + VIR_FORCE_CLOSE(statuspipe[0]); + + if (ret != 1) { + fprintf(stderr, + _("%s: error: unable to determine if daemon is " + "running: %s\n"), argv0, + g_strerror(errno)); + exit(EXIT_FAILURE); + } else if (status != 0) { + fprintf(stderr, + _("%s: error: %s. Check /var/log/messages or run without " + "--daemon for more info.\n"), argv0, + virDaemonErrTypeToString(status)); + exit(EXIT_FAILURE); + } + _exit(EXIT_SUCCESS); + } + } + +error: + VIR_FORCE_CLOSE(statuspipe[0]); + VIR_FORCE_CLOSE(statuspipe[1]); + return -1; +} + + +/* + * Set up the logging environment + * By default if daemonized all errors go to the logfile libvirtd.log, + * but if verbose or error debugging is asked for then also output + * informational and debug messages. Default size if 64 kB. + */ +void +virDaemonSetupLogging(const char *daemon_name, + unsigned int log_level, + char *log_filters, + char *log_outputs, + bool privileged, + bool verbose, + bool godaemon) +{ + virLogReset(); + + /* + * Libvirtd's order of precedence is: + * cmdline > environment > config + * + * Given the precedence, we must process the variables in the opposite + * order, each one overriding the previous. + */ + if (log_level != 0) + virLogSetDefaultPriority(log_level); + + /* In case the config is empty, both filters and outputs will become empty, + * however we can't start with empty outputs, thus we'll need to define and + * setup a default one. + */ + ignore_value(virLogSetFilters(log_filters)); + ignore_value(virLogSetOutputs(log_outputs)); + + /* If there are some environment variables defined, use those instead */ + virLogSetFromEnv(); + + /* + * Command line override for --verbose + */ + if ((verbose) && (virLogGetDefaultPriority() > VIR_LOG_INFO)) + virLogSetDefaultPriority(VIR_LOG_INFO); + + /* Define the default output. This is only applied if there was no setting + * from either the config or the environment. + */ + virLogSetDefaultOutput(daemon_name, godaemon, privileged); + + if (virLogGetNbOutputs() == 0) + virLogSetOutputs(virLogGetDefaultOutput()); +} + + +int +virDaemonUnixSocketPaths(const char *sock_prefix, + bool privileged, + char *unix_sock_dir, + char **sockfile, + char **rosockfile, + char **admsockfile) +{ + int ret = -1; + char *rundir = NULL; + + if (unix_sock_dir) { + if (sockfile) + *sockfile = g_strdup_printf("%s/%s-sock", unix_sock_dir, sock_prefix); + + if (privileged) { + if (rosockfile) + *rosockfile = g_strdup_printf("%s/%s-sock-ro", + unix_sock_dir, sock_prefix); + if (admsockfile) + *admsockfile = g_strdup_printf("%s/%s-admin-sock", + unix_sock_dir, sock_prefix); + } + } else { + if (privileged) { + if (sockfile) + *sockfile = g_strdup_printf("%s/libvirt/%s-sock", + RUNSTATEDIR, sock_prefix); + if (rosockfile) + *rosockfile = g_strdup_printf("%s/libvirt/%s-sock-ro", + RUNSTATEDIR, sock_prefix); + if (admsockfile) + *admsockfile = g_strdup_printf("%s/libvirt/%s-admin-sock", + RUNSTATEDIR, sock_prefix); + } else { + mode_t old_umask; + + rundir = virGetUserRuntimeDirectory(); + + old_umask = umask(077); + if (virFileMakePath(rundir) < 0) { + umask(old_umask); + goto cleanup; + } + umask(old_umask); + + if (sockfile) + *sockfile = g_strdup_printf("%s/%s-sock", rundir, sock_prefix); + if (admsockfile) + *admsockfile = g_strdup_printf("%s/%s-admin-sock", rundir, sock_prefix); + } + } + + ret = 0; + cleanup: + VIR_FREE(rundir); + return ret; +} diff --git a/src/util/virdaemon.h b/src/util/virdaemon.h new file mode 100644 index 0000000000..d032b8ddb3 --- /dev/null +++ b/src/util/virdaemon.h @@ -0,0 +1,74 @@ +/* + * virdaemon.h: shared daemon setup code + * + * Copyright (C) 2020 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see + * <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "virenum.h" + +enum { + VIR_DAEMON_ERR_NONE = 0, + VIR_DAEMON_ERR_PIDFILE, + VIR_DAEMON_ERR_RUNDIR, + VIR_DAEMON_ERR_INIT, + VIR_DAEMON_ERR_SIGNAL, + VIR_DAEMON_ERR_PRIVS, + VIR_DAEMON_ERR_NETWORK, + VIR_DAEMON_ERR_CONFIG, + VIR_DAEMON_ERR_HOOKS, + VIR_DAEMON_ERR_REEXEC, + VIR_DAEMON_ERR_AUDIT, + VIR_DAEMON_ERR_DRIVER, + + VIR_DAEMON_ERR_LAST +}; + +VIR_ENUM_DECL(virDaemonErr); +VIR_ENUM_IMPL(virDaemonErr, + VIR_DAEMON_ERR_LAST, + "Initialization successful", + "Unable to obtain pidfile", + "Unable to create rundir", + "Unable to initialize libvirt", + "Unable to setup signal handlers", + "Unable to drop privileges", + "Unable to initialize network sockets", + "Unable to load configuration file", + "Unable to look for hook scripts", + "Unable to re-execute daemon", + "Unable to initialize audit system", + "Unable to initialize driver", +); + +int virDaemonForkIntoBackground(const char *argv0); + +void virDaemonSetupLogging(const char *daemon_name, + unsigned int log_level, + char *log_filters, + char *log_outputs, + bool privileged, + bool verbose, + bool godaemon); + +int virDaemonUnixSocketPaths(const char *sock_prefix, + bool privileged, + char *unix_sock_dir, + char **sockfile, + char **rosockfile, + char **adminSockfile); -- 2.25.1

On 26. 3. 2020 16:18, Rafael Fonseca wrote:
Several daemons have similar code around general daemon startup code. Let's move it into a file and share it among them.
Signed-off-by: Rafael Fonseca <r4f4rfs@gmail.com> --- src/libvirt_private.syms | 6 + src/util/Makefile.inc.am | 2 + src/util/virdaemon.c | 255 +++++++++++++++++++++++++++++++++++++++ src/util/virdaemon.h | 74 ++++++++++++ 4 files changed, 337 insertions(+) create mode 100644 src/util/virdaemon.c create mode 100644 src/util/virdaemon.h
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 3f032c7963..e276f55bb1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1906,6 +1906,12 @@ virCryptoHashString; virCryptoHaveCipher;
+# util/virdaemon.h +virDaemonForkIntoBackground; +virDaemonSetupLogging; +virDaemonUnixSocketPaths; + + # util/virdbus.h virDBusCallMethod; virDBusCloseSystemBus; diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am index 718b11a5f4..5bc60cb5ea 100644 --- a/src/util/Makefile.inc.am +++ b/src/util/Makefile.inc.am @@ -42,6 +42,8 @@ UTIL_SOURCES = \ util/virconf.h \ util/vircrypto.c \ util/vircrypto.h \ + util/virdaemon.c \ + util/virdaemon.h \ util/virdbus.c \ util/virdbus.h \ util/virdbuspriv.h \ diff --git a/src/util/virdaemon.c b/src/util/virdaemon.c new file mode 100644 index 0000000000..4b63b44d66 --- /dev/null +++ b/src/util/virdaemon.c @@ -0,0 +1,255 @@ +/* + * virdaemon.c: shared daemon setup code + * + * Copyright (C) 2020 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdbool.h> + +#include "virdaemon.h" +#include "virutil.h" +#include "virfile.h" +#include "virlog.h" +#include "viralloc.h" + +#include "configmake.h" + +int +virDaemonForkIntoBackground(const char *argv0) +{ + int statuspipe[2]; + if (virPipeQuiet(statuspipe) < 0) + return -1; + + pid_t pid = fork();
This will fail 'make syntax-check' because the prohibit_fork rule doesn't allow plain fork(). We need to white list this file, becasue virFork() does more than just plain fork() and we really want the plain fork(). Well, all other daemons are whitelisted there exactly because of this code. So we will need to remove them from the whitelist as we switch them over to this new code.
+ switch (pid) { + case 0: + { + /* intermediate child */ + int stdinfd = -1; + int stdoutfd = -1; + int nextpid; + + VIR_FORCE_CLOSE(statuspipe[0]); + + if ((stdinfd = open("/dev/null", O_RDONLY)) <= STDERR_FILENO) + goto cleanup; + if ((stdoutfd = open("/dev/null", O_WRONLY)) <= STDERR_FILENO)
I think this should be '< 0' because we are interested in the success of open() really.
+ goto cleanup; + if (dup2(stdinfd, STDIN_FILENO) != STDIN_FILENO) + goto cleanup; + if (dup2(stdoutfd, STDOUT_FILENO) != STDOUT_FILENO) + goto cleanup; + if (dup2(stdoutfd, STDERR_FILENO) != STDERR_FILENO) + goto cleanup; + if (VIR_CLOSE(stdinfd) < 0) + goto cleanup; + if (VIR_CLOSE(stdoutfd) < 0) + goto cleanup; + + if (setsid() < 0) + goto cleanup; + + nextpid = fork(); + switch (nextpid) { + case 0: /* grandchild */ + return statuspipe[1]; + case -1: /* error */ + goto cleanup; + default: /* intermediate child succeeded */ + _exit(EXIT_SUCCESS); + } + + cleanup: + VIR_FORCE_CLOSE(stdoutfd); + VIR_FORCE_CLOSE(stdinfd); + VIR_FORCE_CLOSE(statuspipe[1]); + _exit(EXIT_FAILURE); + + } + + case -1: /* error in parent */ + goto error; + + default: + { + /* parent */ + int got, exitstatus = 0; + int ret; + char status; + + VIR_FORCE_CLOSE(statuspipe[1]); + + /* We wait to make sure the first child forked successfully */ + if ((got = waitpid(pid, &exitstatus, 0)) < 0 || + got != pid || + exitstatus != 0) { + goto error; + } + + /* If we got here, then the grandchild was spawned, so we + * must exit. Block until the second child initializes + * successfully */ + again: + ret = read(statuspipe[0], &status, 1); + if (ret == -1 && errno == EINTR) + goto again;
I know it's pre-existing, but we have safread() which is there exactly because of EINTR.
+ + VIR_FORCE_CLOSE(statuspipe[0]); + + if (ret != 1) { + fprintf(stderr, + _("%s: error: unable to determine if daemon is " + "running: %s\n"), argv0, + g_strerror(errno)); + exit(EXIT_FAILURE); + } else if (status != 0) { + fprintf(stderr, + _("%s: error: %s. Check /var/log/messages or run without " + "--daemon for more info.\n"), argv0, + virDaemonErrTypeToString(status));
Since these strings should be translated (rightfully), the file must be added onto the POTFILES list.
+ exit(EXIT_FAILURE); + } + _exit(EXIT_SUCCESS); + } + } + +error:
Misaligned label ;-)
+ VIR_FORCE_CLOSE(statuspipe[0]); + VIR_FORCE_CLOSE(statuspipe[1]); + return -1; +} +
Michal

Signed-off-by: Rafael Fonseca <r4f4rfs@gmail.com> --- src/locking/lock_daemon.c | 251 +++++--------------------------------- 1 file changed, 29 insertions(+), 222 deletions(-) diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c index a258f7e6f1..3d33995beb 100644 --- a/src/locking/lock_daemon.c +++ b/src/locking/lock_daemon.c @@ -45,7 +45,7 @@ #include "viruuid.h" #include "virstring.h" #include "virgettext.h" -#include "virenum.h" +#include "virdaemon.h" #include "locking/lock_daemon_dispatch.h" #include "locking/lock_protocol.h" @@ -69,36 +69,6 @@ virLockDaemonPtr lockDaemon = NULL; static bool execRestart; -enum { - VIR_LOCK_DAEMON_ERR_NONE = 0, - VIR_LOCK_DAEMON_ERR_PIDFILE, - VIR_LOCK_DAEMON_ERR_RUNDIR, - VIR_LOCK_DAEMON_ERR_INIT, - VIR_LOCK_DAEMON_ERR_SIGNAL, - VIR_LOCK_DAEMON_ERR_PRIVS, - VIR_LOCK_DAEMON_ERR_NETWORK, - VIR_LOCK_DAEMON_ERR_CONFIG, - VIR_LOCK_DAEMON_ERR_HOOKS, - VIR_LOCK_DAEMON_ERR_REEXEC, - - VIR_LOCK_DAEMON_ERR_LAST -}; - -VIR_ENUM_DECL(virDaemonErr); -VIR_ENUM_IMPL(virDaemonErr, - VIR_LOCK_DAEMON_ERR_LAST, - "Initialization successful", - "Unable to obtain pidfile", - "Unable to create rundir", - "Unable to initialize libvirt", - "Unable to setup signal handlers", - "Unable to drop privileges", - "Unable to initialize network sockets", - "Unable to load configuration file", - "Unable to look for hook scripts", - "Unable to re-execute daemon", -); - static void * virLockDaemonClientNew(virNetServerClientPtr client, void *opaque); @@ -352,122 +322,6 @@ virLockSpacePtr virLockDaemonFindLockSpace(virLockDaemonPtr lockd, } -static int -virLockDaemonForkIntoBackground(const char *argv0) -{ - int statuspipe[2]; - if (virPipeQuiet(statuspipe) < 0) - return -1; - - pid_t pid = fork(); - switch (pid) { - case 0: - { - int stdinfd = -1; - int stdoutfd = -1; - int nextpid; - - VIR_FORCE_CLOSE(statuspipe[0]); - - if ((stdinfd = open("/dev/null", O_RDONLY)) < 0) - goto cleanup; - if ((stdoutfd = open("/dev/null", O_WRONLY)) < 0) - goto cleanup; - if (dup2(stdinfd, STDIN_FILENO) != STDIN_FILENO) - goto cleanup; - if (dup2(stdoutfd, STDOUT_FILENO) != STDOUT_FILENO) - goto cleanup; - if (dup2(stdoutfd, STDERR_FILENO) != STDERR_FILENO) - goto cleanup; - if (VIR_CLOSE(stdinfd) < 0) - goto cleanup; - if (VIR_CLOSE(stdoutfd) < 0) - goto cleanup; - - if (setsid() < 0) - goto cleanup; - - nextpid = fork(); - switch (nextpid) { - case 0: - return statuspipe[1]; - case -1: - return -1; - default: - _exit(0); - } - - cleanup: - VIR_FORCE_CLOSE(stdoutfd); - VIR_FORCE_CLOSE(stdinfd); - return -1; - - } - - case -1: - return -1; - - default: - { - int got, exitstatus = 0; - int ret; - char status; - - VIR_FORCE_CLOSE(statuspipe[1]); - - /* We wait to make sure the first child forked successfully */ - if ((got = waitpid(pid, &exitstatus, 0)) < 0 || - got != pid || - exitstatus != 0) { - return -1; - } - - /* Now block until the second child initializes successfully */ - again: - ret = read(statuspipe[0], &status, 1); - if (ret == -1 && errno == EINTR) - goto again; - - if (ret == 1 && status != 0) { - fprintf(stderr, - _("%s: error: %s. Check /var/log/messages or run without " - "--daemon for more info.\n"), argv0, - virDaemonErrTypeToString(status)); - } - _exit(ret == 1 && status == 0 ? 0 : 1); - } - } -} - - -static int -virLockDaemonUnixSocketPaths(bool privileged, - char **sockfile, - char **adminSockfile) -{ - if (privileged) { - *sockfile = g_strdup(RUNSTATEDIR "/libvirt/virtlockd-sock"); - *adminSockfile = g_strdup(RUNSTATEDIR "/libvirt/virtlockd-admin-sock"); - } else { - g_autofree char *rundir = NULL; - mode_t old_umask; - - rundir = virGetUserRuntimeDirectory(); - - old_umask = umask(077); - if (virFileMakePath(rundir) < 0) { - umask(old_umask); - return -1; - } - umask(old_umask); - - *sockfile = g_strdup_printf("%s/virtlockd-sock", rundir); - *adminSockfile = g_strdup_printf("%s/virtlockd-admin-sock", rundir); - } - return 0; -} - - static void virLockDaemonErrorHandler(void *opaque G_GNUC_UNUSED, virErrorPtr err G_GNUC_UNUSED) @@ -477,59 +331,6 @@ virLockDaemonErrorHandler(void *opaque G_GNUC_UNUSED, } -/* - * Set up the logging environment - * By default if daemonized all errors go to the logfile libvirtd.log, - * but if verbose or error debugging is asked for then also output - * informational and debug messages. Default size if 64 kB. - */ -static int -virLockDaemonSetupLogging(virLockDaemonConfigPtr config, - bool privileged, - bool verbose, - bool godaemon) -{ - virLogReset(); - - /* - * Libvirtd's order of precedence is: - * cmdline > environment > config - * - * Given the precedence, we must process the variables in the opposite - * order, each one overriding the previous. - */ - if (config->log_level != 0) - virLogSetDefaultPriority(config->log_level); - - /* In case the config is empty, both filters and outputs will become empty, - * however we can't start with empty outputs, thus we'll need to define and - * setup a default one. - */ - ignore_value(virLogSetFilters(config->log_filters)); - ignore_value(virLogSetOutputs(config->log_outputs)); - - /* If there are some environment variables defined, use those instead */ - virLogSetFromEnv(); - - /* - * Command line override for --verbose - */ - if ((verbose) && (virLogGetDefaultPriority() > VIR_LOG_INFO)) - virLogSetDefaultPriority(VIR_LOG_INFO); - - /* Define the default output. This is only applied if there was no setting - * from either the config or the environment. - */ - virLogSetDefaultOutput("virtlockd", godaemon, privileged); - - if (virLogGetNbOutputs() == 0) - virLogSetOutputs(virLogGetDefaultOutput()); - - return 0; -} - - - /* Display version information. */ static void virLockDaemonVersion(const char *argv0) @@ -1180,10 +981,13 @@ int main(int argc, char **argv) { } VIR_FREE(remote_config_file); - if (virLockDaemonSetupLogging(config, privileged, verbose, godaemon) < 0) { - VIR_ERROR(_("Can't initialize logging")); - exit(EXIT_FAILURE); - } + virDaemonSetupLogging("virtlockd", + config->log_level, + config->log_filters, + config->log_outputs, + privileged, + verbose, + godaemon); if (!pid_file && virPidFileConstructPath(privileged, @@ -1195,9 +999,12 @@ int main(int argc, char **argv) { } VIR_DEBUG("Decided on pid file path '%s'", NULLSTR(pid_file)); - if (virLockDaemonUnixSocketPaths(privileged, - &sock_file, - &admin_sock_file) < 0) { + if (virDaemonUnixSocketPaths("virtlockd", + privileged, + NULL, + &sock_file, + NULL, + &admin_sock_file) < 0) { VIR_ERROR(_("Can't determine socket paths")); exit(EXIT_FAILURE); } @@ -1227,7 +1034,7 @@ int main(int argc, char **argv) { if (virFileMakePath(run_dir) < 0) { VIR_ERROR(_("unable to create rundir %s: %s"), run_dir, g_strerror(errno)); - ret = VIR_LOCK_DAEMON_ERR_RUNDIR; + ret = VIR_DAEMON_ERR_RUNDIR; umask(old_umask); goto cleanup; } @@ -1237,7 +1044,7 @@ int main(int argc, char **argv) { pid_file, &pid_file_fd, privileged)) < 0) { - ret = VIR_LOCK_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } @@ -1258,7 +1065,7 @@ int main(int argc, char **argv) { goto cleanup; } - if ((statuswrite = virLockDaemonForkIntoBackground(argv[0])) < 0) { + if ((statuswrite = virDaemonForkIntoBackground(argv[0])) < 0) { VIR_ERROR(_("Failed to fork as daemon: %s"), g_strerror(errno)); goto cleanup; @@ -1267,19 +1074,19 @@ int main(int argc, char **argv) { /* If we have a pidfile set, claim it now, exiting if already taken */ if ((pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0) { - ret = VIR_LOCK_DAEMON_ERR_PIDFILE; + ret = VIR_DAEMON_ERR_PIDFILE; goto cleanup; } if (!(lockDaemon = virLockDaemonNew(config, privileged))) { - ret = VIR_LOCK_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } if (virSystemdGetActivation(actmap, G_N_ELEMENTS(actmap), &act) < 0) { - ret = VIR_LOCK_DAEMON_ERR_NETWORK; + ret = VIR_DAEMON_ERR_NETWORK; goto cleanup; } @@ -1291,7 +1098,7 @@ int main(int argc, char **argv) { sock_file, 0700, 0, 0, NULL, false, 0, 1) < 0) { - ret = VIR_LOCK_DAEMON_ERR_NETWORK; + ret = VIR_DAEMON_ERR_NETWORK; goto cleanup; } if (virNetServerAddServiceUNIX(adminSrv, @@ -1299,13 +1106,13 @@ int main(int argc, char **argv) { admin_sock_file, 0700, 0, 0, NULL, false, 0, 1) < 0) { - ret = VIR_LOCK_DAEMON_ERR_NETWORK; + ret = VIR_DAEMON_ERR_NETWORK; goto cleanup; } if (act && virSystemdActivationComplete(act) < 0) { - ret = VIR_LOCK_DAEMON_ERR_NETWORK; + ret = VIR_DAEMON_ERR_NETWORK; goto cleanup; } } else { @@ -1323,7 +1130,7 @@ int main(int argc, char **argv) { } if ((virLockDaemonSetupSignals(lockDaemon->dmn)) < 0) { - ret = VIR_LOCK_DAEMON_ERR_SIGNAL; + ret = VIR_DAEMON_ERR_SIGNAL; goto cleanup; } @@ -1331,12 +1138,12 @@ int main(int argc, char **argv) { VIR_LOCK_SPACE_PROTOCOL_PROGRAM_VERSION, virLockSpaceProtocolProcs, virLockSpaceProtocolNProcs))) { - ret = VIR_LOCK_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } if (virNetServerAddProgram(lockSrv, lockProgram) < 0) { - ret = VIR_LOCK_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } @@ -1345,11 +1152,11 @@ int main(int argc, char **argv) { ADMIN_PROTOCOL_VERSION, adminProcs, adminNProcs))) { - ret = VIR_LOCK_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } if (virNetServerAddProgram(adminSrv, adminProgram) < 0) { - ret = VIR_LOCK_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } } @@ -1379,7 +1186,7 @@ int main(int argc, char **argv) { virLockDaemonPreExecRestart(state_file, lockDaemon->dmn, argv) < 0) - ret = VIR_LOCK_DAEMON_ERR_REEXEC; + ret = VIR_DAEMON_ERR_REEXEC; else ret = 0; -- 2.25.1

Signed-off-by: Rafael Fonseca <r4f4rfs@gmail.com> --- src/logging/log_daemon.c | 239 +++++---------------------------------- 1 file changed, 29 insertions(+), 210 deletions(-) diff --git a/src/logging/log_daemon.c b/src/logging/log_daemon.c index 3319bf1f6f..dcafcda926 100644 --- a/src/logging/log_daemon.c +++ b/src/logging/log_daemon.c @@ -44,7 +44,7 @@ #include "viruuid.h" #include "virstring.h" #include "virgettext.h" -#include "virenum.h" +#include "virdaemon.h" #include "log_daemon_dispatch.h" #include "log_protocol.h" @@ -65,36 +65,6 @@ virLogDaemonPtr logDaemon = NULL; static bool execRestart; -enum { - VIR_LOG_DAEMON_ERR_NONE = 0, - VIR_LOG_DAEMON_ERR_PIDFILE, - VIR_LOG_DAEMON_ERR_RUNDIR, - VIR_LOG_DAEMON_ERR_INIT, - VIR_LOG_DAEMON_ERR_SIGNAL, - VIR_LOG_DAEMON_ERR_PRIVS, - VIR_LOG_DAEMON_ERR_NETWORK, - VIR_LOG_DAEMON_ERR_CONFIG, - VIR_LOG_DAEMON_ERR_HOOKS, - VIR_LOG_DAEMON_ERR_REEXEC, - - VIR_LOG_DAEMON_ERR_LAST -}; - -VIR_ENUM_DECL(virDaemonErr); -VIR_ENUM_IMPL(virDaemonErr, - VIR_LOG_DAEMON_ERR_LAST, - "Initialization successful", - "Unable to obtain pidfile", - "Unable to create rundir", - "Unable to initialize log daemon", - "Unable to setup signal handlers", - "Unable to drop privileges", - "Unable to initialize network sockets", - "Unable to load configuration file", - "Unable to look for hook scripts", - "Unable to re-execute daemon", -); - static void * virLogDaemonClientNew(virNetServerClientPtr client, void *opaque); @@ -294,122 +264,6 @@ virLogDaemonNewPostExecRestart(virJSONValuePtr object, bool privileged, } -static int -virLogDaemonForkIntoBackground(const char *argv0) -{ - int statuspipe[2]; - if (virPipeQuiet(statuspipe) < 0) - return -1; - - pid_t pid = fork(); - switch (pid) { - case 0: - { - int stdinfd = -1; - int stdoutfd = -1; - int nextpid; - - VIR_FORCE_CLOSE(statuspipe[0]); - - if ((stdinfd = open("/dev/null", O_RDONLY)) < 0) - goto cleanup; - if ((stdoutfd = open("/dev/null", O_WRONLY)) < 0) - goto cleanup; - if (dup2(stdinfd, STDIN_FILENO) != STDIN_FILENO) - goto cleanup; - if (dup2(stdoutfd, STDOUT_FILENO) != STDOUT_FILENO) - goto cleanup; - if (dup2(stdoutfd, STDERR_FILENO) != STDERR_FILENO) - goto cleanup; - if (VIR_CLOSE(stdinfd) < 0) - goto cleanup; - if (VIR_CLOSE(stdoutfd) < 0) - goto cleanup; - - if (setsid() < 0) - goto cleanup; - - nextpid = fork(); - switch (nextpid) { - case 0: - return statuspipe[1]; - case -1: - return -1; - default: - _exit(0); - } - - cleanup: - VIR_FORCE_CLOSE(stdoutfd); - VIR_FORCE_CLOSE(stdinfd); - return -1; - - } - - case -1: - return -1; - - default: - { - int got, exitstatus = 0; - int ret; - char status; - - VIR_FORCE_CLOSE(statuspipe[1]); - - /* We wait to make sure the first child forked successfully */ - if ((got = waitpid(pid, &exitstatus, 0)) < 0 || - got != pid || - exitstatus != 0) { - return -1; - } - - /* Now block until the second child initializes successfully */ - again: - ret = read(statuspipe[0], &status, 1); - if (ret == -1 && errno == EINTR) - goto again; - - if (ret == 1 && status != 0) { - fprintf(stderr, - _("%s: error: %s. Check /var/log/messages or run without " - "--daemon for more info.\n"), argv0, - virDaemonErrTypeToString(status)); - } - _exit(ret == 1 && status == 0 ? 0 : 1); - } - } -} - - -static int -virLogDaemonUnixSocketPaths(bool privileged, - char **sockfile, - char **adminSockfile) -{ - if (privileged) { - *sockfile = g_strdup(RUNSTATEDIR "/libvirt/virtlogd-sock"); - *adminSockfile = g_strdup(RUNSTATEDIR "/libvirt/virtlogd-admin-sock"); - } else { - g_autofree char *rundir = NULL; - mode_t old_umask; - - rundir = virGetUserRuntimeDirectory(); - - old_umask = umask(077); - if (virFileMakePath(rundir) < 0) { - umask(old_umask); - return -1; - } - umask(old_umask); - - *sockfile = g_strdup_printf("%s/virtlogd-sock", rundir); - *adminSockfile = g_strdup_printf("%s/virtlogd-admin-sock", rundir); - } - return 0; -} - - static void virLogDaemonErrorHandler(void *opaque G_GNUC_UNUSED, virErrorPtr err G_GNUC_UNUSED) @@ -419,50 +273,6 @@ virLogDaemonErrorHandler(void *opaque G_GNUC_UNUSED, } -static void -virLogDaemonSetupLogging(virLogDaemonConfigPtr config, - bool privileged, - bool verbose, - bool godaemon) -{ - virLogReset(); - - /* - * Libvirtd's order of precedence is: - * cmdline > environment > config - * - * Given the precedence, we must process the variables in the opposite - * order, each one overriding the previous. - */ - if (config->log_level != 0) - virLogSetDefaultPriority(config->log_level); - - /* In case the config is empty, both filters and outputs will become empty, - * however we can't start with empty outputs, thus we'll need to define and - * setup a default one. - */ - ignore_value(virLogSetFilters(config->log_filters)); - ignore_value(virLogSetOutputs(config->log_outputs)); - - /* If there are some environment variables defined, use those instead */ - virLogSetFromEnv(); - - /* - * Command line override for --verbose - */ - if ((verbose) && (virLogGetDefaultPriority() > VIR_LOG_INFO)) - virLogSetDefaultPriority(VIR_LOG_INFO); - - /* Define the default output. This is only applied if there was no setting - * from either the config or the environment. - */ - virLogSetDefaultOutput("virtlogd", godaemon, privileged); - - if (virLogGetNbOutputs() == 0) - virLogSetOutputs(virLogGetDefaultOutput()); -} - - /* Display version information. */ static void @@ -951,7 +761,13 @@ int main(int argc, char **argv) { exit(EXIT_FAILURE); } - virLogDaemonSetupLogging(config, privileged, verbose, godaemon); + virDaemonSetupLogging("virtlogd", + config->log_level, + config->log_filters, + config->log_outputs, + privileged, + verbose, + godaemon); if (!pid_file && virPidFileConstructPath(privileged, @@ -963,9 +779,12 @@ int main(int argc, char **argv) { } VIR_DEBUG("Decided on pid file path '%s'", NULLSTR(pid_file)); - if (virLogDaemonUnixSocketPaths(privileged, - &sock_file, - &admin_sock_file) < 0) { + if (virDaemonUnixSocketPaths("virtlogd", + privileged, + NULL, + &sock_file, + NULL, + &admin_sock_file) < 0) { VIR_ERROR(_("Can't determine socket paths")); exit(EXIT_FAILURE); } @@ -995,7 +814,7 @@ int main(int argc, char **argv) { if (virFileMakePath(run_dir) < 0) { VIR_ERROR(_("unable to create rundir %s: %s"), run_dir, g_strerror(errno)); - ret = VIR_LOG_DAEMON_ERR_RUNDIR; + ret = VIR_DAEMON_ERR_RUNDIR; umask(old_umask); goto cleanup; } @@ -1006,7 +825,7 @@ int main(int argc, char **argv) { &pid_file_fd, privileged, config)) < 0) { - ret = VIR_LOG_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } @@ -1028,7 +847,7 @@ int main(int argc, char **argv) { goto cleanup; } - if ((statuswrite = virLogDaemonForkIntoBackground(argv[0])) < 0) { + if ((statuswrite = virDaemonForkIntoBackground(argv[0])) < 0) { VIR_ERROR(_("Failed to fork as daemon: %s"), g_strerror(errno)); goto cleanup; @@ -1037,19 +856,19 @@ int main(int argc, char **argv) { /* If we have a pidfile set, claim it now, exiting if already taken */ if ((pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0) { - ret = VIR_LOG_DAEMON_ERR_PIDFILE; + ret = VIR_DAEMON_ERR_PIDFILE; goto cleanup; } if (!(logDaemon = virLogDaemonNew(config, privileged))) { - ret = VIR_LOG_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } if (virSystemdGetActivation(actmap, G_N_ELEMENTS(actmap), &act) < 0) { - ret = VIR_LOG_DAEMON_ERR_NETWORK; + ret = VIR_DAEMON_ERR_NETWORK; goto cleanup; } @@ -1061,7 +880,7 @@ int main(int argc, char **argv) { sock_file, 0700, 0, 0, NULL, false, 0, 1) < 0) { - ret = VIR_LOG_DAEMON_ERR_NETWORK; + ret = VIR_DAEMON_ERR_NETWORK; goto cleanup; } if (virNetServerAddServiceUNIX(adminSrv, @@ -1069,13 +888,13 @@ int main(int argc, char **argv) { admin_sock_file, 0700, 0, 0, NULL, false, 0, 1) < 0) { - ret = VIR_LOG_DAEMON_ERR_NETWORK; + ret = VIR_DAEMON_ERR_NETWORK; goto cleanup; } if (act && virSystemdActivationComplete(act) < 0) { - ret = VIR_LOG_DAEMON_ERR_NETWORK; + ret = VIR_DAEMON_ERR_NETWORK; goto cleanup; } } else { @@ -1093,7 +912,7 @@ int main(int argc, char **argv) { } if ((virLogDaemonSetupSignals(logDaemon->dmn)) < 0) { - ret = VIR_LOG_DAEMON_ERR_SIGNAL; + ret = VIR_DAEMON_ERR_SIGNAL; goto cleanup; } @@ -1101,11 +920,11 @@ int main(int argc, char **argv) { VIR_LOG_MANAGER_PROTOCOL_PROGRAM_VERSION, virLogManagerProtocolProcs, virLogManagerProtocolNProcs))) { - ret = VIR_LOG_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } if (virNetServerAddProgram(logSrv, logProgram) < 0) { - ret = VIR_LOG_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } @@ -1114,11 +933,11 @@ int main(int argc, char **argv) { ADMIN_PROTOCOL_VERSION, adminProcs, adminNProcs))) { - ret = VIR_LOG_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } if (virNetServerAddProgram(adminSrv, adminProgram) < 0) { - ret = VIR_LOG_DAEMON_ERR_INIT; + ret = VIR_DAEMON_ERR_INIT; goto cleanup; } } @@ -1147,7 +966,7 @@ int main(int argc, char **argv) { virLogDaemonPreExecRestart(state_file, logDaemon->dmn, argv) < 0) - ret = VIR_LOG_DAEMON_ERR_REEXEC; + ret = VIR_DAEMON_ERR_REEXEC; else ret = 0; -- 2.25.1

Signed-off-by: Rafael Fonseca <r4f4rfs@gmail.com> --- src/remote/remote_daemon.c | 263 +++---------------------------------- 1 file changed, 15 insertions(+), 248 deletions(-) diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index f3b3c70ebf..a1552800e9 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -57,6 +57,7 @@ #include "util/virnetdevopenvswitch.h" #include "virsystemd.h" #include "virhostuptime.h" +#include "virdaemon.h" #include "driver.h" @@ -78,192 +79,6 @@ virNetServerProgramPtr qemuProgram = NULL; volatile bool driversInitialized = false; -enum { - VIR_DAEMON_ERR_NONE = 0, - VIR_DAEMON_ERR_PIDFILE, - VIR_DAEMON_ERR_RUNDIR, - VIR_DAEMON_ERR_INIT, - VIR_DAEMON_ERR_SIGNAL, - VIR_DAEMON_ERR_PRIVS, - VIR_DAEMON_ERR_NETWORK, - VIR_DAEMON_ERR_CONFIG, - VIR_DAEMON_ERR_HOOKS, - VIR_DAEMON_ERR_AUDIT, - VIR_DAEMON_ERR_DRIVER, - - VIR_DAEMON_ERR_LAST -}; - -VIR_ENUM_DECL(virDaemonErr); -VIR_ENUM_IMPL(virDaemonErr, - VIR_DAEMON_ERR_LAST, - "Initialization successful", - "Unable to obtain pidfile", - "Unable to create rundir", - "Unable to initialize libvirt", - "Unable to setup signal handlers", - "Unable to drop privileges", - "Unable to initialize network sockets", - "Unable to load configuration file", - "Unable to look for hook scripts", - "Unable to initialize audit system", - "Unable to initialize driver", -); - -static int daemonForkIntoBackground(const char *argv0) -{ - int statuspipe[2]; - if (virPipeQuiet(statuspipe) < 0) - return -1; - - pid_t pid = fork(); - switch (pid) { - case 0: - { - /* intermediate child */ - int stdinfd = -1; - int stdoutfd = -1; - int nextpid; - - VIR_FORCE_CLOSE(statuspipe[0]); - - if ((stdinfd = open("/dev/null", O_RDONLY)) <= STDERR_FILENO) - goto cleanup; - if ((stdoutfd = open("/dev/null", O_WRONLY)) <= STDERR_FILENO) - goto cleanup; - if (dup2(stdinfd, STDIN_FILENO) != STDIN_FILENO) - goto cleanup; - if (dup2(stdoutfd, STDOUT_FILENO) != STDOUT_FILENO) - goto cleanup; - if (dup2(stdoutfd, STDERR_FILENO) != STDERR_FILENO) - goto cleanup; - if (VIR_CLOSE(stdinfd) < 0) - goto cleanup; - if (VIR_CLOSE(stdoutfd) < 0) - goto cleanup; - - if (setsid() < 0) - goto cleanup; - - nextpid = fork(); - switch (nextpid) { - case 0: /* grandchild */ - return statuspipe[1]; - case -1: /* error */ - goto cleanup; - default: /* intermediate child succeeded */ - _exit(EXIT_SUCCESS); - } - - cleanup: - VIR_FORCE_CLOSE(stdoutfd); - VIR_FORCE_CLOSE(stdinfd); - VIR_FORCE_CLOSE(statuspipe[1]); - _exit(EXIT_FAILURE); - - } - - case -1: /* error in parent */ - goto error; - - default: - { - /* parent */ - int ret; - char status; - - VIR_FORCE_CLOSE(statuspipe[1]); - - /* We wait to make sure the first child forked successfully */ - if (virProcessWait(pid, NULL, false) < 0) - goto error; - - /* If we get here, then the grandchild was spawned, so we - * must exit. Block until the second child initializes - * successfully */ - again: - ret = read(statuspipe[0], &status, 1); - if (ret == -1 && errno == EINTR) - goto again; - - VIR_FORCE_CLOSE(statuspipe[0]); - - if (ret != 1) { - fprintf(stderr, - _("%s: error: unable to determine if daemon is " - "running: %s\n"), argv0, - g_strerror(errno)); - exit(EXIT_FAILURE); - } else if (status != 0) { - fprintf(stderr, - _("%s: error: %s. Check /var/log/messages or run " - "without --daemon for more info.\n"), argv0, - virDaemonErrTypeToString(status)); - exit(EXIT_FAILURE); - } - _exit(EXIT_SUCCESS); - } - } - - error: - VIR_FORCE_CLOSE(statuspipe[0]); - VIR_FORCE_CLOSE(statuspipe[1]); - return -1; -} - - -static int -daemonUnixSocketPaths(struct daemonConfig *config, - bool privileged, - char **sockfile, - char **rosockfile, - char **admsockfile) -{ - int ret = -1; - char *rundir = NULL; - - if (config->unix_sock_dir) { - *sockfile = g_strdup_printf("%s/%s-sock", config->unix_sock_dir, - SOCK_PREFIX); - - if (privileged) { - *rosockfile = g_strdup_printf("%s/%s-sock-ro", - config->unix_sock_dir, SOCK_PREFIX); - *admsockfile = g_strdup_printf("%s/%s-admin-sock", - config->unix_sock_dir, SOCK_PREFIX); - } - } else { - if (privileged) { - *sockfile = g_strdup_printf("%s/libvirt/%s-sock", - RUNSTATEDIR, SOCK_PREFIX); - *rosockfile = g_strdup_printf("%s/libvirt/%s-sock-ro", - RUNSTATEDIR, SOCK_PREFIX); - *admsockfile = g_strdup_printf("%s/libvirt/%s-admin-sock", - RUNSTATEDIR, SOCK_PREFIX); - } else { - mode_t old_umask; - - rundir = virGetUserRuntimeDirectory(); - - old_umask = umask(077); - if (virFileMakePath(rundir) < 0) { - umask(old_umask); - goto cleanup; - } - umask(old_umask); - - *sockfile = g_strdup_printf("%s/%s-sock", rundir, SOCK_PREFIX); - *admsockfile = g_strdup_printf("%s/%s-admin-sock", rundir, SOCK_PREFIX); - } - } - - ret = 0; - cleanup: - VIR_FREE(rundir); - return ret; -} - - static void daemonErrorHandler(void *opaque G_GNUC_UNUSED, virErrorPtr err G_GNUC_UNUSED) { @@ -604,58 +419,6 @@ daemonSetupNetDevOpenvswitch(struct daemonConfig *config) } -/* - * Set up the logging environment - * 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. - */ -static int -daemonSetupLogging(struct daemonConfig *config, - bool privileged, - bool verbose, - bool godaemon) -{ - virLogReset(); - - /* - * Logging setup order of precedence is: - * cmdline > environment > config - * - * Given the precedence, we must process the variables in the opposite - * order, each one overriding the previous. - */ - if (config->log_level != 0) - virLogSetDefaultPriority(config->log_level); - - /* In case the config is empty, both filters and outputs will become empty, - * however we can't start with empty outputs, thus we'll need to define and - * setup a default one. - */ - ignore_value(virLogSetFilters(config->log_filters)); - ignore_value(virLogSetOutputs(config->log_outputs)); - - /* If there are some environment variables defined, use those instead */ - virLogSetFromEnv(); - - /* - * Command line override for --verbose - */ - if ((verbose) && (virLogGetDefaultPriority() > VIR_LOG_INFO)) - virLogSetDefaultPriority(VIR_LOG_INFO); - - /* Define the default output. This is only applied if there was no setting - * from either the config or the environment. - */ - virLogSetDefaultOutput(DAEMON_NAME, godaemon, privileged); - - if (virLogGetNbOutputs() == 0) - virLogSetOutputs(virLogGetDefaultOutput()); - - return 0; -} - - static int daemonSetupAccessManager(struct daemonConfig *config) { @@ -1148,10 +911,13 @@ int main(int argc, char **argv) { exit(EXIT_FAILURE); } - if (daemonSetupLogging(config, privileged, verbose, godaemon) < 0) { - VIR_ERROR(_("Can't initialize logging")); - exit(EXIT_FAILURE); - } + virDaemonSetupLogging(DAEMON_NAME, + config->log_level, + config->log_filters, + config->log_outputs, + privileged, + verbose, + godaemon); /* Let's try to initialize global variable that holds the host's boot time. */ if (virHostBootTimeInit() < 0) { @@ -1178,11 +944,12 @@ int main(int argc, char **argv) { } VIR_DEBUG("Decided on pid file path '%s'", NULLSTR(pid_file)); - if (daemonUnixSocketPaths(config, - privileged, - &sock_file, - &sock_file_ro, - &sock_file_adm) < 0) { + if (virDaemonUnixSocketPaths(SOCK_PREFIX, + privileged, + config->unix_sock_dir, + &sock_file, + &sock_file_ro, + &sock_file_adm) < 0) { VIR_ERROR(_("Can't determine socket paths")); exit(EXIT_FAILURE); } @@ -1198,7 +965,7 @@ int main(int argc, char **argv) { goto cleanup; } - if ((statuswrite = daemonForkIntoBackground(argv[0])) < 0) { + if ((statuswrite = virDaemonForkIntoBackground(argv[0])) < 0) { VIR_ERROR(_("Failed to fork as daemon: %s"), g_strerror(errno)); goto cleanup; -- 2.25.1

On 26. 3. 2020 16:17, Rafael Fonseca wrote:
Libvirt ships several daemons (libvirtd, virtlogd, virtlockd) that all have similar code around general daemon startup. Right now the code is duplicated for each daemon, but it could be shared, like in a new file src/util/virdaemon.c.
Rafael Fonseca (4): util: introduce shared daemon startup code locking: use shared daemon startup code logging: use shared daemon startup code remote: use shared daemon startup code
src/libvirt_private.syms | 6 + src/locking/lock_daemon.c | 251 ++++------------------------------- src/logging/log_daemon.c | 239 ++++----------------------------- src/remote/remote_daemon.c | 263 +++---------------------------------- src/util/Makefile.inc.am | 2 + src/util/virdaemon.c | 255 +++++++++++++++++++++++++++++++++++ src/util/virdaemon.h | 74 +++++++++++ 7 files changed, 410 insertions(+), 680 deletions(-) create mode 100644 src/util/virdaemon.c create mode 100644 src/util/virdaemon.h
I'm fixing all the small nits I've rasied and pushing. Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Michal
participants (2)
-
Michal Prívozník
-
Rafael Fonseca