mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 09:17:52 +03:00
locking: use shared daemon startup code
Signed-off-by: Rafael Fonseca <r4f4rfs@gmail.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
fc5925f1e0
commit
0678140239
@ -2016,7 +2016,7 @@ exclude_file_name_regexp--sc_prohibit_close = \
|
||||
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
|
||||
(^tests/(virhostcpu|virpcitest)data/|docs/js/.*\.js|docs/fonts/.*\.woff|\.diff|tests/virconfdata/no-newline\.conf$$)
|
||||
|
||||
_src2=src/(util/(vircommand|virdaemon)|libvirt|lxc/lxc_controller|locking/lock_daemon|logging/log_daemon|remote/remote_daemon)
|
||||
_src2=src/(util/(vircommand|virdaemon)|libvirt|lxc/lxc_controller|logging/log_daemon|remote/remote_daemon)
|
||||
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
|
||||
(^($(_src2)|tests/testutils)\.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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user