mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-08 20:51:26 +00:00
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
This commit is contained in:
parent
8001eef5d0
commit
a71f79c37e
@ -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) {
|
|||||||
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:
|
|||||||
static void qemudCleanup(struct qemud_server *server) {
|
static void qemudCleanup(struct qemud_server *server) {
|
||||||
struct qemud_socket *sock;
|
struct qemud_socket *sock;
|
||||||
|
|
||||||
close(server->sigread);
|
if (server->sigread != -1)
|
||||||
|
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)
|
|||||||
#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 {
|
|||||||
#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) {
|
|||||||
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) {
|
|||||||
/* 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) {
|
|||||||
* 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 {
|
|||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user