提交 a71f79c3 编写于 作者: D Daniel P. Berrange

Pull signal setup code out into separate method

* daemon/libvirtd.c: Introduce a daemonSetupSignals() method
  and put all signal handling code there
* daemon/libvirtd.h: Add sigread/sigwrite to qemud_server type
上级 8001eef5
...@@ -782,7 +782,7 @@ static void virshErrorHandler(void *opaque ATTRIBUTE_UNUSED, virErrorPtr err ATT ...@@ -782,7 +782,7 @@ static void virshErrorHandler(void *opaque ATTRIBUTE_UNUSED, virErrorPtr err ATT
* took care of reporting the error */ * took care of reporting the error */
} }
static struct qemud_server *qemudInitialize(int sigread) { static struct qemud_server *qemudInitialize(void) {
struct qemud_server *server; struct qemud_server *server;
if (VIR_ALLOC(server) < 0) { if (VIR_ALLOC(server) < 0) {
...@@ -790,21 +790,26 @@ static struct qemud_server *qemudInitialize(int sigread) { ...@@ -790,21 +790,26 @@ static struct qemud_server *qemudInitialize(int sigread) {
return NULL; return NULL;
} }
server->privileged = geteuid() == 0 ? 1 : 0;
server->sigread = server->sigwrite = -1;
if (virMutexInit(&server->lock) < 0) { if (virMutexInit(&server->lock) < 0) {
VIR_ERROR("%s", _("cannot initialize mutex")); VIR_ERROR("%s", _("cannot initialize mutex"));
VIR_FREE(server); VIR_FREE(server);
return NULL;
} }
if (virCondInit(&server->job) < 0) { if (virCondInit(&server->job) < 0) {
VIR_ERROR("%s", _("cannot initialize condition variable")); VIR_ERROR("%s", _("cannot initialize condition variable"));
virMutexDestroy(&server->lock); virMutexDestroy(&server->lock);
VIR_FREE(server); VIR_FREE(server);
return NULL;
} }
server->privileged = geteuid() == 0 ? 1 : 0;
server->sigread = sigread;
if (virEventInit() < 0) { if (virEventInit() < 0) {
VIR_ERROR0(_("Failed to initialize event system")); VIR_ERROR0(_("Failed to initialize event system"));
virMutexDestroy(&server->lock);
if (virCondDestroy(&server->job) < 0)
{}
VIR_FREE(server); VIR_FREE(server);
return NULL; return NULL;
} }
...@@ -2296,7 +2301,10 @@ cleanup: ...@@ -2296,7 +2301,10 @@ cleanup:
static void qemudCleanup(struct qemud_server *server) { static void qemudCleanup(struct qemud_server *server) {
struct qemud_socket *sock; struct qemud_socket *sock;
if (server->sigread != -1)
close(server->sigread); close(server->sigread);
if (server->sigwrite != -1)
close(server->sigwrite);
sock = server->sockets; sock = server->sockets;
while (sock) { while (sock) {
...@@ -2786,6 +2794,67 @@ qemudSetupPrivs (void) ...@@ -2786,6 +2794,67 @@ qemudSetupPrivs (void)
#define qemudSetupPrivs() 0 #define qemudSetupPrivs() 0
#endif #endif
/*
* Doing anything non-trivial in signal handlers is pretty dangerous,
* since there are very few async-signal safe POSIX funtions. To
* deal with this we setup a very simple signal handler. It simply
* writes the signal number to a pipe. The main event loop then sees
* the signal on the pipe and can safely do the processing from
* event loop context
*/
static int
daemonSetupSignals(struct qemud_server *server)
{
struct sigaction sig_action;
int sigpipe[2];
if (pipe(sigpipe) < 0)
return -1;
if (virSetNonBlock(sigpipe[0]) < 0 ||
virSetNonBlock(sigpipe[1]) < 0 ||
virSetCloseExec(sigpipe[0]) < 0 ||
virSetCloseExec(sigpipe[1]) < 0) {
char ebuf[1024];
VIR_ERROR(_("Failed to create pipe: %s"),
virStrerror(errno, ebuf, sizeof ebuf));
goto error;
}
sig_action.sa_sigaction = sig_handler;
sig_action.sa_flags = SA_SIGINFO;
sigemptyset(&sig_action.sa_mask);
sigaction(SIGHUP, &sig_action, NULL);
sigaction(SIGINT, &sig_action, NULL);
sigaction(SIGQUIT, &sig_action, NULL);
sigaction(SIGTERM, &sig_action, NULL);
sigaction(SIGCHLD, &sig_action, NULL);
sig_action.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sig_action, NULL);
if (virEventAddHandleImpl(sigpipe[0],
VIR_EVENT_HANDLE_READABLE,
qemudDispatchSignalEvent,
server, NULL) < 0) {
VIR_ERROR0(_("Failed to register callback for signal pipe"));
goto error;
}
server->sigread = sigpipe[0];
server->sigwrite = sigpipe[1];
sigwrite = sigpipe[1];
return 0;
error:
close(sigpipe[0]);
close(sigpipe[1]);
return -1;
}
/* Print command-line usage. */ /* Print command-line usage. */
static void static void
usage (const char *argv0) usage (const char *argv0)
...@@ -2839,8 +2908,6 @@ enum { ...@@ -2839,8 +2908,6 @@ enum {
#define MAX_LISTEN 5 #define MAX_LISTEN 5
int main(int argc, char **argv) { int main(int argc, char **argv) {
struct qemud_server *server = NULL; struct qemud_server *server = NULL;
struct sigaction sig_action;
int sigpipe[2];
const char *pid_file = NULL; const char *pid_file = NULL;
const char *remote_config_file = NULL; const char *remote_config_file = NULL;
int ret = 1; int ret = 1;
...@@ -2929,7 +2996,7 @@ int main(int argc, char **argv) { ...@@ -2929,7 +2996,7 @@ int main(int argc, char **argv) {
if (qemudGoDaemon() < 0) { if (qemudGoDaemon() < 0) {
VIR_ERROR(_("Failed to fork as daemon: %s"), VIR_ERROR(_("Failed to fork as daemon: %s"),
virStrerror(errno, ebuf, sizeof ebuf)); virStrerror(errno, ebuf, sizeof ebuf));
goto error1; goto error;
} }
} }
...@@ -2942,32 +3009,7 @@ int main(int argc, char **argv) { ...@@ -2942,32 +3009,7 @@ int main(int argc, char **argv) {
/* If we have a pidfile set, claim it now, exiting if already taken */ /* If we have a pidfile set, claim it now, exiting if already taken */
if (pid_file != NULL && if (pid_file != NULL &&
qemudWritePidFile (pid_file) < 0) qemudWritePidFile (pid_file) < 0)
goto error1; goto error;
if (pipe(sigpipe) < 0 ||
virSetNonBlock(sigpipe[0]) < 0 ||
virSetNonBlock(sigpipe[1]) < 0 ||
virSetCloseExec(sigpipe[0]) < 0 ||
virSetCloseExec(sigpipe[1]) < 0) {
char ebuf[1024];
VIR_ERROR(_("Failed to create pipe: %s"),
virStrerror(errno, ebuf, sizeof ebuf));
goto error2;
}
sigwrite = sigpipe[1];
sig_action.sa_sigaction = sig_handler;
sig_action.sa_flags = SA_SIGINFO;
sigemptyset(&sig_action.sa_mask);
sigaction(SIGHUP, &sig_action, NULL);
sigaction(SIGINT, &sig_action, NULL);
sigaction(SIGQUIT, &sig_action, NULL);
sigaction(SIGTERM, &sig_action, NULL);
sigaction(SIGCHLD, &sig_action, NULL);
sig_action.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sig_action, NULL);
/* Ensure the rundir exists (on tmpfs on some systems) */ /* Ensure the rundir exists (on tmpfs on some systems) */
if (geteuid() == 0) { if (geteuid() == 0) {
...@@ -2990,46 +3032,37 @@ int main(int argc, char **argv) { ...@@ -2990,46 +3032,37 @@ int main(int argc, char **argv) {
* drivers * drivers
*/ */
if (qemudSetupPrivs() < 0) if (qemudSetupPrivs() < 0)
goto error2; goto error;
if (!(server = qemudInitialize(sigpipe[0]))) { if (!(server = qemudInitialize())) {
ret = 2; ret = 2;
goto error2; goto error;
} }
if ((daemonSetupSignals(server)) < 0)
goto error;
/* Read the config file (if it exists). */ /* Read the config file (if it exists). */
if (remoteReadConfigFile (server, remote_config_file) < 0) if (remoteReadConfigFile (server, remote_config_file) < 0)
goto error2; goto error;
/* Disable error func, now logging is setup */ /* Disable error func, now logging is setup */
virSetErrorFunc(NULL, virshErrorHandler); virSetErrorFunc(NULL, virshErrorHandler);
if (virEventAddHandleImpl(sigpipe[0],
VIR_EVENT_HANDLE_READABLE,
qemudDispatchSignalEvent,
server, NULL) < 0) {
VIR_ERROR0(_("Failed to register callback for signal pipe"));
ret = 3;
goto error2;
}
if (qemudNetworkInit(server) < 0) { if (qemudNetworkInit(server) < 0) {
ret = 2; ret = 2;
goto error2; goto error;
} }
qemudRunLoop(server); qemudRunLoop(server);
ret = 0; ret = 0;
error2: error:
if (server) if (server)
qemudCleanup(server); qemudCleanup(server);
if (pid_file) if (pid_file)
unlink (pid_file); unlink (pid_file);
close(sigwrite);
error1:
virLogShutdown(); virLogShutdown();
return ret; return ret;
} }
...@@ -267,6 +267,7 @@ struct qemud_server { ...@@ -267,6 +267,7 @@ struct qemud_server {
struct qemud_client **clients; struct qemud_client **clients;
int sigread; int sigread;
int sigwrite;
char *logDir; char *logDir;
unsigned int shutdown : 1; unsigned int shutdown : 1;
#ifdef HAVE_AVAHI #ifdef HAVE_AVAHI
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册