[libvirt] [PATCH 05/14] Introduce basic infrastructure for virtlockd daemon
Michal Privoznik
mprivozn at redhat.com
Wed Dec 12 18:14:20 UTC 2012
On 11.12.2012 21:41, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
>
> The virtlockd daemon will maintain locks on behalf of libvirtd.
> There are two reasons for it to be separate
>
> - Avoid risk of other libvirtd threads accidentally
> releasing fcntl() locks by opening + closing a file
> that is locked
> - Ensure locks can be preserved across libvirtd restarts.
> virtlockd will need to be able to re-exec itself while
> maintaining locks. This is simpler to achieve if its
> sole job is maintaining locks
>
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
> .gitignore | 2 +
> cfg.mk | 6 +-
> libvirt.spec.in | 7 +
> po/POTFILES.in | 2 +
> src/Makefile.am | 89 +++-
> src/locking/lock_daemon.c | 850 +++++++++++++++++++++++++++++++++++++++
> src/locking/lock_daemon.h | 43 ++
> src/locking/lock_daemon_config.c | 193 +++++++++
> src/locking/lock_daemon_config.h | 50 +++
> src/locking/virtlockd.init.in | 93 +++++
> src/locking/virtlockd.sysconf | 3 +
> 11 files changed, 1334 insertions(+), 4 deletions(-)
> create mode 100644 src/locking/lock_daemon.c
> create mode 100644 src/locking/lock_daemon.h
> create mode 100644 src/locking/lock_daemon_config.c
> create mode 100644 src/locking/lock_daemon_config.h
> create mode 100644 src/locking/virtlockd.init.in
> create mode 100644 src/locking/virtlockd.sysconf
>
> diff --git a/.gitignore b/.gitignore
> index 0dadd21..1e3a624 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -123,6 +123,8 @@
> /src/test_libvirt*.aug
> /src/util/virkeymaps.h
> /src/virt-aa-helper
> +/src/virtlockd
> +/src/virtlockd.init
> /tests/*.log
> /tests/*.pid
> /tests/*xml2*test
> diff --git a/cfg.mk b/cfg.mk
> index f218eb6..95a1d3a 100644
> --- a/cfg.mk
> +++ b/cfg.mk
> @@ -655,6 +655,8 @@ sc_prohibit_cross_inclusion:
> @for dir in $(cross_dirs); do \
> case $$dir in \
> util/) safe="util";; \
> + locking/) \
> + safe="($$dir|util|conf|rpc)";; \
> cpu/ | locking/ | network/ | rpc/ | security/) \
> safe="($$dir|util|conf)";; \
> xenapi/ | xenxs/ ) safe="($$dir|util|conf|xen)";; \
> @@ -743,7 +745,7 @@ $(srcdir)/src/remote/remote_client_bodies.h: $(srcdir)/src/remote/remote_protoco
> # List all syntax-check exemptions:
> exclude_file_name_regexp--sc_avoid_strcase = ^tools/virsh\.h$$
>
> -_src1=libvirt|fdstream|qemu/qemu_monitor|util/(command|util)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller
> +_src1=libvirt|fdstream|qemu/qemu_monitor|util/(command|util)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller|locking/lock_daemon
> exclude_file_name_regexp--sc_avoid_write = \
> ^(src/($(_src1))|daemon/libvirtd|tools/console|tests/(shunload|virnettlscontext)test)\.c$$
>
> @@ -776,7 +778,7 @@ exclude_file_name_regexp--sc_prohibit_close = \
> exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
> (^tests/(qemuhelp|nodeinfo)data/|\.(gif|ico|png|diff)$$)
>
> -_src2=src/(util/command|libvirt|lxc/lxc_controller)
> +_src2=src/(util/command|libvirt|lxc/lxc_controller|locking/lock_daemon)
> exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
> (^($(_src2)|tests/testutils|daemon/libvirtd)\.c$$)
>
> diff --git a/libvirt.spec.in b/libvirt.spec.in
> index d6e1fbe..e12fca4 100644
> --- a/libvirt.spec.in
> +++ b/libvirt.spec.in
> @@ -1661,9 +1661,11 @@ fi
> %{_unitdir}/libvirtd.service
> %else
> %{_sysconfdir}/rc.d/init.d/libvirtd
> +%{_sysconfdir}/rc.d/init.d/virtlockd
> %endif
> %doc daemon/libvirtd.upstart
> %config(noreplace) %{_sysconfdir}/sysconfig/libvirtd
> +%config(noreplace) %{_sysconfdir}/sysconfig/virtlockd
> %config(noreplace) %{_sysconfdir}/libvirt/libvirtd.conf
> %if 0%{?fedora} >= 14 || 0%{?rhel} >= 6
> %config(noreplace) %{_sysconfdir}/sysctl.d/libvirtd
> @@ -1730,6 +1732,10 @@ rm -f $RPM_BUILD_ROOT%{_sysconfdir}/sysctl.d/libvirtd
> %dir %attr(0755, root, root) %{_localstatedir}/lib/libvirt/dnsmasq/
> %endif
>
> +%if %{with_libvirtd}
> +%dir %attr(0755, root, root) %{_libdir}/libvirt/lock-driver
> +%endif
> +
> %if %{with_qemu}
> %{_datadir}/augeas/lenses/libvirtd_qemu.aug
> %{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
> @@ -1763,6 +1769,7 @@ rm -f $RPM_BUILD_ROOT%{_sysconfdir}/sysctl.d/libvirtd
>
> %attr(0755, root, root) %{_libexecdir}/libvirt_iohelper
> %attr(0755, root, root) %{_sbindir}/libvirtd
> +%attr(0755, root, root) %{_sbindir}/virtlockd
>
> %{_mandir}/man8/libvirtd.8*
>
> diff --git a/po/POTFILES.in b/po/POTFILES.in
> index 51a1f5c..34c688c 100644
> --- a/po/POTFILES.in
> +++ b/po/POTFILES.in
> @@ -48,6 +48,8 @@ src/interface/interface_backend_udev.c
> src/internal.h
> src/libvirt.c
> src/libvirt-qemu.c
> +src/locking/lock_daemon.c
> +src/locking/lock_daemon_config.c
> src/locking/lock_driver_sanlock.c
> src/locking/lock_manager.c
> src/locking/sanlock_helper.c
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 6d2816d..6a66efd 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -148,6 +148,13 @@ LOCK_DRIVER_SANLOCK_SOURCES = \
> LOCK_DRIVER_SANLOCK_HELPER_SOURCES = \
> locking/sanlock_helper.c
>
> +LOCK_DAEMON_SOURCES = \
> + locking/lock_daemon.h \
> + locking/lock_daemon.c \
> + locking/lock_daemon_config.h \
> + locking/lock_daemon_config.c \
> + $(NULL)
> +
> NETDEV_CONF_SOURCES = \
> conf/netdev_bandwidth_conf.h conf/netdev_bandwidth_conf.c \
> conf/netdev_vport_profile_conf.h conf/netdev_vport_profile_conf.c \
> @@ -1508,6 +1515,76 @@ libvirt_qemu_la_CFLAGS = $(AM_CFLAGS)
> libvirt_qemu_la_LIBADD = libvirt.la $(CYGWIN_EXTRA_LIBADD)
> EXTRA_DIST += $(LIBVIRT_QEMU_SYMBOL_FILE)
>
> +if WITH_LIBVIRTD
> +sbin_PROGRAMS = virtlockd
> +
> +virtlockd_SOURCES = $(LOCK_DAEMON_SOURCES)
> +virtlockd_CFLAGS = \
> + $(AM_CFLAGS) \
> + $(NULL)
> +virtlockd_LDFLAGS = \
> + $(AM_LDFLAGS) \
> + $(CYGWIN_EXTRA_LDFLAGS) \
> + $(MINGW_EXTRA_LDFLAGS) \
> + $(NULL)
> +virtlockd_LDADD = \
> + libvirt-net-rpc-server.la \
> + libvirt-net-rpc.la \
> + libvirt_util.la \
> + ../gnulib/lib/libgnu.la \
> + $(CYGWIN_EXTRA_LIBADD) \
> + $(NULL)
> +if WITH_DTRACE_PROBES
> +virtlockd_LDADD += libvirt_probes.lo
> +endif
> +
> +else
> +EXTRA_DIST += $(LOCK_DAEMON_SOURCES)
> +endif
> +
> +EXTRA_DIST += locking/virtlockd.sysconf
> +
> +install-sysconfig:
> + mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig
> + $(INSTALL_DATA) $(srcdir)/locking/virtlockd.sysconf \
> + $(DESTDIR)$(sysconfdir)/sysconfig/virtlockd
> +
> +uninstall-sysconfig:
> + rm -f $(DESTDIR)$(sysconfdir)/sysconfig/virtlockd
> +
> +EXTRA_DIST += locking/virtlockd.init.in
> +
> +if WITH_LIBVIRTD
> +if LIBVIRT_INIT_SCRIPT_RED_HAT
> +install-init:: virtlockd.init install-sysconfig
> + mkdir -p $(DESTDIR)$(sysconfdir)/rc.d/init.d
> + $(INSTALL_SCRIPT) virtlockd.init \
> + $(DESTDIR)$(sysconfdir)/rc.d/init.d/virtlockd
> +
> +uninstall-init:: uninstall-sysconfig
> + rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
> +
> +BUILT_SOURCES += virtlockd.init
> +else
> +install-init::
> +uninstall-init::
> +endif
> +else
> +install-init::
> +uninstall-init::
> +endif
> +
> +virtlockd.init: locking/virtlockd.init.in $(top_builddir)/config.status
> + $(AM_V_GEN)sed \
> + -e "s!::localstatedir::!$(localstatedir)!g" \
> + -e "s!::sbindir::!$(sbindir)!g" \
> + -e "s!::sysconfdir::!$(sysconfdir)!g" \
> + < $< > $@-t && \
> + chmod a+x $@-t && \
> + mv $@-t $@
> +
> +
> +
> if HAVE_SANLOCK
> lockdriverdir = $(libdir)/libvirt/lock-driver
> lockdriver_LTLIBRARIES = sanlock.la
> @@ -1745,7 +1822,11 @@ endif
> endif
> EXTRA_DIST += $(SECURITY_DRIVER_APPARMOR_HELPER_SOURCES)
>
> -install-data-local:
> +install-data-local: install-init
> +if WITH_LIBVIRTD
> + $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/lockd"
> + $(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/lockd"
> +endif
> $(MKDIR_P) "$(DESTDIR)$(localstatedir)/cache/libvirt"
> $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/images"
> $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/filesystems"
> @@ -1794,7 +1875,11 @@ if WITH_NETWORK
> $(DESTDIR)$(sysconfdir)/libvirt/qemu/networks/autostart/default.xml
> endif
>
> -uninstall-local::
> +uninstall-local:: uninstall-init
> +if WITH_LIBVIRTD
> + rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/lockd" ||:
> + rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/lockd" ||:
> +endif
> rmdir "$(DESTDIR)$(localstatedir)/cache/libvirt" ||:
> rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/images" ||:
> rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/filesystems" ||:
> diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c
> new file mode 100644
> index 0000000..f821d2e
> --- /dev/null
> +++ b/src/locking/lock_daemon.c
> @@ -0,0 +1,850 @@
> +/*
> + * lock_daemon.c: lock management daemon
> + *
> + * Copyright (C) 2006-2012 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/>.
> + *
> + * Author: Daniel P. Berrange <berrange at redhat.com>
> + */
> +
> +#include <config.h>
> +
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/wait.h>
> +#include <sys/stat.h>
> +#include <getopt.h>
> +#include <stdlib.h>
> +#include <locale.h>
> +
> +
> +#include "lock_daemon.h"
> +#include "lock_daemon_config.h"
> +#include "util.h"
> +#include "virfile.h"
> +#include "virpidfile.h"
> +#include "virterror_internal.h"
> +#include "logging.h"
> +#include "memory.h"
> +#include "conf.h"
> +#include "rpc/virnetserver.h"
> +#include "virrandom.h"
> +#include "virhash.h"
You may want to sort these so we don't introduce yet another file which
needs sorting - assuming we will stick to your idea of sorting header
files include after the release.
> +
> +#include "configmake.h"
> +
> +#define VIR_FROM_THIS VIR_FROM_LOCKING
> +
> +struct _virLockDaemon {
> + virMutex lock;
> + virNetServerPtr srv;
> +};
> +
> +virLockDaemonPtr lockDaemon = NULL;
> +
> +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_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");
> +
> +static void *
> +virLockDaemonClientNew(virNetServerClientPtr client,
> + void *opaque);
> +static void
> +virLockDaemonClientFree(void *opaque);
> +
> +static void
> +virLockDaemonFree(virLockDaemonPtr lockd)
> +{
> + if (!lockd)
> + return;
> +
> + virObjectUnref(lockd->srv);
> +
> + VIR_FREE(lockd);
> +}
> +
> +
> +static virLockDaemonPtr
> +virLockDaemonNew(bool privileged)
> +{
> + virLockDaemonPtr lockd;
> +
> + if (VIR_ALLOC(lockd) < 0) {
> + virReportOOMError();
> + return NULL;
> + }
> +
> + if (virMutexInit(&lockd->lock) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Unable to initialize mutex"));
> + VIR_FREE(lockd);
> + return NULL;
> + }
> +
> + if (!(lockd->srv = virNetServerNew(1, 1, 0, 20,
> + -1, 0,
> + false, NULL,
> + virLockDaemonClientNew,
> + NULL,
> + virLockDaemonClientFree,
> + (void*)(intptr_t)(privileged ? 0x1 : 0x0))))
> + goto error;
> +
> + return lockd;
> +
> +error:
> + virLockDaemonFree(lockd);
> + return NULL;
> +}
> +
> +
> +static int
> +virLockDaemonForkIntoBackground(const char *argv0)
> +{
> + int statuspipe[2];
> + if (pipe(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);
> + }
> + }
> +}
This is basically a copy-paste of daemonForkIntoBackground(). I wonder
if we can use (modified) version of it instead of this.
> +
> +
> +static int
> +virLockDaemonPidFilePath(bool privileged,
> + char **pidfile)
> +{
> + if (privileged) {
> + if (!(*pidfile = strdup(LOCALSTATEDIR "/run/virtlockd.pid")))
> + goto no_memory;
> + } else {
> + char *rundir = NULL;
> + mode_t old_umask;
> +
> + if (!(rundir = virGetUserRuntimeDirectory()))
> + goto error;
> +
> + old_umask = umask(077);
> + if (virFileMakePath(rundir) < 0) {
> + umask(old_umask);
> + goto error;
> + }
> + umask(old_umask);
> +
> + if (virAsprintf(pidfile, "%s/virtlockd.pid", rundir) < 0) {
> + VIR_FREE(rundir);
> + goto no_memory;
> + }
> +
> + VIR_FREE(rundir);
> + }
> +
> + return 0;
> +
> +no_memory:
> + virReportOOMError();
> +error:
> + return -1;
> +}
> +
> +
> +static int
> +virLockDaemonUnixSocketPaths(bool privileged,
> + char **sockfile)
> +{
> + if (privileged) {
> + if (!(*sockfile = strdup(LOCALSTATEDIR "/run/libvirt/virtlockd-sock")))
> + goto no_memory;
> + } else {
> + char *rundir = NULL;
> + mode_t old_umask;
> +
> + if (!(rundir = virGetUserRuntimeDirectory()))
> + goto error;
> +
> + old_umask = umask(077);
> + if (virFileMakePath(rundir) < 0) {
> + umask(old_umask);
> + goto error;
> + }
> + umask(old_umask);
> +
> + if (virAsprintf(sockfile, "%s/virtlockd-sock", rundir) < 0) {
> + VIR_FREE(rundir);
> + goto no_memory;
> + }
> +
> + VIR_FREE(rundir);
> + }
> + return 0;
> +
> +no_memory:
> + virReportOOMError();
> +error:
> + return -1;
> +}
> +
> +
> +static void
> +virLockDaemonErrorHandler(void *opaque ATTRIBUTE_UNUSED,
> + virErrorPtr err ATTRIBUTE_UNUSED)
> +{
> + /* Don't do anything, since logging infrastructure already
> + * took care of reporting the error */
> +}
> +
> +
> +/*
> + * 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
> + *
> + * In order to achieve this, we must process configuration in
> + * different order for the log level versus the filters and
> + * outputs. Because filters and outputs append, we have to look at
> + * the environment first and then only check the config file if
> + * there was no result from the environment. The default output is
> + * then applied only if there was no setting from either of the
> + * first two. Because we don't have a way to determine if the log
> + * level has been set, we must process variables in the opposite
> + * order, each one overriding the previous.
> + */
> + if (config->log_level != 0)
> + virLogSetDefaultPriority(config->log_level);
> +
> + virLogSetFromEnv();
> +
> + virLogSetBufferSize(config->log_buffer_size);
> +
> + if (virLogGetNbFilters() == 0)
> + virLogParseFilters(config->log_filters);
> +
> + if (virLogGetNbOutputs() == 0)
> + virLogParseOutputs(config->log_outputs);
> +
> + /*
> + * If no defined outputs, and either running
> + * as daemon or not on a tty, then first try
> + * to direct it to the systemd journal
> + * (if it exists)....
> + */
> + if (virLogGetNbOutputs() == 0 &&
> + (godaemon || !isatty(STDIN_FILENO))) {
> + char *tmp;
> + if (access("/run/systemd/journal/socket", W_OK) >= 0) {
> + if (virAsprintf(&tmp, "%d:journald", virLogGetDefaultPriority()) < 0)
> + goto no_memory;
> + virLogParseOutputs(tmp);
> + VIR_FREE(tmp);
> + }
> + }
> +
> + /*
> + * otherwise direct to libvirtd.log when running
> + * as daemon. Otherwise the default output is stderr.
> + */
> + if (virLogGetNbOutputs() == 0) {
> + char *tmp = NULL;
> +
> + if (godaemon) {
> + if (privileged) {
> + if (virAsprintf(&tmp, "%d:file:%s/log/libvirt/virtlockd.log",
> + virLogGetDefaultPriority(),
> + LOCALSTATEDIR) == -1)
> + goto no_memory;
> + } else {
> + char *logdir = virGetUserCacheDirectory();
> + mode_t old_umask;
> +
> + if (!logdir)
> + goto error;
> +
> + old_umask = umask(077);
> + if (virFileMakePath(logdir) < 0) {
> + umask(old_umask);
> + goto error;
> + }
> + umask(old_umask);
> +
> + if (virAsprintf(&tmp, "%d:file:%s/virtlockd.log",
> + virLogGetDefaultPriority(), logdir) == -1) {
> + VIR_FREE(logdir);
> + goto no_memory;
> + }
> + VIR_FREE(logdir);
> + }
> + } else {
> + if (virAsprintf(&tmp, "%d:stderr", virLogGetDefaultPriority()) < 0)
> + goto no_memory;
> + }
> + virLogParseOutputs(tmp);
> + VIR_FREE(tmp);
> + }
> +
> + /*
> + * Command line override for --verbose
> + */
> + if ((verbose) && (virLogGetDefaultPriority() > VIR_LOG_INFO))
> + virLogSetDefaultPriority(VIR_LOG_INFO);
> +
> + return 0;
> +
> +no_memory:
> + virReportOOMError();
> +error:
> + return -1;
> +}
Same here. This one is even closer to daemonSetupLogging()
> +
> +
> +
> +/* Display version information. */
> +static void
> +virLockDaemonVersion(const char *argv0)
> +{
> + printf("%s (%s) %s\n", argv0, PACKAGE_NAME, PACKAGE_VERSION);
> +}
> +
> +static void
> +virLockDaemonShutdownHandler(virNetServerPtr srv,
> + siginfo_t *sig ATTRIBUTE_UNUSED,
> + void *opaque ATTRIBUTE_UNUSED)
> +{
> + virNetServerQuit(srv);
> +}
> +
> +static int
> +virLockDaemonSetupSignals(virNetServerPtr srv)
> +{
> + if (virNetServerAddSignalHandler(srv, SIGINT, virLockDaemonShutdownHandler, NULL) < 0)
> + return -1;
> + if (virNetServerAddSignalHandler(srv, SIGQUIT, virLockDaemonShutdownHandler, NULL) < 0)
> + return -1;
> + if (virNetServerAddSignalHandler(srv, SIGTERM, virLockDaemonShutdownHandler, NULL) < 0)
> + return -1;
> + return 0;
> +}
> +
> +static int
> +virLockDaemonSetupNetworking(virNetServerPtr srv, const char *sock_path)
> +{
> + virNetServerServicePtr svc;
> +
> + VIR_DEBUG("Setting up networking natively");
> +
> + if (!(svc = virNetServerServiceNewUNIX(sock_path, 0700, 0, 0, false, 1, NULL)))
> + return -1;
> +
> + if (virNetServerAddService(srv, svc, NULL) < 0) {
> + virObjectUnref(svc);
> + return -1;
> + }
> + return 0;
> +}
> +
> +
> +static void
> +virLockDaemonClientFree(void *opaque)
> +{
> + virLockDaemonClientPtr priv = opaque;
> +
> + if (!priv)
> + return;
> +
> + VIR_DEBUG("priv=%p client=%lld",
> + priv,
> + (unsigned long long)priv->clientPid);
> +
> + virMutexDestroy(&priv->lock);
> + VIR_FREE(priv);
> +}
> +
> +
> +static void *
> +virLockDaemonClientNew(virNetServerClientPtr client,
> + void *opaque)
> +{
> + virLockDaemonClientPtr priv;
> + uid_t clientuid;
> + gid_t clientgid;
> + bool privileged = opaque != NULL;
> +
> + if (VIR_ALLOC(priv) < 0) {
> + virReportOOMError();
> + return NULL;
> + }
> +
> + if (virMutexInit(&priv->lock) < 0) {
> + VIR_FREE(priv);
> + virReportOOMError();
> + return NULL;
> + }
> +
> + if (virNetServerClientGetUNIXIdentity(client,
> + &clientuid,
> + &clientgid,
> + &priv->clientPid) < 0)
> + goto error;
> +
> + VIR_DEBUG("New client pid %llu uid %llu",
> + (unsigned long long)priv->clientPid,
> + (unsigned long long)clientuid);
> +
> + if (!privileged) {
> + if (geteuid() != clientuid) {
> + virReportError(VIR_ERR_OPERATION_DENIED,
> + _("Disallowing client %llu with uid %llu"),
> + (unsigned long long)priv->clientPid,
> + (unsigned long long)clientuid);
> + goto error;
> + }
> + } else {
> + if (clientuid != 0) {
> + virReportError(VIR_ERR_OPERATION_DENIED,
> + _("Disallowing client %llu with uid %llu"),
> + (unsigned long long)priv->clientPid,
> + (unsigned long long)clientuid);
> + goto error;
> + }
> + }
> +
> + return priv;
> +
> +error:
> + virMutexDestroy(&priv->lock);
> + VIR_FREE(priv);
> + return NULL;
> +}
> +
> +
> +static void
> +virLockDaemonUsage(const char *argv0, bool privileged)
> +{
> + fprintf(stderr,
> + _("\n"
> + "Usage:\n"
> + " %s [options]\n"
> + "\n"
> + "Options:\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"
> + " | --version Display version information.\n"
> + " -p | --pid-file <file> Change name of PID file.\n"
> + "\n"
> + "libvirt lock management daemon:\n"), argv0);
> +
> + if (privileged) {
> + fprintf(stderr,
> + _("\n"
> + " Default paths:\n"
> + "\n"
> + " Configuration file (unless overridden by -f):\n"
> + " %s/libvirt/virtlockd.conf\n"
> + "\n"
> + " Sockets:\n"
> + " %s/run/libvirt/virtlockd-sock\n"
> + "\n"
> + " PID file (unless overridden by -p):\n"
> + " %s/run/virtlockd.pid\n"
> + "\n"),
> + SYSCONFDIR,
> + LOCALSTATEDIR,
> + LOCALSTATEDIR);
> + } else {
> + fprintf(stderr,
> + "%s", _("\n"
> + " Default paths:\n"
> + "\n"
> + " Configuration file (unless overridden by -f):\n"
> + " $XDG_CONFIG_HOME/libvirt/virtlockd.conf\n"
> + "\n"
> + " Sockets:\n"
> + " $XDG_RUNTIME_DIR/libvirt/virtlockd-sock\n"
> + "\n"
> + " PID file:\n"
> + " $XDG_RUNTIME_DIR/libvirt/virtlockd.pid\n"
> + "\n"));
just a small nit, if you'd move "%s" to the previous line, this and the
previous blocks would be perfectly aligned.
> + }
> +}
> +
> +enum {
> + OPT_VERSION = 129
> +};
> +
> +#define MAX_LISTEN 5
> +int main(int argc, char **argv) {
> + char *remote_config_file = NULL;
> + int statuswrite = -1;
> + int ret = 1;
> + int verbose = 0;
> + int godaemon = 0;
> + int timeout = 0;
timeout seems dummy to me.
ACK if you either remove it or (more likely) implement it.
More information about the libvir-list
mailing list