Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
L
libvirt
Manage
Activity
Members
Labels
Plan
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Libvirt Packaging Team
libvirt
Commits
43b7dacb
Commit
43b7dacb
authored
15 years ago
by
Laurent Léonard
Browse files
Options
Downloads
Patches
Plain Diff
Don't let parent of daemon exit until basic initialization is done.
parent
35451bf3
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
debian/patches/0006-Don-t-let-parent-of-daemon-exit-until-basic-initiali.patch
+233
-0
233 additions, 0 deletions
...on-t-let-parent-of-daemon-exit-until-basic-initiali.patch
debian/patches/series
+1
-0
1 addition, 0 deletions
debian/patches/series
with
234 additions
and
0 deletions
debian/patches/0006-Don-t-let-parent-of-daemon-exit-until-basic-initiali.patch
0 → 100644
+
233
−
0
View file @
43b7dacb
From: =?utf-8?q?Laurent=20L=C3=A9onard?= <laurent@open-minds.org>
Date: Sun, 25 Oct 2009 01:36:36 +0200
Subject: [PATCH] Don't let parent of daemon exit until basic initialization is done.
---
daemon/libvirtd.c | 116 +++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 99 insertions(+), 17 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 78dfb2d..d102c66 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -185,6 +185,30 @@
static int max_client_requests = 5;
static sig_atomic_t sig_errors = 0;
static int sig_lasterrno = 0;
+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_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")
+
static void sig_handler(int sig, siginfo_t * siginfo,
void* context ATTRIBUTE_UNUSED) {
int origerrno;
@@ -375,7 +399,11 @@
qemudDispatchSignalEvent(int watch ATTRIBUTE_UNUSED,
}
-static int qemudGoDaemon(void) {
+static int daemonForkIntoBackground(void) {
+ int statuspipe[2];
+ if (pipe(statuspipe) < 0)
+ return -1;
+
int pid = fork();
switch (pid) {
case 0:
@@ -384,6 +412,8 @@
static int qemudGoDaemon(void) {
int stdoutfd = -1;
int nextpid;
+ close(statuspipe[0]);
+
if ((stdinfd = open("/dev/null", O_RDONLY)) < 0)
goto cleanup;
if ((stdoutfd = open("/dev/null", O_WRONLY)) < 0)
@@ -407,7 +437,7 @@
static int qemudGoDaemon(void) {
nextpid = fork();
switch (nextpid) {
case 0:
- return 0;
+ return statuspipe[1];
case -1:
return -1;
default:
@@ -428,15 +458,29 @@
static int qemudGoDaemon(void) {
default:
{
- int got, status = 0;
- /* We wait to make sure the next child forked
- successfully */
- if ((got = waitpid(pid, &status, 0)) < 0 ||
+ int got, exitstatus = 0;
+ int ret;
+ char status;
+
+ close(statuspipe[1]);
+
+ /* We wait to make sure the first child forked successfully */
+ if ((got = waitpid(pid, &exitstatus, 0)) < 0 ||
got != pid ||
status != 0) {
return -1;
}
- _exit(0);
+
+ /* 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, "error: %s\n", virDaemonErrTypeToString(status));
+ }
+ _exit(ret == 1 && status == 0 ? 0 : 1);
}
}
}
@@ -859,8 +903,6 @@
static struct qemud_server *qemudInitialize(int sigread) {
virEventUpdateTimeoutImpl,
virEventRemoveTimeoutImpl);
- virStateInitialize(server->privileged);
-
return server;
}
@@ -2842,6 +2884,7 @@
int main(int argc, char **argv) {
int sigpipe[2];
const char *pid_file = NULL;
const char *remote_config_file = NULL;
+ int statuswrite = -1;
int ret = 1;
struct option opts[] = {
@@ -2923,7 +2966,7 @@
int main(int argc, char **argv) {
if (godaemon) {
char ebuf[1024];
- if (qemudGoDaemon() < 0) {
+ if ((statuswrite = daemonForkIntoBackground()) < 0) {
VIR_ERROR(_("Failed to fork as daemon: %s"),
virStrerror(errno, ebuf, sizeof ebuf));
goto error1;
@@ -2938,8 +2981,11 @@
int main(int argc, char **argv) {
/* If we have a pidfile set, claim it now, exiting if already taken */
if (pid_file != NULL &&
- qemudWritePidFile (pid_file) < 0)
+ qemudWritePidFile (pid_file) < 0) {
+ pid_file = NULL; /* Prevent unlinking of someone else's pid ! */
+ ret = VIR_DAEMON_ERR_PIDFILE;
goto error1;
+ }
if (pipe(sigpipe) < 0 ||
virSetNonBlock(sigpipe[0]) < 0 ||
@@ -2973,7 +3019,8 @@
int main(int argc, char **argv) {
if (mkdir (rundir, 0755)) {
if (errno != EEXIST) {
VIR_ERROR0 (_("unable to create rundir"));
- return -1;
+ ret = VIR_DAEMON_ERR_RUNDIR;
+ goto error1;
}
}
}
@@ -2984,17 +3031,21 @@
int main(int argc, char **argv) {
* which is also passed into all libvirt stateful
* drivers
*/
- if (qemudSetupPrivs() < 0)
+ if (qemudSetupPrivs() < 0) {
+ ret = VIR_DAEMON_ERR_PRIVS;
goto error2;
+ }
if (!(server = qemudInitialize(sigpipe[0]))) {
- ret = 2;
+ ret = VIR_DAEMON_ERR_INIT;
goto error2;
}
/* Read the config file (if it exists). */
- if (remoteReadConfigFile (server, remote_config_file) < 0)
+ if (remoteReadConfigFile (server, remote_config_file) < 0) {
+ ret = VIR_DAEMON_ERR_CONFIG;
goto error2;
+ }
/* Change the group ownership of /var/run/libvirt to unix_sock_gid */
if (unix_sock_dir && server->privileged) {
@@ -3013,15 +3064,46 @@
int main(int argc, char **argv) {
}
if (!(server = qemudNetworkInit(server))) {
- ret = 2;
+ ret = VIR_DAEMON_ERR_NETWORK;
goto error2;
}
- qemudRunLoop(server);
+ /* Tell parent of daemon that basic initialization is complete
+ * In particular we're ready to accept net connections & have
+ * written the pidfile
+ */
+ if (statuswrite != -1) {
+ char status = 0;
+ while (write(statuswrite, &status, 1) == -1 &&
+ errno == EINTR)
+ ;
+ close(statuswrite);
+ statuswrite = -1;
+ }
+
+ /* Start the stateful HV drivers
+ * This is delibrately done after telling the parent process
+ * we're ready, since it can take a long time and this will
+ * seriously delay OS bootup process */
+ if (virStateInitialize(server->privileged) < 0) {
+ VIR_ERROR0("Driver state initialization failed");
+ goto error2;
+ }
+ qemudRunLoop(server);
ret = 0;
error2:
+ if (statuswrite != -1) {
+ if (ret != 0) {
+ /* Tell parent of daemon what failed */
+ char status = ret;
+ while (write(statuswrite, &status, 1) == -1 &&
+ errno == EINTR)
+ ;
+ }
+ close(statuswrite);
+ }
if (server)
qemudCleanup(server);
if (pid_file)
--
This diff is collapsed.
Click to expand it.
debian/patches/series
+
1
−
0
View file @
43b7dacb
...
...
@@ -3,3 +3,4 @@
0003-allow-libvirt-group-to-access-the-socket.patch
0004-fix-Debian-specific-path-to-hvm-loader.patch
0005-Fix-SELinux-linking-issues.patch
0006-Don-t-let-parent-of-daemon-exit-until-basic-initiali.patch
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment