2020-03-26 15:18:00 +00:00
|
|
|
/*
|
|
|
|
* 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>
|
|
|
|
|
util: Fix virDaemonForkIntoBackground
This commit partially reverts
commit c360ea28dc267802690e129fbad08ca2f22a44e9
Refs: v6.2.0-rc1-1-gc360ea28dc
Author: Rafael Fonseca <r4f4rfs@gmail.com>
AuthorDate: Fri Mar 27 18:40:47 2020 +0100
Commit: Michal Prívozník <mprivozn@redhat.com>
CommitDate: Mon Mar 30 09:48:22 2020 +0200
util: virdaemon: fix compilation on mingw
The daemons are not supported on Win32 and therefore were not compiled
in that platform. However, with the daemon code sharing, all the code in
utils *is* compiled and it failed because `waitpid`, `fork`, and
`setsid` are not available. So, as before, let's not build them on
Win32 and make the code more portable by using existing vir* wrappers.
Not compiling virDaemonForkIntoBackground on Win32 is good, but the
second part of the original patch incorrectly replaced waitpid and fork
with our virProcessWait and virFork APIs. These APIs are more than just
simple wrappers and we don't want any of the extra functionality.
Especially virFork would reset any setup made before
virDaemonForkIntoBackground is called, such as logging, signal handling,
etc.
As a result of the change the additional fix in v6.2.0-67-ga87e4788d2
(util: virdaemon: fix waiting for child processes) is no longer
needed and it is effectively reverted by this commit.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2020-04-16 13:11:06 +00:00
|
|
|
#include <sys/types.h>
|
2020-03-26 15:18:00 +00:00
|
|
|
#include <sys/stat.h>
|
2020-04-17 18:27:00 +00:00
|
|
|
#ifndef WIN32
|
|
|
|
# include <sys/wait.h>
|
|
|
|
#endif
|
2020-03-26 15:18:00 +00:00
|
|
|
#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"
|
|
|
|
|
2020-03-27 17:40:47 +00:00
|
|
|
#ifndef WIN32
|
|
|
|
|
2020-03-26 15:18:00 +00:00
|
|
|
int
|
|
|
|
virDaemonForkIntoBackground(const char *argv0)
|
|
|
|
{
|
|
|
|
int statuspipe[2];
|
|
|
|
if (virPipeQuiet(statuspipe) < 0)
|
|
|
|
return -1;
|
|
|
|
|
util: Fix virDaemonForkIntoBackground
This commit partially reverts
commit c360ea28dc267802690e129fbad08ca2f22a44e9
Refs: v6.2.0-rc1-1-gc360ea28dc
Author: Rafael Fonseca <r4f4rfs@gmail.com>
AuthorDate: Fri Mar 27 18:40:47 2020 +0100
Commit: Michal Prívozník <mprivozn@redhat.com>
CommitDate: Mon Mar 30 09:48:22 2020 +0200
util: virdaemon: fix compilation on mingw
The daemons are not supported on Win32 and therefore were not compiled
in that platform. However, with the daemon code sharing, all the code in
utils *is* compiled and it failed because `waitpid`, `fork`, and
`setsid` are not available. So, as before, let's not build them on
Win32 and make the code more portable by using existing vir* wrappers.
Not compiling virDaemonForkIntoBackground on Win32 is good, but the
second part of the original patch incorrectly replaced waitpid and fork
with our virProcessWait and virFork APIs. These APIs are more than just
simple wrappers and we don't want any of the extra functionality.
Especially virFork would reset any setup made before
virDaemonForkIntoBackground is called, such as logging, signal handling,
etc.
As a result of the change the additional fix in v6.2.0-67-ga87e4788d2
(util: virdaemon: fix waiting for child processes) is no longer
needed and it is effectively reverted by this commit.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2020-04-16 13:11:06 +00:00
|
|
|
pid_t pid = fork();
|
2020-03-26 15:18:00 +00:00
|
|
|
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)) < 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;
|
|
|
|
|
util: Fix virDaemonForkIntoBackground
This commit partially reverts
commit c360ea28dc267802690e129fbad08ca2f22a44e9
Refs: v6.2.0-rc1-1-gc360ea28dc
Author: Rafael Fonseca <r4f4rfs@gmail.com>
AuthorDate: Fri Mar 27 18:40:47 2020 +0100
Commit: Michal Prívozník <mprivozn@redhat.com>
CommitDate: Mon Mar 30 09:48:22 2020 +0200
util: virdaemon: fix compilation on mingw
The daemons are not supported on Win32 and therefore were not compiled
in that platform. However, with the daemon code sharing, all the code in
utils *is* compiled and it failed because `waitpid`, `fork`, and
`setsid` are not available. So, as before, let's not build them on
Win32 and make the code more portable by using existing vir* wrappers.
Not compiling virDaemonForkIntoBackground on Win32 is good, but the
second part of the original patch incorrectly replaced waitpid and fork
with our virProcessWait and virFork APIs. These APIs are more than just
simple wrappers and we don't want any of the extra functionality.
Especially virFork would reset any setup made before
virDaemonForkIntoBackground is called, such as logging, signal handling,
etc.
As a result of the change the additional fix in v6.2.0-67-ga87e4788d2
(util: virdaemon: fix waiting for child processes) is no longer
needed and it is effectively reverted by this commit.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2020-04-16 13:11:06 +00:00
|
|
|
nextpid = fork();
|
2020-03-26 15:18:00 +00:00
|
|
|
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 */
|
util: Fix virDaemonForkIntoBackground
This commit partially reverts
commit c360ea28dc267802690e129fbad08ca2f22a44e9
Refs: v6.2.0-rc1-1-gc360ea28dc
Author: Rafael Fonseca <r4f4rfs@gmail.com>
AuthorDate: Fri Mar 27 18:40:47 2020 +0100
Commit: Michal Prívozník <mprivozn@redhat.com>
CommitDate: Mon Mar 30 09:48:22 2020 +0200
util: virdaemon: fix compilation on mingw
The daemons are not supported on Win32 and therefore were not compiled
in that platform. However, with the daemon code sharing, all the code in
utils *is* compiled and it failed because `waitpid`, `fork`, and
`setsid` are not available. So, as before, let's not build them on
Win32 and make the code more portable by using existing vir* wrappers.
Not compiling virDaemonForkIntoBackground on Win32 is good, but the
second part of the original patch incorrectly replaced waitpid and fork
with our virProcessWait and virFork APIs. These APIs are more than just
simple wrappers and we don't want any of the extra functionality.
Especially virFork would reset any setup made before
virDaemonForkIntoBackground is called, such as logging, signal handling,
etc.
As a result of the change the additional fix in v6.2.0-67-ga87e4788d2
(util: virdaemon: fix waiting for child processes) is no longer
needed and it is effectively reverted by this commit.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2020-04-16 13:11:06 +00:00
|
|
|
int got, exitstatus = 0;
|
2020-03-26 15:18:00 +00:00
|
|
|
int ret;
|
|
|
|
char status;
|
|
|
|
|
|
|
|
VIR_FORCE_CLOSE(statuspipe[1]);
|
|
|
|
|
|
|
|
/* We wait to make sure the first child forked successfully */
|
util: Fix virDaemonForkIntoBackground
This commit partially reverts
commit c360ea28dc267802690e129fbad08ca2f22a44e9
Refs: v6.2.0-rc1-1-gc360ea28dc
Author: Rafael Fonseca <r4f4rfs@gmail.com>
AuthorDate: Fri Mar 27 18:40:47 2020 +0100
Commit: Michal Prívozník <mprivozn@redhat.com>
CommitDate: Mon Mar 30 09:48:22 2020 +0200
util: virdaemon: fix compilation on mingw
The daemons are not supported on Win32 and therefore were not compiled
in that platform. However, with the daemon code sharing, all the code in
utils *is* compiled and it failed because `waitpid`, `fork`, and
`setsid` are not available. So, as before, let's not build them on
Win32 and make the code more portable by using existing vir* wrappers.
Not compiling virDaemonForkIntoBackground on Win32 is good, but the
second part of the original patch incorrectly replaced waitpid and fork
with our virProcessWait and virFork APIs. These APIs are more than just
simple wrappers and we don't want any of the extra functionality.
Especially virFork would reset any setup made before
virDaemonForkIntoBackground is called, such as logging, signal handling,
etc.
As a result of the change the additional fix in v6.2.0-67-ga87e4788d2
(util: virdaemon: fix waiting for child processes) is no longer
needed and it is effectively reverted by this commit.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2020-04-16 13:11:06 +00:00
|
|
|
if ((got = waitpid(pid, &exitstatus, 0)) < 0 ||
|
|
|
|
got != pid ||
|
2020-03-26 15:18:00 +00:00
|
|
|
exitstatus != 0) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we got here, then the grandchild was spawned, so we
|
|
|
|
* must exit. Block until the second child initializes
|
|
|
|
* successfully */
|
|
|
|
ret = saferead(statuspipe[0], &status, 1);
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2020-03-27 17:40:47 +00:00
|
|
|
|
|
|
|
#else /* WIN32 */
|
|
|
|
|
|
|
|
int virDaemonForkIntoBackground(const char *argv0 G_GNUC_UNUSED)
|
|
|
|
{
|
|
|
|
errno = ENOTSUP;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void virDaemonSetupLogging(const char *daemon_name G_GNUC_UNUSED,
|
|
|
|
unsigned int log_level G_GNUC_UNUSED,
|
|
|
|
char *log_filters G_GNUC_UNUSED,
|
|
|
|
char *log_outputs G_GNUC_UNUSED,
|
|
|
|
bool privileged G_GNUC_UNUSED,
|
|
|
|
bool verbose G_GNUC_UNUSED,
|
|
|
|
bool godaemon G_GNUC_UNUSED)
|
|
|
|
{
|
|
|
|
/* NOOP */
|
|
|
|
errno = ENOTSUP;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int virDaemonUnixSocketPaths(const char *sock_prefix G_GNUC_UNUSED,
|
|
|
|
bool privileged G_GNUC_UNUSED,
|
|
|
|
char *unix_sock_dir G_GNUC_UNUSED,
|
|
|
|
char **sockfile G_GNUC_UNUSED,
|
|
|
|
char **rosockfile G_GNUC_UNUSED,
|
|
|
|
char **adminSockfile G_GNUC_UNUSED)
|
|
|
|
{
|
|
|
|
errno = ENOTSUP;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* WIN32 */
|