mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-12 15:52:55 +00:00
Move daemon-related parts of virNetServer to virNetDaemon
This allows to have more servers in one daemon which helps isolating some resources. Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
parent
387cb8c6b2
commit
fa14207368
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* libvirtd.c: daemon start of day, guest process & i/o management
|
* libvirtd.c: daemon start of day, guest process & i/o management
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2014 Red Hat, Inc.
|
* Copyright (C) 2006-2015 Red Hat, Inc.
|
||||||
* Copyright (C) 2006 Daniel P. Berrange
|
* Copyright (C) 2006 Daniel P. Berrange
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -49,7 +49,7 @@
|
|||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virconf.h"
|
#include "virconf.h"
|
||||||
#include "virnetlink.h"
|
#include "virnetlink.h"
|
||||||
#include "virnetserver.h"
|
#include "virnetdaemon.h"
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "virhook.h"
|
#include "virhook.h"
|
||||||
#include "viraudit.h"
|
#include "viraudit.h"
|
||||||
@ -776,14 +776,14 @@ daemonSetupPrivs(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void daemonShutdownHandler(virNetServerPtr srv,
|
static void daemonShutdownHandler(virNetDaemonPtr dmn,
|
||||||
siginfo_t *sig ATTRIBUTE_UNUSED,
|
siginfo_t *sig ATTRIBUTE_UNUSED,
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
virNetServerQuit(srv);
|
virNetDaemonQuit(dmn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void daemonReloadHandler(virNetServerPtr srv ATTRIBUTE_UNUSED,
|
static void daemonReloadHandler(virNetDaemonPtr dmn ATTRIBUTE_UNUSED,
|
||||||
siginfo_t *sig ATTRIBUTE_UNUSED,
|
siginfo_t *sig ATTRIBUTE_UNUSED,
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
@ -799,15 +799,15 @@ static void daemonReloadHandler(virNetServerPtr srv ATTRIBUTE_UNUSED,
|
|||||||
VIR_WARN("Error while reloading drivers");
|
VIR_WARN("Error while reloading drivers");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int daemonSetupSignals(virNetServerPtr srv)
|
static int daemonSetupSignals(virNetDaemonPtr dmn)
|
||||||
{
|
{
|
||||||
if (virNetServerAddSignalHandler(srv, SIGINT, daemonShutdownHandler, NULL) < 0)
|
if (virNetDaemonAddSignalHandler(dmn, SIGINT, daemonShutdownHandler, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (virNetServerAddSignalHandler(srv, SIGQUIT, daemonShutdownHandler, NULL) < 0)
|
if (virNetDaemonAddSignalHandler(dmn, SIGQUIT, daemonShutdownHandler, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (virNetServerAddSignalHandler(srv, SIGTERM, daemonShutdownHandler, NULL) < 0)
|
if (virNetDaemonAddSignalHandler(dmn, SIGTERM, daemonShutdownHandler, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (virNetServerAddSignalHandler(srv, SIGHUP, daemonReloadHandler, NULL) < 0)
|
if (virNetDaemonAddSignalHandler(dmn, SIGHUP, daemonReloadHandler, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -815,12 +815,12 @@ static int daemonSetupSignals(virNetServerPtr srv)
|
|||||||
|
|
||||||
static void daemonInhibitCallback(bool inhibit, void *opaque)
|
static void daemonInhibitCallback(bool inhibit, void *opaque)
|
||||||
{
|
{
|
||||||
virNetServerPtr srv = opaque;
|
virNetDaemonPtr dmn = opaque;
|
||||||
|
|
||||||
if (inhibit)
|
if (inhibit)
|
||||||
virNetServerAddShutdownInhibition(srv);
|
virNetDaemonAddShutdownInhibition(dmn);
|
||||||
else
|
else
|
||||||
virNetServerRemoveShutdownInhibition(srv);
|
virNetDaemonRemoveShutdownInhibition(dmn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -830,26 +830,26 @@ static DBusConnection *systemBus;
|
|||||||
|
|
||||||
static void daemonStopWorker(void *opaque)
|
static void daemonStopWorker(void *opaque)
|
||||||
{
|
{
|
||||||
virNetServerPtr srv = opaque;
|
virNetDaemonPtr dmn = opaque;
|
||||||
|
|
||||||
VIR_DEBUG("Begin stop srv=%p", srv);
|
VIR_DEBUG("Begin stop dmn=%p", dmn);
|
||||||
|
|
||||||
ignore_value(virStateStop());
|
ignore_value(virStateStop());
|
||||||
|
|
||||||
VIR_DEBUG("Completed stop srv=%p", srv);
|
VIR_DEBUG("Completed stop dmn=%p", dmn);
|
||||||
|
|
||||||
/* Exit libvirtd cleanly */
|
/* Exit libvirtd cleanly */
|
||||||
virNetServerQuit(srv);
|
virNetDaemonQuit(dmn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We do this in a thread to not block the main loop */
|
/* We do this in a thread to not block the main loop */
|
||||||
static void daemonStop(virNetServerPtr srv)
|
static void daemonStop(virNetDaemonPtr dmn)
|
||||||
{
|
{
|
||||||
virThread thr;
|
virThread thr;
|
||||||
virObjectRef(srv);
|
virObjectRef(dmn);
|
||||||
if (virThreadCreate(&thr, false, daemonStopWorker, srv) < 0)
|
if (virThreadCreate(&thr, false, daemonStopWorker, dmn) < 0)
|
||||||
virObjectUnref(srv);
|
virObjectUnref(dmn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -858,14 +858,14 @@ handleSessionMessageFunc(DBusConnection *connection ATTRIBUTE_UNUSED,
|
|||||||
DBusMessage *message,
|
DBusMessage *message,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
virNetServerPtr srv = opaque;
|
virNetDaemonPtr dmn = opaque;
|
||||||
|
|
||||||
VIR_DEBUG("srv=%p", srv);
|
VIR_DEBUG("dmn=%p", dmn);
|
||||||
|
|
||||||
if (dbus_message_is_signal(message,
|
if (dbus_message_is_signal(message,
|
||||||
DBUS_INTERFACE_LOCAL,
|
DBUS_INTERFACE_LOCAL,
|
||||||
"Disconnected"))
|
"Disconnected"))
|
||||||
daemonStop(srv);
|
daemonStop(dmn);
|
||||||
|
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
}
|
}
|
||||||
@ -876,14 +876,14 @@ handleSystemMessageFunc(DBusConnection *connection ATTRIBUTE_UNUSED,
|
|||||||
DBusMessage *message,
|
DBusMessage *message,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
virNetServerPtr srv = opaque;
|
virNetDaemonPtr dmn = opaque;
|
||||||
|
|
||||||
VIR_DEBUG("srv=%p", srv);
|
VIR_DEBUG("dmn=%p", dmn);
|
||||||
|
|
||||||
if (dbus_message_is_signal(message,
|
if (dbus_message_is_signal(message,
|
||||||
"org.freedesktop.login1.Manager",
|
"org.freedesktop.login1.Manager",
|
||||||
"PrepareForShutdown"))
|
"PrepareForShutdown"))
|
||||||
daemonStop(srv);
|
daemonStop(dmn);
|
||||||
|
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
}
|
}
|
||||||
@ -892,22 +892,22 @@ handleSystemMessageFunc(DBusConnection *connection ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
static void daemonRunStateInit(void *opaque)
|
static void daemonRunStateInit(void *opaque)
|
||||||
{
|
{
|
||||||
virNetServerPtr srv = opaque;
|
virNetDaemonPtr dmn = opaque;
|
||||||
virIdentityPtr sysident = virIdentityGetSystem();
|
virIdentityPtr sysident = virIdentityGetSystem();
|
||||||
|
|
||||||
virIdentitySetCurrent(sysident);
|
virIdentitySetCurrent(sysident);
|
||||||
|
|
||||||
/* Since driver initialization can take time inhibit daemon shutdown until
|
/* Since driver initialization can take time inhibit daemon shutdown until
|
||||||
we're done so clients get a chance to connect */
|
we're done so clients get a chance to connect */
|
||||||
daemonInhibitCallback(true, srv);
|
daemonInhibitCallback(true, dmn);
|
||||||
|
|
||||||
/* Start the stateful HV drivers
|
/* Start the stateful HV drivers
|
||||||
* This is deliberately done after telling the parent process
|
* This is deliberately done after telling the parent process
|
||||||
* we're ready, since it can take a long time and this will
|
* we're ready, since it can take a long time and this will
|
||||||
* seriously delay OS bootup process */
|
* seriously delay OS bootup process */
|
||||||
if (virStateInitialize(virNetServerIsPrivileged(srv),
|
if (virStateInitialize(virNetDaemonIsPrivileged(dmn),
|
||||||
daemonInhibitCallback,
|
daemonInhibitCallback,
|
||||||
srv) < 0) {
|
dmn) < 0) {
|
||||||
VIR_ERROR(_("Driver state initialization failed"));
|
VIR_ERROR(_("Driver state initialization failed"));
|
||||||
/* Ensure the main event loop quits */
|
/* Ensure the main event loop quits */
|
||||||
kill(getpid(), SIGTERM);
|
kill(getpid(), SIGTERM);
|
||||||
@ -918,17 +918,17 @@ static void daemonRunStateInit(void *opaque)
|
|||||||
|
|
||||||
#ifdef HAVE_DBUS
|
#ifdef HAVE_DBUS
|
||||||
/* Tie the non-priviledged libvirtd to the session/shutdown lifecycle */
|
/* Tie the non-priviledged libvirtd to the session/shutdown lifecycle */
|
||||||
if (!virNetServerIsPrivileged(srv)) {
|
if (!virNetDaemonIsPrivileged(dmn)) {
|
||||||
|
|
||||||
sessionBus = virDBusGetSessionBus();
|
sessionBus = virDBusGetSessionBus();
|
||||||
if (sessionBus != NULL)
|
if (sessionBus != NULL)
|
||||||
dbus_connection_add_filter(sessionBus,
|
dbus_connection_add_filter(sessionBus,
|
||||||
handleSessionMessageFunc, srv, NULL);
|
handleSessionMessageFunc, dmn, NULL);
|
||||||
|
|
||||||
systemBus = virDBusGetSystemBus();
|
systemBus = virDBusGetSystemBus();
|
||||||
if (systemBus != NULL) {
|
if (systemBus != NULL) {
|
||||||
dbus_connection_add_filter(systemBus,
|
dbus_connection_add_filter(systemBus,
|
||||||
handleSystemMessageFunc, srv, NULL);
|
handleSystemMessageFunc, dmn, NULL);
|
||||||
dbus_bus_add_match(systemBus,
|
dbus_bus_add_match(systemBus,
|
||||||
"type='signal',sender='org.freedesktop.login1', interface='org.freedesktop.login1.Manager'",
|
"type='signal',sender='org.freedesktop.login1', interface='org.freedesktop.login1.Manager'",
|
||||||
NULL);
|
NULL);
|
||||||
@ -936,20 +936,20 @@ static void daemonRunStateInit(void *opaque)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Only now accept clients from network */
|
/* Only now accept clients from network */
|
||||||
virNetServerUpdateServices(srv, true);
|
virNetDaemonUpdateServices(dmn, true);
|
||||||
cleanup:
|
cleanup:
|
||||||
daemonInhibitCallback(false, srv);
|
daemonInhibitCallback(false, dmn);
|
||||||
virObjectUnref(srv);
|
virObjectUnref(dmn);
|
||||||
virObjectUnref(sysident);
|
virObjectUnref(sysident);
|
||||||
virIdentitySetCurrent(NULL);
|
virIdentitySetCurrent(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int daemonStateInit(virNetServerPtr srv)
|
static int daemonStateInit(virNetDaemonPtr dmn)
|
||||||
{
|
{
|
||||||
virThread thr;
|
virThread thr;
|
||||||
virObjectRef(srv);
|
virObjectRef(dmn);
|
||||||
if (virThreadCreate(&thr, false, daemonRunStateInit, srv) < 0) {
|
if (virThreadCreate(&thr, false, daemonRunStateInit, dmn) < 0) {
|
||||||
virObjectUnref(srv);
|
virObjectUnref(dmn);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -1100,6 +1100,7 @@ daemonUsage(const char *argv0, bool privileged)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
virNetDaemonPtr dmn = NULL;
|
||||||
virNetServerPtr srv = NULL;
|
virNetServerPtr srv = NULL;
|
||||||
char *remote_config_file = NULL;
|
char *remote_config_file = NULL;
|
||||||
int statuswrite = -1;
|
int statuswrite = -1;
|
||||||
@ -1354,6 +1355,12 @@ int main(int argc, char **argv) {
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(dmn = virNetDaemonNew()) ||
|
||||||
|
virNetDaemonAddServer(dmn, srv) < 0) {
|
||||||
|
ret = VIR_DAEMON_ERR_INIT;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/* Beyond this point, nothing should rely on using
|
/* Beyond this point, nothing should rely on using
|
||||||
* getuid/geteuid() == 0, for privilege level checks.
|
* getuid/geteuid() == 0, for privilege level checks.
|
||||||
*/
|
*/
|
||||||
@ -1408,11 +1415,10 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (timeout != -1) {
|
if (timeout != -1) {
|
||||||
VIR_DEBUG("Registering shutdown timeout %d", timeout);
|
VIR_DEBUG("Registering shutdown timeout %d", timeout);
|
||||||
virNetServerAutoShutdown(srv,
|
virNetDaemonAutoShutdown(dmn, timeout);
|
||||||
timeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((daemonSetupSignals(srv)) < 0) {
|
if ((daemonSetupSignals(dmn)) < 0) {
|
||||||
ret = VIR_DAEMON_ERR_SIGNAL;
|
ret = VIR_DAEMON_ERR_SIGNAL;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -1467,7 +1473,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize drivers & then start accepting new clients from network */
|
/* Initialize drivers & then start accepting new clients from network */
|
||||||
if (daemonStateInit(srv) < 0) {
|
if (daemonStateInit(dmn) < 0) {
|
||||||
ret = VIR_DAEMON_ERR_INIT;
|
ret = VIR_DAEMON_ERR_INIT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -1489,7 +1495,7 @@ int main(int argc, char **argv) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Run event loop. */
|
/* Run event loop. */
|
||||||
virNetServerRun(srv);
|
virNetDaemonRun(dmn);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
@ -1501,7 +1507,8 @@ int main(int argc, char **argv) {
|
|||||||
virObjectUnref(remoteProgram);
|
virObjectUnref(remoteProgram);
|
||||||
virObjectUnref(lxcProgram);
|
virObjectUnref(lxcProgram);
|
||||||
virObjectUnref(qemuProgram);
|
virObjectUnref(qemuProgram);
|
||||||
virNetServerClose(srv);
|
virNetDaemonClose(dmn);
|
||||||
|
virObjectUnref(dmn);
|
||||||
virObjectUnref(srv);
|
virObjectUnref(srv);
|
||||||
virNetlinkShutdown();
|
virNetlinkShutdown();
|
||||||
if (statuswrite != -1) {
|
if (statuswrite != -1) {
|
||||||
|
@ -82,7 +82,9 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li>Daemon Startup
|
<li>Daemon Startup
|
||||||
<p>The daemon initialization processing will declare itself
|
<p>The daemon initialization processing will declare itself
|
||||||
as a server via a virNetServerNew() call, then use
|
as a daemon via a virNetDaemonNew() call, then creates new server
|
||||||
|
using virNetServerNew() and adds that server to the main daemon
|
||||||
|
struct with virNetDaemonAddServer() call. It will then use
|
||||||
virDriverLoadModule() to find/load all known drivers,
|
virDriverLoadModule() to find/load all known drivers,
|
||||||
set up an RPC server program using the <code>remoteProcs[]</code>
|
set up an RPC server program using the <code>remoteProcs[]</code>
|
||||||
table via a virNetServerProgramNew() call. The table is the
|
table via a virNetServerProgramNew() call. The table is the
|
||||||
|
@ -532,6 +532,13 @@
|
|||||||
calls in parallel, with dispatch across multiple worker threads.
|
calls in parallel, with dispatch across multiple worker threads.
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
|
<dt><code>virNetDaemonPtr</code> (virnetdaemon.h)</dt>
|
||||||
|
<dd>The virNetDaemon APIs are used to manage a daemon process. A
|
||||||
|
deamon is a process that might expose one or more servers. It
|
||||||
|
handles most process-related details, network-related should
|
||||||
|
be part of the underlying server.
|
||||||
|
</dd>
|
||||||
|
|
||||||
<dt><code>virNetServerMDNSPtr</code> (virnetservermdns.h)</dt>
|
<dt><code>virNetServerMDNSPtr</code> (virnetservermdns.h)</dt>
|
||||||
<dd>The virNetServerMDNS APIs are used to advertise a server
|
<dd>The virNetServerMDNS APIs are used to advertise a server
|
||||||
across the local network, enabling clients to automatically
|
across the local network, enabling clients to automatically
|
||||||
|
@ -132,6 +132,7 @@ src/rpc/virkeepalive.c
|
|||||||
src/rpc/virnetclient.c
|
src/rpc/virnetclient.c
|
||||||
src/rpc/virnetclientprogram.c
|
src/rpc/virnetclientprogram.c
|
||||||
src/rpc/virnetclientstream.c
|
src/rpc/virnetclientstream.c
|
||||||
|
src/rpc/virnetdaemon.c
|
||||||
src/rpc/virnetmessage.c
|
src/rpc/virnetmessage.c
|
||||||
src/rpc/virnetsaslcontext.c
|
src/rpc/virnetsaslcontext.c
|
||||||
src/rpc/virnetsocket.c
|
src/rpc/virnetsocket.c
|
||||||
|
@ -2507,6 +2507,7 @@ libvirt_net_rpc_server_la_SOURCES = \
|
|||||||
rpc/virnetserverservice.h rpc/virnetserverservice.c \
|
rpc/virnetserverservice.h rpc/virnetserverservice.c \
|
||||||
rpc/virnetserverclient.h rpc/virnetserverclient.c \
|
rpc/virnetserverclient.h rpc/virnetserverclient.c \
|
||||||
rpc/virnetservermdns.h rpc/virnetservermdns.c \
|
rpc/virnetservermdns.h rpc/virnetservermdns.c \
|
||||||
|
rpc/virnetdaemon.h rpc/virnetdaemon.c \
|
||||||
rpc/virnetserver.h rpc/virnetserver.c
|
rpc/virnetserver.h rpc/virnetserver.c
|
||||||
libvirt_net_rpc_server_la_CFLAGS = \
|
libvirt_net_rpc_server_la_CFLAGS = \
|
||||||
$(AVAHI_CFLAGS) \
|
$(AVAHI_CFLAGS) \
|
||||||
|
@ -57,6 +57,24 @@ virNetClientStreamSendPacket;
|
|||||||
virNetClientStreamSetError;
|
virNetClientStreamSetError;
|
||||||
|
|
||||||
|
|
||||||
|
# rpc/virnetdaemon.h
|
||||||
|
virNetDaemonAddServer;
|
||||||
|
virNetDaemonAddServerPostExec;
|
||||||
|
virNetDaemonAddShutdownInhibition;
|
||||||
|
virNetDaemonAddSignalHandler;
|
||||||
|
virNetDaemonAutoShutdown;
|
||||||
|
virNetDaemonClose;
|
||||||
|
virNetDaemonGetServer;
|
||||||
|
virNetDaemonIsPrivileged;
|
||||||
|
virNetDaemonNew;
|
||||||
|
virNetDaemonNewPostExecRestart;
|
||||||
|
virNetDaemonPreExecRestart;
|
||||||
|
virNetDaemonQuit;
|
||||||
|
virNetDaemonRemoveShutdownInhibition;
|
||||||
|
virNetDaemonRun;
|
||||||
|
virNetDaemonUpdateServices;
|
||||||
|
|
||||||
|
|
||||||
# rpc/virnetmessage.h
|
# rpc/virnetmessage.h
|
||||||
virNetMessageClear;
|
virNetMessageClear;
|
||||||
virNetMessageDecodeHeader;
|
virNetMessageDecodeHeader;
|
||||||
@ -80,18 +98,16 @@ xdr_virNetMessageError;
|
|||||||
virNetServerAddClient;
|
virNetServerAddClient;
|
||||||
virNetServerAddProgram;
|
virNetServerAddProgram;
|
||||||
virNetServerAddService;
|
virNetServerAddService;
|
||||||
virNetServerAddShutdownInhibition;
|
|
||||||
virNetServerAddSignalHandler;
|
|
||||||
virNetServerAutoShutdown;
|
|
||||||
virNetServerClose;
|
virNetServerClose;
|
||||||
virNetServerIsPrivileged;
|
virNetServerHasClients;
|
||||||
virNetServerKeepAliveRequired;
|
virNetServerKeepAliveRequired;
|
||||||
virNetServerNew;
|
virNetServerNew;
|
||||||
virNetServerNewPostExecRestart;
|
virNetServerNewPostExecRestart;
|
||||||
virNetServerPreExecRestart;
|
virNetServerPreExecRestart;
|
||||||
virNetServerQuit;
|
virNetServerProcessClients;
|
||||||
virNetServerRemoveShutdownInhibition;
|
virNetServerStart;
|
||||||
virNetServerRun;
|
virNetServerTrackCompletedAuth;
|
||||||
|
virNetServerTrackPendingAuth;
|
||||||
virNetServerUpdateServices;
|
virNetServerUpdateServices;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* lock_daemon.c: lock management daemon
|
* lock_daemon.c: lock management daemon
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2014 Red Hat, Inc.
|
* Copyright (C) 2006-2015 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -41,6 +41,7 @@
|
|||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virconf.h"
|
#include "virconf.h"
|
||||||
|
#include "rpc/virnetdaemon.h"
|
||||||
#include "rpc/virnetserver.h"
|
#include "rpc/virnetserver.h"
|
||||||
#include "virrandom.h"
|
#include "virrandom.h"
|
||||||
#include "virhash.h"
|
#include "virhash.h"
|
||||||
@ -60,6 +61,7 @@ VIR_LOG_INIT("locking.lock_daemon");
|
|||||||
|
|
||||||
struct _virLockDaemon {
|
struct _virLockDaemon {
|
||||||
virMutex lock;
|
virMutex lock;
|
||||||
|
virNetDaemonPtr dmn;
|
||||||
virNetServerPtr srv;
|
virNetServerPtr srv;
|
||||||
virHashTablePtr lockspaces;
|
virHashTablePtr lockspaces;
|
||||||
virLockSpacePtr defaultLockspace;
|
virLockSpacePtr defaultLockspace;
|
||||||
@ -118,6 +120,7 @@ virLockDaemonFree(virLockDaemonPtr lockd)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
virObjectUnref(lockd->srv);
|
virObjectUnref(lockd->srv);
|
||||||
|
virObjectUnref(lockd->dmn);
|
||||||
virHashFree(lockd->lockspaces);
|
virHashFree(lockd->lockspaces);
|
||||||
virLockSpaceFree(lockd->defaultLockspace);
|
virLockSpaceFree(lockd->defaultLockspace);
|
||||||
|
|
||||||
@ -155,6 +158,10 @@ virLockDaemonNew(virLockDaemonConfigPtr config, bool privileged)
|
|||||||
(void*)(intptr_t)(privileged ? 0x1 : 0x0))))
|
(void*)(intptr_t)(privileged ? 0x1 : 0x0))))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (!(lockd->dmn = virNetDaemonNew()) ||
|
||||||
|
virNetDaemonAddServer(lockd->dmn, lockd->srv) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (!(lockd->lockspaces = virHashCreate(VIR_LOCK_DAEMON_NUM_LOCKSPACES,
|
if (!(lockd->lockspaces = virHashCreate(VIR_LOCK_DAEMON_NUM_LOCKSPACES,
|
||||||
virLockDaemonLockSpaceDataFree)))
|
virLockDaemonLockSpaceDataFree)))
|
||||||
goto error;
|
goto error;
|
||||||
@ -230,13 +237,24 @@ virLockDaemonNewPostExecRestart(virJSONValuePtr object, bool privileged)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virJSONValueObjectHasKey(object, "daemon")) {
|
||||||
|
if (!(child = virJSONValueObjectGet(object, "daemon"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Malformed daemon data from JSON file"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (!(child = virJSONValueObjectGet(object, "server"))) {
|
if (!(child = virJSONValueObjectGet(object, "server"))) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("Missing server data from JSON file"));
|
_("Missing server data from JSON file"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(lockd->srv = virNetServerNewPostExecRestart(child,
|
if (!(lockd->dmn = virNetDaemonNewPostExecRestart(child)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!(lockd->srv = virNetDaemonAddServerPostExec(lockd->dmn,
|
||||||
virLockDaemonClientNew,
|
virLockDaemonClientNew,
|
||||||
virLockDaemonClientNewPostExecRestart,
|
virLockDaemonClientNewPostExecRestart,
|
||||||
virLockDaemonClientPreExecRestart,
|
virLockDaemonClientPreExecRestart,
|
||||||
@ -529,32 +547,32 @@ virLockDaemonVersion(const char *argv0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virLockDaemonShutdownHandler(virNetServerPtr srv,
|
virLockDaemonShutdownHandler(virNetDaemonPtr dmn,
|
||||||
siginfo_t *sig ATTRIBUTE_UNUSED,
|
siginfo_t *sig ATTRIBUTE_UNUSED,
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
virNetServerQuit(srv);
|
virNetDaemonQuit(dmn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virLockDaemonExecRestartHandler(virNetServerPtr srv,
|
virLockDaemonExecRestartHandler(virNetDaemonPtr dmn,
|
||||||
siginfo_t *sig ATTRIBUTE_UNUSED,
|
siginfo_t *sig ATTRIBUTE_UNUSED,
|
||||||
void *opaque ATTRIBUTE_UNUSED)
|
void *opaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
execRestart = true;
|
execRestart = true;
|
||||||
virNetServerQuit(srv);
|
virNetDaemonQuit(dmn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virLockDaemonSetupSignals(virNetServerPtr srv)
|
virLockDaemonSetupSignals(virNetDaemonPtr dmn)
|
||||||
{
|
{
|
||||||
if (virNetServerAddSignalHandler(srv, SIGINT, virLockDaemonShutdownHandler, NULL) < 0)
|
if (virNetDaemonAddSignalHandler(dmn, SIGINT, virLockDaemonShutdownHandler, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (virNetServerAddSignalHandler(srv, SIGQUIT, virLockDaemonShutdownHandler, NULL) < 0)
|
if (virNetDaemonAddSignalHandler(dmn, SIGQUIT, virLockDaemonShutdownHandler, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (virNetServerAddSignalHandler(srv, SIGTERM, virLockDaemonShutdownHandler, NULL) < 0)
|
if (virNetDaemonAddSignalHandler(dmn, SIGTERM, virLockDaemonShutdownHandler, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (virNetServerAddSignalHandler(srv, SIGUSR1, virLockDaemonExecRestartHandler, NULL) < 0)
|
if (virNetDaemonAddSignalHandler(dmn, SIGUSR1, virLockDaemonExecRestartHandler, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -966,7 +984,7 @@ virLockDaemonPostExecRestart(const char *state_file,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
virLockDaemonPreExecRestart(const char *state_file,
|
virLockDaemonPreExecRestart(const char *state_file,
|
||||||
virNetServerPtr srv,
|
virNetDaemonPtr dmn,
|
||||||
char **argv)
|
char **argv)
|
||||||
{
|
{
|
||||||
virJSONValuePtr child;
|
virJSONValuePtr child;
|
||||||
@ -982,10 +1000,10 @@ virLockDaemonPreExecRestart(const char *state_file,
|
|||||||
if (!(object = virJSONValueNewObject()))
|
if (!(object = virJSONValueNewObject()))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!(child = virNetServerPreExecRestart(srv)))
|
if (!(child = virNetDaemonPreExecRestart(dmn)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virJSONValueObjectAppend(object, "server", child) < 0) {
|
if (virJSONValueObjectAppend(object, "daemon", child) < 0) {
|
||||||
virJSONValueFree(child);
|
virJSONValueFree(child);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -1350,11 +1368,11 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (timeout != -1) {
|
if (timeout != -1) {
|
||||||
VIR_DEBUG("Registering shutdown timeout %d", timeout);
|
VIR_DEBUG("Registering shutdown timeout %d", timeout);
|
||||||
virNetServerAutoShutdown(lockDaemon->srv,
|
virNetDaemonAutoShutdown(lockDaemon->dmn,
|
||||||
timeout);
|
timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((virLockDaemonSetupSignals(lockDaemon->srv)) < 0) {
|
if ((virLockDaemonSetupSignals(lockDaemon->dmn)) < 0) {
|
||||||
ret = VIR_LOCK_DAEMON_ERR_SIGNAL;
|
ret = VIR_LOCK_DAEMON_ERR_SIGNAL;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -1366,6 +1384,7 @@ int main(int argc, char **argv) {
|
|||||||
ret = VIR_LOCK_DAEMON_ERR_INIT;
|
ret = VIR_LOCK_DAEMON_ERR_INIT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virNetServerAddProgram(lockDaemon->srv, lockProgram) < 0) {
|
if (virNetServerAddProgram(lockDaemon->srv, lockProgram) < 0) {
|
||||||
ret = VIR_LOCK_DAEMON_ERR_INIT;
|
ret = VIR_LOCK_DAEMON_ERR_INIT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -1389,12 +1408,12 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
/* Start accepting new clients from network */
|
/* Start accepting new clients from network */
|
||||||
|
|
||||||
virNetServerUpdateServices(lockDaemon->srv, true);
|
virNetDaemonUpdateServices(lockDaemon->dmn, true);
|
||||||
virNetServerRun(lockDaemon->srv);
|
virNetDaemonRun(lockDaemon->dmn);
|
||||||
|
|
||||||
if (execRestart &&
|
if (execRestart &&
|
||||||
virLockDaemonPreExecRestart(state_file,
|
virLockDaemonPreExecRestart(state_file,
|
||||||
lockDaemon->srv,
|
lockDaemon->dmn,
|
||||||
argv) < 0)
|
argv) < 0)
|
||||||
ret = VIR_LOCK_DAEMON_ERR_REEXEC;
|
ret = VIR_LOCK_DAEMON_ERR_REEXEC;
|
||||||
else
|
else
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "rpc/virnetserver.h"
|
#include "rpc/virnetdaemon.h"
|
||||||
#include "configmake.h"
|
#include "configmake.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
#include "virutil.h"
|
#include "virutil.h"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* lock_daemon_dispatch.c: lock management daemon dispatch
|
* lock_daemon_dispatch.c: lock management daemon dispatch
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2012 Red Hat, Inc.
|
* Copyright (C) 2006-2015 Red Hat, Inc.
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include "rpc/virnetserver.h"
|
#include "rpc/virnetdaemon.h"
|
||||||
#include "rpc/virnetserverclient.h"
|
#include "rpc/virnetserverclient.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2010-2014 Red Hat, Inc.
|
* Copyright (C) 2010-2015 Red Hat, Inc.
|
||||||
* Copyright IBM Corp. 2008
|
* Copyright IBM Corp. 2008
|
||||||
*
|
*
|
||||||
* lxc_controller.c: linux container process controller
|
* lxc_controller.c: linux container process controller
|
||||||
@ -65,7 +65,7 @@
|
|||||||
#include "virprocess.h"
|
#include "virprocess.h"
|
||||||
#include "virnuma.h"
|
#include "virnuma.h"
|
||||||
#include "virdbus.h"
|
#include "virdbus.h"
|
||||||
#include "rpc/virnetserver.h"
|
#include "rpc/virnetdaemon.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_LXC
|
#define VIR_FROM_THIS VIR_FROM_LXC
|
||||||
@ -93,7 +93,7 @@ struct _virLXCControllerConsole {
|
|||||||
size_t fromContLen;
|
size_t fromContLen;
|
||||||
char fromContBuf[1024];
|
char fromContBuf[1024];
|
||||||
|
|
||||||
virNetServerPtr server;
|
virNetDaemonPtr daemon;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _virLXCController virLXCController;
|
typedef struct _virLXCController virLXCController;
|
||||||
@ -128,8 +128,7 @@ struct _virLXCController {
|
|||||||
|
|
||||||
virSecurityManagerPtr securityManager;
|
virSecurityManagerPtr securityManager;
|
||||||
|
|
||||||
/* Server socket */
|
virNetDaemonPtr daemon;
|
||||||
virNetServerPtr server;
|
|
||||||
bool firstClient;
|
bool firstClient;
|
||||||
virNetServerClientPtr client;
|
virNetServerClientPtr client;
|
||||||
virNetServerProgramPtr prog;
|
virNetServerProgramPtr prog;
|
||||||
@ -152,7 +151,7 @@ static void virLXCControllerQuitTimer(int timer ATTRIBUTE_UNUSED, void *opaque)
|
|||||||
virLXCControllerPtr ctrl = opaque;
|
virLXCControllerPtr ctrl = opaque;
|
||||||
|
|
||||||
VIR_DEBUG("Triggering event loop quit");
|
VIR_DEBUG("Triggering event loop quit");
|
||||||
virNetServerQuit(ctrl->server);
|
virNetDaemonQuit(ctrl->daemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -283,7 +282,7 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl)
|
|||||||
if (ctrl->timerShutdown != -1)
|
if (ctrl->timerShutdown != -1)
|
||||||
virEventRemoveTimeout(ctrl->timerShutdown);
|
virEventRemoveTimeout(ctrl->timerShutdown);
|
||||||
|
|
||||||
virObjectUnref(ctrl->server);
|
virObjectUnref(ctrl->daemon);
|
||||||
virLXCControllerFreeFuse(ctrl);
|
virLXCControllerFreeFuse(ctrl);
|
||||||
|
|
||||||
VIR_FREE(ctrl->nbdpids);
|
VIR_FREE(ctrl->nbdpids);
|
||||||
@ -301,7 +300,7 @@ static int virLXCControllerAddConsole(virLXCControllerPtr ctrl,
|
|||||||
{
|
{
|
||||||
if (VIR_EXPAND_N(ctrl->consoles, ctrl->nconsoles, 1) < 0)
|
if (VIR_EXPAND_N(ctrl->consoles, ctrl->nconsoles, 1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
ctrl->consoles[ctrl->nconsoles-1].server = ctrl->server;
|
ctrl->consoles[ctrl->nconsoles-1].daemon = ctrl->daemon;
|
||||||
ctrl->consoles[ctrl->nconsoles-1].hostFd = hostFd;
|
ctrl->consoles[ctrl->nconsoles-1].hostFd = hostFd;
|
||||||
ctrl->consoles[ctrl->nconsoles-1].hostWatch = -1;
|
ctrl->consoles[ctrl->nconsoles-1].hostWatch = -1;
|
||||||
|
|
||||||
@ -902,6 +901,7 @@ static void *virLXCControllerClientPrivateNew(virNetServerClientPtr client,
|
|||||||
|
|
||||||
static int virLXCControllerSetupServer(virLXCControllerPtr ctrl)
|
static int virLXCControllerSetupServer(virLXCControllerPtr ctrl)
|
||||||
{
|
{
|
||||||
|
virNetServerPtr srv = NULL;
|
||||||
virNetServerServicePtr svc = NULL;
|
virNetServerServicePtr svc = NULL;
|
||||||
char *sockpath;
|
char *sockpath;
|
||||||
|
|
||||||
@ -909,7 +909,7 @@ static int virLXCControllerSetupServer(virLXCControllerPtr ctrl)
|
|||||||
LXC_STATE_DIR, ctrl->name) < 0)
|
LXC_STATE_DIR, ctrl->name) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(ctrl->server = virNetServerNew(0, 0, 0, 1,
|
if (!(srv = virNetServerNew(0, 0, 0, 1,
|
||||||
0, -1, 0, false,
|
0, -1, 0, false,
|
||||||
NULL,
|
NULL,
|
||||||
virLXCControllerClientPrivateNew,
|
virLXCControllerClientPrivateNew,
|
||||||
@ -936,7 +936,7 @@ static int virLXCControllerSetupServer(virLXCControllerPtr ctrl)
|
|||||||
if (virSecurityManagerClearSocketLabel(ctrl->securityManager, ctrl->def) < 0)
|
if (virSecurityManagerClearSocketLabel(ctrl->securityManager, ctrl->def) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (virNetServerAddService(ctrl->server, svc, NULL) < 0)
|
if (virNetServerAddService(srv, svc, NULL) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
virObjectUnref(svc);
|
virObjectUnref(svc);
|
||||||
svc = NULL;
|
svc = NULL;
|
||||||
@ -947,14 +947,19 @@ static int virLXCControllerSetupServer(virLXCControllerPtr ctrl)
|
|||||||
virLXCMonitorNProcs)))
|
virLXCMonitorNProcs)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
virNetServerUpdateServices(ctrl->server, true);
|
if (!(ctrl->daemon = virNetDaemonNew()) ||
|
||||||
|
virNetDaemonAddServer(ctrl->daemon, srv) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
virNetDaemonUpdateServices(ctrl->daemon, true);
|
||||||
VIR_FREE(sockpath);
|
VIR_FREE(sockpath);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
VIR_FREE(sockpath);
|
VIR_FREE(sockpath);
|
||||||
virObjectUnref(ctrl->server);
|
virObjectUnref(srv);
|
||||||
ctrl->server = NULL;
|
virObjectUnref(ctrl->daemon);
|
||||||
|
ctrl->daemon = NULL;
|
||||||
virObjectUnref(svc);
|
virObjectUnref(svc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -982,7 +987,7 @@ static bool wantReboot;
|
|||||||
static virMutex lock = VIR_MUTEX_INITIALIZER;
|
static virMutex lock = VIR_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
|
||||||
static void virLXCControllerSignalChildIO(virNetServerPtr server,
|
static void virLXCControllerSignalChildIO(virNetDaemonPtr daemon,
|
||||||
siginfo_t *info ATTRIBUTE_UNUSED,
|
siginfo_t *info ATTRIBUTE_UNUSED,
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
@ -993,7 +998,7 @@ static void virLXCControllerSignalChildIO(virNetServerPtr server,
|
|||||||
ret = waitpid(-1, &status, WNOHANG);
|
ret = waitpid(-1, &status, WNOHANG);
|
||||||
VIR_DEBUG("Got sig child %d vs %lld", ret, (unsigned long long)ctrl->initpid);
|
VIR_DEBUG("Got sig child %d vs %lld", ret, (unsigned long long)ctrl->initpid);
|
||||||
if (ret == ctrl->initpid) {
|
if (ret == ctrl->initpid) {
|
||||||
virNetServerQuit(server);
|
virNetDaemonQuit(daemon);
|
||||||
virMutexLock(&lock);
|
virMutexLock(&lock);
|
||||||
if (WIFSIGNALED(status) &&
|
if (WIFSIGNALED(status) &&
|
||||||
WTERMSIG(status) == SIGHUP) {
|
WTERMSIG(status) == SIGHUP) {
|
||||||
@ -1052,7 +1057,7 @@ static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr consol
|
|||||||
VIR_DEBUG(":fail");
|
VIR_DEBUG(":fail");
|
||||||
virReportSystemError(errno, "%s",
|
virReportSystemError(errno, "%s",
|
||||||
_("Unable to add epoll fd"));
|
_("Unable to add epoll fd"));
|
||||||
virNetServerQuit(console->server);
|
virNetDaemonQuit(console->daemon);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
console->hostEpoll = events;
|
console->hostEpoll = events;
|
||||||
@ -1064,7 +1069,7 @@ static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr consol
|
|||||||
virReportSystemError(errno, "%s",
|
virReportSystemError(errno, "%s",
|
||||||
_("Unable to remove epoll fd"));
|
_("Unable to remove epoll fd"));
|
||||||
VIR_DEBUG(":fail");
|
VIR_DEBUG(":fail");
|
||||||
virNetServerQuit(console->server);
|
virNetDaemonQuit(console->daemon);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
console->hostEpoll = 0;
|
console->hostEpoll = 0;
|
||||||
@ -1090,7 +1095,7 @@ static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr consol
|
|||||||
virReportSystemError(errno, "%s",
|
virReportSystemError(errno, "%s",
|
||||||
_("Unable to add epoll fd"));
|
_("Unable to add epoll fd"));
|
||||||
VIR_DEBUG(":fail");
|
VIR_DEBUG(":fail");
|
||||||
virNetServerQuit(console->server);
|
virNetDaemonQuit(console->daemon);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
console->contEpoll = events;
|
console->contEpoll = events;
|
||||||
@ -1102,7 +1107,7 @@ static void virLXCControllerConsoleUpdateWatch(virLXCControllerConsolePtr consol
|
|||||||
virReportSystemError(errno, "%s",
|
virReportSystemError(errno, "%s",
|
||||||
_("Unable to remove epoll fd"));
|
_("Unable to remove epoll fd"));
|
||||||
VIR_DEBUG(":fail");
|
VIR_DEBUG(":fail");
|
||||||
virNetServerQuit(console->server);
|
virNetDaemonQuit(console->daemon);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
console->contEpoll = 0;
|
console->contEpoll = 0;
|
||||||
@ -1131,7 +1136,7 @@ static void virLXCControllerConsoleEPoll(int watch, int fd, int events, void *op
|
|||||||
continue;
|
continue;
|
||||||
virReportSystemError(errno, "%s",
|
virReportSystemError(errno, "%s",
|
||||||
_("Unable to wait on epoll"));
|
_("Unable to wait on epoll"));
|
||||||
virNetServerQuit(console->server);
|
virNetDaemonQuit(console->daemon);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1244,7 +1249,7 @@ static void virLXCControllerConsoleIO(int watch, int fd, int events, void *opaqu
|
|||||||
virEventRemoveHandle(console->contWatch);
|
virEventRemoveHandle(console->contWatch);
|
||||||
virEventRemoveHandle(console->hostWatch);
|
virEventRemoveHandle(console->hostWatch);
|
||||||
console->contWatch = console->hostWatch = -1;
|
console->contWatch = console->hostWatch = -1;
|
||||||
virNetServerQuit(console->server);
|
virNetDaemonQuit(console->daemon);
|
||||||
virMutexUnlock(&lock);
|
virMutexUnlock(&lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1264,7 +1269,7 @@ static int virLXCControllerMain(virLXCControllerPtr ctrl)
|
|||||||
int rc = -1;
|
int rc = -1;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (virNetServerAddSignalHandler(ctrl->server,
|
if (virNetDaemonAddSignalHandler(ctrl->daemon,
|
||||||
SIGCHLD,
|
SIGCHLD,
|
||||||
virLXCControllerSignalChildIO,
|
virLXCControllerSignalChildIO,
|
||||||
ctrl) < 0)
|
ctrl) < 0)
|
||||||
@ -1310,7 +1315,7 @@ static int virLXCControllerMain(virLXCControllerPtr ctrl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virNetServerRun(ctrl->server);
|
virNetDaemonRun(ctrl->daemon);
|
||||||
|
|
||||||
err = virGetLastError();
|
err = virGetLastError();
|
||||||
if (!err || err->code == VIR_ERR_OK)
|
if (!err || err->code == VIR_ERR_OK)
|
||||||
@ -2284,7 +2289,7 @@ virLXCControllerEventSendExit(virLXCControllerPtr ctrl,
|
|||||||
VIR_DEBUG("Waiting for client to complete dispatch");
|
VIR_DEBUG("Waiting for client to complete dispatch");
|
||||||
ctrl->inShutdown = true;
|
ctrl->inShutdown = true;
|
||||||
virNetServerClientDelayedClose(ctrl->client);
|
virNetServerClientDelayedClose(ctrl->client);
|
||||||
virNetServerRun(ctrl->server);
|
virNetDaemonRun(ctrl->daemon);
|
||||||
}
|
}
|
||||||
VIR_DEBUG("Client has gone away");
|
VIR_DEBUG("Client has gone away");
|
||||||
return 0;
|
return 0;
|
||||||
|
749
src/rpc/virnetdaemon.c
Normal file
749
src/rpc/virnetdaemon.c
Normal file
@ -0,0 +1,749 @@
|
|||||||
|
/*
|
||||||
|
* virnetdaemon.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 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/>.
|
||||||
|
*
|
||||||
|
* Author: Martin Kletzander <mkletzan@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "virnetdaemon.h"
|
||||||
|
#include "virlog.h"
|
||||||
|
#include "viralloc.h"
|
||||||
|
#include "virerror.h"
|
||||||
|
#include "virthread.h"
|
||||||
|
#include "virthreadpool.h"
|
||||||
|
#include "virutil.h"
|
||||||
|
#include "virfile.h"
|
||||||
|
#include "virnetserver.h"
|
||||||
|
#include "virnetservermdns.h"
|
||||||
|
#include "virdbus.h"
|
||||||
|
#include "virstring.h"
|
||||||
|
#include "virsystemd.h"
|
||||||
|
|
||||||
|
#ifndef SA_SIGINFO
|
||||||
|
# define SA_SIGINFO 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define VIR_FROM_THIS VIR_FROM_RPC
|
||||||
|
|
||||||
|
VIR_LOG_INIT("rpc.netserver");
|
||||||
|
|
||||||
|
typedef struct _virNetDaemonSignal virNetDaemonSignal;
|
||||||
|
typedef virNetDaemonSignal *virNetDaemonSignalPtr;
|
||||||
|
|
||||||
|
struct _virNetDaemonSignal {
|
||||||
|
struct sigaction oldaction;
|
||||||
|
int signum;
|
||||||
|
virNetDaemonSignalFunc func;
|
||||||
|
void *opaque;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _virNetDaemon {
|
||||||
|
virObjectLockable parent;
|
||||||
|
|
||||||
|
bool privileged;
|
||||||
|
|
||||||
|
size_t nsignals;
|
||||||
|
virNetDaemonSignalPtr *signals;
|
||||||
|
int sigread;
|
||||||
|
int sigwrite;
|
||||||
|
int sigwatch;
|
||||||
|
|
||||||
|
size_t nservers;
|
||||||
|
virNetServerPtr *servers;
|
||||||
|
virJSONValuePtr srvObject;
|
||||||
|
|
||||||
|
bool quit;
|
||||||
|
|
||||||
|
unsigned int autoShutdownTimeout;
|
||||||
|
size_t autoShutdownInhibitions;
|
||||||
|
bool autoShutdownCallingInhibit;
|
||||||
|
int autoShutdownInhibitFd;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static virClassPtr virNetDaemonClass;
|
||||||
|
|
||||||
|
static void
|
||||||
|
virNetDaemonDispose(void *obj)
|
||||||
|
{
|
||||||
|
virNetDaemonPtr dmn = obj;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
VIR_FORCE_CLOSE(dmn->autoShutdownInhibitFd);
|
||||||
|
|
||||||
|
for (i = 0; i < dmn->nsignals; i++) {
|
||||||
|
sigaction(dmn->signals[i]->signum, &dmn->signals[i]->oldaction, NULL);
|
||||||
|
VIR_FREE(dmn->signals[i]);
|
||||||
|
}
|
||||||
|
VIR_FREE(dmn->signals);
|
||||||
|
VIR_FORCE_CLOSE(dmn->sigread);
|
||||||
|
VIR_FORCE_CLOSE(dmn->sigwrite);
|
||||||
|
if (dmn->sigwatch > 0)
|
||||||
|
virEventRemoveHandle(dmn->sigwatch);
|
||||||
|
|
||||||
|
for (i = 0; i < dmn->nservers; i++)
|
||||||
|
virObjectUnref(dmn->servers[i]);
|
||||||
|
VIR_FREE(dmn->servers);
|
||||||
|
|
||||||
|
virJSONValueFree(dmn->srvObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNetDaemonOnceInit(void)
|
||||||
|
{
|
||||||
|
if (!(virNetDaemonClass = virClassNew(virClassForObjectLockable(),
|
||||||
|
"virNetDaemon",
|
||||||
|
sizeof(virNetDaemon),
|
||||||
|
virNetDaemonDispose)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_ONCE_GLOBAL_INIT(virNetDaemon)
|
||||||
|
|
||||||
|
|
||||||
|
virNetDaemonPtr
|
||||||
|
virNetDaemonNew(void)
|
||||||
|
{
|
||||||
|
virNetDaemonPtr dmn;
|
||||||
|
struct sigaction sig_action;
|
||||||
|
|
||||||
|
if (virNetDaemonInitialize() < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(dmn = virObjectLockableNew(virNetDaemonClass)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dmn->sigwrite = dmn->sigread = -1;
|
||||||
|
dmn->privileged = geteuid() == 0;
|
||||||
|
dmn->autoShutdownInhibitFd = -1;
|
||||||
|
|
||||||
|
if (virEventRegisterDefaultImpl() < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
memset(&sig_action, 0, sizeof(sig_action));
|
||||||
|
sig_action.sa_handler = SIG_IGN;
|
||||||
|
sigaction(SIGPIPE, &sig_action, NULL);
|
||||||
|
|
||||||
|
return dmn;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virObjectUnref(dmn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetDaemonAddServer(virNetDaemonPtr dmn, virNetServerPtr srv)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
if (VIR_APPEND_ELEMENT(dmn->servers, dmn->nservers, srv) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
virObjectRef(srv);
|
||||||
|
ret = dmn->nservers - 1;
|
||||||
|
cleanup:
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Separate function merely for the purpose of unified error
|
||||||
|
* reporting.
|
||||||
|
*/
|
||||||
|
static virNetServerPtr
|
||||||
|
virNetDaemonGetServerInternal(virNetDaemonPtr dmn,
|
||||||
|
int subServerID)
|
||||||
|
{
|
||||||
|
if (subServerID < 0 || subServerID >= dmn->nservers) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG,
|
||||||
|
_("Invalid server ID: %d"),
|
||||||
|
subServerID);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return virObjectRef(dmn->servers[subServerID]);
|
||||||
|
}
|
||||||
|
|
||||||
|
virNetServerPtr
|
||||||
|
virNetDaemonGetServer(virNetDaemonPtr dmn,
|
||||||
|
int subServerID)
|
||||||
|
{
|
||||||
|
virNetServerPtr srv = NULL;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
srv = virNetDaemonGetServerInternal(dmn, subServerID);
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
|
||||||
|
return srv;
|
||||||
|
}
|
||||||
|
|
||||||
|
virNetServerPtr
|
||||||
|
virNetDaemonAddServerPostExec(virNetDaemonPtr dmn,
|
||||||
|
virNetServerClientPrivNew clientPrivNew,
|
||||||
|
virNetServerClientPrivNewPostExecRestart clientPrivNewPostExecRestart,
|
||||||
|
virNetServerClientPrivPreExecRestart clientPrivPreExecRestart,
|
||||||
|
virFreeCallback clientPrivFree,
|
||||||
|
void *clientPrivOpaque)
|
||||||
|
{
|
||||||
|
virJSONValuePtr object = NULL;
|
||||||
|
virNetServerPtr srv = NULL;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
if (!dmn->srvObject) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Cannot add more servers post-exec than "
|
||||||
|
"there were pre-exec"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virJSONValueIsArray(dmn->srvObject)) {
|
||||||
|
object = virJSONValueArraySteal(dmn->srvObject, 0);
|
||||||
|
if (virJSONValueArraySize(dmn->srvObject) == 0) {
|
||||||
|
virJSONValueFree(dmn->srvObject);
|
||||||
|
dmn->srvObject = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
object = dmn->srvObject;
|
||||||
|
dmn->srvObject = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
srv = virNetServerNewPostExecRestart(object,
|
||||||
|
clientPrivNew,
|
||||||
|
clientPrivNewPostExecRestart,
|
||||||
|
clientPrivPreExecRestart,
|
||||||
|
clientPrivFree,
|
||||||
|
clientPrivOpaque);
|
||||||
|
|
||||||
|
if (!srv || VIR_APPEND_ELEMENT_COPY(dmn->servers, dmn->nservers, srv) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
virJSONValueFree(object);
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
return srv;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
virObjectUnref(srv);
|
||||||
|
virJSONValueFree(object);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virNetDaemonPtr
|
||||||
|
virNetDaemonNewPostExecRestart(virJSONValuePtr object)
|
||||||
|
{
|
||||||
|
virNetDaemonPtr dmn = NULL;
|
||||||
|
virJSONValuePtr servers = virJSONValueObjectGet(object, "servers");
|
||||||
|
bool new_version = virJSONValueObjectHasKey(object, "servers");
|
||||||
|
|
||||||
|
if (!(dmn = virNetDaemonNew()))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (new_version && !servers) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Malformed servers data in JSON document"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dmn->srvObject = virJSONValueCopy(new_version ? servers : object)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return dmn;
|
||||||
|
error:
|
||||||
|
virObjectUnref(dmn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virJSONValuePtr
|
||||||
|
virNetDaemonPreExecRestart(virNetDaemonPtr dmn)
|
||||||
|
{
|
||||||
|
virJSONValuePtr object, srvArray = NULL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
if (!(object = virJSONValueNewObject()))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!(srvArray = virJSONValueNewArray()) ||
|
||||||
|
virJSONValueObjectAppend(object, "servers", srvArray) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
for (i = 0; i < dmn->nservers; i++) {
|
||||||
|
virJSONValuePtr srvJSON = NULL;
|
||||||
|
srvJSON = virNetServerPreExecRestart(dmn->servers[i]);
|
||||||
|
|
||||||
|
if (!srvJSON)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (virJSONValueArrayAppend(srvArray, srvJSON) < 0) {
|
||||||
|
virJSONValueFree(srvJSON);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
|
||||||
|
return object;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virJSONValueFree(object);
|
||||||
|
virJSONValueFree(srvArray);
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
virNetDaemonIsPrivileged(virNetDaemonPtr dmn)
|
||||||
|
{
|
||||||
|
bool priv;
|
||||||
|
virObjectLock(dmn);
|
||||||
|
priv = dmn->privileged;
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
return priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
virNetDaemonAutoShutdown(virNetDaemonPtr dmn,
|
||||||
|
unsigned int timeout)
|
||||||
|
{
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
dmn->autoShutdownTimeout = timeout;
|
||||||
|
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(HAVE_DBUS) && defined(DBUS_TYPE_UNIX_FD)
|
||||||
|
static void
|
||||||
|
virNetDaemonGotInhibitReply(DBusPendingCall *pending,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virNetDaemonPtr dmn = opaque;
|
||||||
|
DBusMessage *reply;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
dmn->autoShutdownCallingInhibit = false;
|
||||||
|
|
||||||
|
VIR_DEBUG("dmn=%p", dmn);
|
||||||
|
|
||||||
|
reply = dbus_pending_call_steal_reply(pending);
|
||||||
|
if (reply == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (dbus_message_get_args(reply, NULL,
|
||||||
|
DBUS_TYPE_UNIX_FD, &fd,
|
||||||
|
DBUS_TYPE_INVALID)) {
|
||||||
|
if (dmn->autoShutdownInhibitions) {
|
||||||
|
dmn->autoShutdownInhibitFd = fd;
|
||||||
|
} else {
|
||||||
|
/* We stopped the last VM since we made the inhibit call */
|
||||||
|
VIR_FORCE_CLOSE(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbus_message_unref(reply);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* As per: http://www.freedesktop.org/wiki/Software/systemd/inhibit */
|
||||||
|
static void
|
||||||
|
virNetDaemonCallInhibit(virNetDaemonPtr dmn,
|
||||||
|
const char *what,
|
||||||
|
const char *who,
|
||||||
|
const char *why,
|
||||||
|
const char *mode)
|
||||||
|
{
|
||||||
|
DBusMessage *message;
|
||||||
|
DBusPendingCall *pendingReply;
|
||||||
|
DBusConnection *systemBus;
|
||||||
|
|
||||||
|
VIR_DEBUG("dmn=%p what=%s who=%s why=%s mode=%s",
|
||||||
|
dmn, NULLSTR(what), NULLSTR(who), NULLSTR(why), NULLSTR(mode));
|
||||||
|
|
||||||
|
if (!(systemBus = virDBusGetSystemBus()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Only one outstanding call at a time */
|
||||||
|
if (dmn->autoShutdownCallingInhibit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
message = dbus_message_new_method_call("org.freedesktop.login1",
|
||||||
|
"/org/freedesktop/login1",
|
||||||
|
"org.freedesktop.login1.Manager",
|
||||||
|
"Inhibit");
|
||||||
|
if (message == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dbus_message_append_args(message,
|
||||||
|
DBUS_TYPE_STRING, &what,
|
||||||
|
DBUS_TYPE_STRING, &who,
|
||||||
|
DBUS_TYPE_STRING, &why,
|
||||||
|
DBUS_TYPE_STRING, &mode,
|
||||||
|
DBUS_TYPE_INVALID);
|
||||||
|
|
||||||
|
pendingReply = NULL;
|
||||||
|
if (dbus_connection_send_with_reply(systemBus, message,
|
||||||
|
&pendingReply,
|
||||||
|
25*1000)) {
|
||||||
|
dbus_pending_call_set_notify(pendingReply,
|
||||||
|
virNetDaemonGotInhibitReply,
|
||||||
|
dmn, NULL);
|
||||||
|
dmn->autoShutdownCallingInhibit = true;
|
||||||
|
}
|
||||||
|
dbus_message_unref(message);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
virNetDaemonAddShutdownInhibition(virNetDaemonPtr dmn)
|
||||||
|
{
|
||||||
|
virObjectLock(dmn);
|
||||||
|
dmn->autoShutdownInhibitions++;
|
||||||
|
|
||||||
|
VIR_DEBUG("dmn=%p inhibitions=%zu", dmn, dmn->autoShutdownInhibitions);
|
||||||
|
|
||||||
|
#if defined(HAVE_DBUS) && defined(DBUS_TYPE_UNIX_FD)
|
||||||
|
if (dmn->autoShutdownInhibitions == 1)
|
||||||
|
virNetDaemonCallInhibit(dmn,
|
||||||
|
"shutdown",
|
||||||
|
_("Libvirt"),
|
||||||
|
_("Virtual machines need to be saved"),
|
||||||
|
"delay");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
virNetDaemonRemoveShutdownInhibition(virNetDaemonPtr dmn)
|
||||||
|
{
|
||||||
|
virObjectLock(dmn);
|
||||||
|
dmn->autoShutdownInhibitions--;
|
||||||
|
|
||||||
|
VIR_DEBUG("dmn=%p inhibitions=%zu", dmn, dmn->autoShutdownInhibitions);
|
||||||
|
|
||||||
|
if (dmn->autoShutdownInhibitions == 0)
|
||||||
|
VIR_FORCE_CLOSE(dmn->autoShutdownInhibitFd);
|
||||||
|
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static sig_atomic_t sigErrors;
|
||||||
|
static int sigLastErrno;
|
||||||
|
static int sigWrite = -1;
|
||||||
|
|
||||||
|
static void
|
||||||
|
virNetDaemonSignalHandler(int sig, siginfo_t * siginfo,
|
||||||
|
void* context ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
int origerrno;
|
||||||
|
int r;
|
||||||
|
siginfo_t tmp;
|
||||||
|
|
||||||
|
if (SA_SIGINFO)
|
||||||
|
tmp = *siginfo;
|
||||||
|
else
|
||||||
|
memset(&tmp, 0, sizeof(tmp));
|
||||||
|
|
||||||
|
/* set the sig num in the struct */
|
||||||
|
tmp.si_signo = sig;
|
||||||
|
|
||||||
|
origerrno = errno;
|
||||||
|
r = safewrite(sigWrite, &tmp, sizeof(tmp));
|
||||||
|
if (r == -1) {
|
||||||
|
sigErrors++;
|
||||||
|
sigLastErrno = errno;
|
||||||
|
}
|
||||||
|
errno = origerrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
virNetDaemonSignalEvent(int watch,
|
||||||
|
int fd ATTRIBUTE_UNUSED,
|
||||||
|
int events ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virNetDaemonPtr dmn = opaque;
|
||||||
|
siginfo_t siginfo;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
if (saferead(dmn->sigread, &siginfo, sizeof(siginfo)) != sizeof(siginfo)) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Failed to read from signal pipe"));
|
||||||
|
virEventRemoveHandle(watch);
|
||||||
|
dmn->sigwatch = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < dmn->nsignals; i++) {
|
||||||
|
if (siginfo.si_signo == dmn->signals[i]->signum) {
|
||||||
|
virNetDaemonSignalFunc func = dmn->signals[i]->func;
|
||||||
|
void *funcopaque = dmn->signals[i]->opaque;
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
func(dmn, &siginfo, funcopaque);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unexpected signal received: %d"), siginfo.si_signo);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virNetDaemonSignalSetup(virNetDaemonPtr dmn)
|
||||||
|
{
|
||||||
|
int fds[2] = { -1, -1 };
|
||||||
|
|
||||||
|
if (dmn->sigwrite != -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (pipe2(fds, O_CLOEXEC|O_NONBLOCK) < 0) {
|
||||||
|
virReportSystemError(errno, "%s",
|
||||||
|
_("Unable to create signal pipe"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dmn->sigwatch = virEventAddHandle(fds[0],
|
||||||
|
VIR_EVENT_HANDLE_READABLE,
|
||||||
|
virNetDaemonSignalEvent,
|
||||||
|
dmn, NULL)) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Failed to add signal handle watch"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
dmn->sigread = fds[0];
|
||||||
|
dmn->sigwrite = fds[1];
|
||||||
|
sigWrite = fds[1];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
VIR_FORCE_CLOSE(fds[0]);
|
||||||
|
VIR_FORCE_CLOSE(fds[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetDaemonAddSignalHandler(virNetDaemonPtr dmn,
|
||||||
|
int signum,
|
||||||
|
virNetDaemonSignalFunc func,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virNetDaemonSignalPtr sigdata = NULL;
|
||||||
|
struct sigaction sig_action;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
if (virNetDaemonSignalSetup(dmn) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (VIR_EXPAND_N(dmn->signals, dmn->nsignals, 1) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(sigdata) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
sigdata->signum = signum;
|
||||||
|
sigdata->func = func;
|
||||||
|
sigdata->opaque = opaque;
|
||||||
|
|
||||||
|
memset(&sig_action, 0, sizeof(sig_action));
|
||||||
|
sig_action.sa_sigaction = virNetDaemonSignalHandler;
|
||||||
|
sig_action.sa_flags = SA_SIGINFO;
|
||||||
|
sigemptyset(&sig_action.sa_mask);
|
||||||
|
|
||||||
|
sigaction(signum, &sig_action, &sigdata->oldaction);
|
||||||
|
|
||||||
|
dmn->signals[dmn->nsignals-1] = sigdata;
|
||||||
|
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
VIR_FREE(sigdata);
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virNetDaemonAutoShutdownTimer(int timerid ATTRIBUTE_UNUSED,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
virNetDaemonPtr dmn = opaque;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
if (!dmn->autoShutdownInhibitions) {
|
||||||
|
VIR_DEBUG("Automatic shutdown triggered");
|
||||||
|
dmn->quit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
virNetDaemonUpdateServices(virNetDaemonPtr dmn,
|
||||||
|
bool enabled)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
for (i = 0; i < dmn->nservers; i++)
|
||||||
|
virNetServerUpdateServices(dmn->servers[i], enabled);
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
virNetDaemonRun(virNetDaemonPtr dmn)
|
||||||
|
{
|
||||||
|
int timerid = -1;
|
||||||
|
bool timerActive = false;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
if (dmn->srvObject) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Not all servers restored, cannot run server"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < dmn->nservers; i++) {
|
||||||
|
if (virNetServerStart(dmn->servers[i]) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
dmn->quit = false;
|
||||||
|
|
||||||
|
if (dmn->autoShutdownTimeout &&
|
||||||
|
(timerid = virEventAddTimeout(-1,
|
||||||
|
virNetDaemonAutoShutdownTimer,
|
||||||
|
dmn, NULL)) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Failed to register shutdown timeout"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We are accepting connections now. Notify systemd
|
||||||
|
* so it can start dependent services. */
|
||||||
|
virSystemdNotifyStartup();
|
||||||
|
|
||||||
|
VIR_DEBUG("dmn=%p quit=%d", dmn, dmn->quit);
|
||||||
|
while (!dmn->quit) {
|
||||||
|
/* A shutdown timeout is specified, so check
|
||||||
|
* if any drivers have active state, if not
|
||||||
|
* shutdown after timeout seconds
|
||||||
|
*/
|
||||||
|
if (dmn->autoShutdownTimeout) {
|
||||||
|
if (timerActive) {
|
||||||
|
for (i = 0; i < dmn->nservers; i++) {
|
||||||
|
if (virNetServerHasClients(dmn->servers[i])) {
|
||||||
|
VIR_DEBUG("Deactivating shutdown timer %d", timerid);
|
||||||
|
virEventUpdateTimeout(timerid, -1);
|
||||||
|
timerActive = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < dmn->nservers; i++) {
|
||||||
|
if (!virNetServerHasClients(dmn->servers[i])) {
|
||||||
|
VIR_DEBUG("Activating shutdown timer %d", timerid);
|
||||||
|
virEventUpdateTimeout(timerid,
|
||||||
|
dmn->autoShutdownTimeout * 1000);
|
||||||
|
timerActive = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
if (virEventRunDefaultImpl() < 0) {
|
||||||
|
virObjectLock(dmn);
|
||||||
|
VIR_DEBUG("Loop iteration error, exiting");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
for (i = 0; i < dmn->nservers; i++)
|
||||||
|
virNetServerProcessClients(dmn->servers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
virNetDaemonQuit(virNetDaemonPtr dmn)
|
||||||
|
{
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
VIR_DEBUG("Quit requested %p", dmn);
|
||||||
|
dmn->quit = true;
|
||||||
|
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
virNetDaemonClose(virNetDaemonPtr dmn)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!dmn)
|
||||||
|
return;
|
||||||
|
|
||||||
|
virObjectLock(dmn);
|
||||||
|
|
||||||
|
for (i = 0; i < dmn->nservers; i++)
|
||||||
|
virNetServerClose(dmn->servers[i]);
|
||||||
|
|
||||||
|
virObjectUnlock(dmn);
|
||||||
|
}
|
82
src/rpc/virnetdaemon.h
Normal file
82
src/rpc/virnetdaemon.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* virnetdaemon.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 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/>.
|
||||||
|
*
|
||||||
|
* Author: Martin Kletzander <mkletzan@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __VIR_NET_DAEMON_H__
|
||||||
|
# define __VIR_NET_DAEMON_H__
|
||||||
|
|
||||||
|
# include <signal.h>
|
||||||
|
|
||||||
|
# ifdef WITH_GNUTLS
|
||||||
|
# include "virnettlscontext.h"
|
||||||
|
# endif
|
||||||
|
# include "virobject.h"
|
||||||
|
# include "virjson.h"
|
||||||
|
# include "virnetserverprogram.h"
|
||||||
|
# include "virnetserverclient.h"
|
||||||
|
# include "virnetserverservice.h"
|
||||||
|
# include "virnetserver.h"
|
||||||
|
|
||||||
|
virNetDaemonPtr virNetDaemonNew(void);
|
||||||
|
|
||||||
|
int virNetDaemonAddServer(virNetDaemonPtr dmn, virNetServerPtr);
|
||||||
|
|
||||||
|
virNetServerPtr virNetDaemonAddServerPostExec(virNetDaemonPtr dmn,
|
||||||
|
virNetServerClientPrivNew clientPrivNew,
|
||||||
|
virNetServerClientPrivNewPostExecRestart clientPrivNewPostExecRestart,
|
||||||
|
virNetServerClientPrivPreExecRestart clientPrivPreExecRestart,
|
||||||
|
virFreeCallback clientPrivFree,
|
||||||
|
void *clientPrivOpaque);
|
||||||
|
|
||||||
|
virNetDaemonPtr virNetDaemonNewPostExecRestart(virJSONValuePtr object);
|
||||||
|
|
||||||
|
virJSONValuePtr virNetDaemonPreExecRestart(virNetDaemonPtr dmn);
|
||||||
|
|
||||||
|
typedef int (*virNetDaemonAutoShutdownFunc)(virNetDaemonPtr dmn, void *opaque);
|
||||||
|
|
||||||
|
bool virNetDaemonIsPrivileged(virNetDaemonPtr dmn);
|
||||||
|
|
||||||
|
void virNetDaemonAutoShutdown(virNetDaemonPtr dmn,
|
||||||
|
unsigned int timeout);
|
||||||
|
|
||||||
|
void virNetDaemonAddShutdownInhibition(virNetDaemonPtr dmn);
|
||||||
|
void virNetDaemonRemoveShutdownInhibition(virNetDaemonPtr dmn);
|
||||||
|
|
||||||
|
typedef void (*virNetDaemonSignalFunc)(virNetDaemonPtr dmn, siginfo_t *info, void *opaque);
|
||||||
|
|
||||||
|
int virNetDaemonAddSignalHandler(virNetDaemonPtr dmn,
|
||||||
|
int signum,
|
||||||
|
virNetDaemonSignalFunc func,
|
||||||
|
void *opaque);
|
||||||
|
|
||||||
|
void virNetDaemonUpdateServices(virNetDaemonPtr dmn,
|
||||||
|
bool enabled);
|
||||||
|
|
||||||
|
void virNetDaemonRun(virNetDaemonPtr dmn);
|
||||||
|
|
||||||
|
void virNetDaemonQuit(virNetDaemonPtr dmn);
|
||||||
|
|
||||||
|
void virNetDaemonClose(virNetDaemonPtr dmn);
|
||||||
|
|
||||||
|
virNetServerPtr virNetDaemonGetServer(virNetDaemonPtr dmn,
|
||||||
|
int subServerID);
|
||||||
|
|
||||||
|
#endif /* __VIR_NET_DAEMON_H__ */
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* virnetserver.c: generic network RPC server
|
* virnetserver.c: generic network RPC server
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2012, 2014 Red Hat, Inc.
|
* Copyright (C) 2006-2015 Red Hat, Inc.
|
||||||
* Copyright (C) 2006 Daniel P. Berrange
|
* Copyright (C) 2006 Daniel P. Berrange
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -23,40 +23,19 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "virnetserver.h"
|
#include "virnetserver.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
#include "virthread.h"
|
#include "virthread.h"
|
||||||
#include "virthreadpool.h"
|
#include "virthreadpool.h"
|
||||||
#include "virutil.h"
|
|
||||||
#include "virfile.h"
|
|
||||||
#include "virnetservermdns.h"
|
#include "virnetservermdns.h"
|
||||||
#include "virdbus.h"
|
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
#include "virsystemd.h"
|
|
||||||
|
|
||||||
#ifndef SA_SIGINFO
|
|
||||||
# define SA_SIGINFO 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_RPC
|
#define VIR_FROM_THIS VIR_FROM_RPC
|
||||||
|
|
||||||
VIR_LOG_INIT("rpc.netserver");
|
VIR_LOG_INIT("rpc.netserver");
|
||||||
|
|
||||||
typedef struct _virNetServerSignal virNetServerSignal;
|
|
||||||
typedef virNetServerSignal *virNetServerSignalPtr;
|
|
||||||
|
|
||||||
struct _virNetServerSignal {
|
|
||||||
struct sigaction oldaction;
|
|
||||||
int signum;
|
|
||||||
virNetServerSignalFunc func;
|
|
||||||
void *opaque;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _virNetServerJob virNetServerJob;
|
typedef struct _virNetServerJob virNetServerJob;
|
||||||
typedef virNetServerJob *virNetServerJobPtr;
|
typedef virNetServerJob *virNetServerJobPtr;
|
||||||
@ -72,14 +51,6 @@ struct _virNetServer {
|
|||||||
|
|
||||||
virThreadPoolPtr workers;
|
virThreadPoolPtr workers;
|
||||||
|
|
||||||
bool privileged;
|
|
||||||
|
|
||||||
size_t nsignals;
|
|
||||||
virNetServerSignalPtr *signals;
|
|
||||||
int sigread;
|
|
||||||
int sigwrite;
|
|
||||||
int sigwatch;
|
|
||||||
|
|
||||||
char *mdnsGroupName;
|
char *mdnsGroupName;
|
||||||
virNetServerMDNSPtr mdns;
|
virNetServerMDNSPtr mdns;
|
||||||
virNetServerMDNSGroupPtr mdnsGroup;
|
virNetServerMDNSGroupPtr mdnsGroup;
|
||||||
@ -100,17 +71,10 @@ struct _virNetServer {
|
|||||||
unsigned int keepaliveCount;
|
unsigned int keepaliveCount;
|
||||||
bool keepaliveRequired;
|
bool keepaliveRequired;
|
||||||
|
|
||||||
bool quit;
|
|
||||||
|
|
||||||
#ifdef WITH_GNUTLS
|
#ifdef WITH_GNUTLS
|
||||||
virNetTLSContextPtr tls;
|
virNetTLSContextPtr tls;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int autoShutdownTimeout;
|
|
||||||
size_t autoShutdownInhibitions;
|
|
||||||
bool autoShutdownCallingInhibit;
|
|
||||||
int autoShutdownInhibitFd;
|
|
||||||
|
|
||||||
virNetServerClientPrivNew clientPrivNew;
|
virNetServerClientPrivNew clientPrivNew;
|
||||||
virNetServerClientPrivPreExecRestart clientPrivPreExecRestart;
|
virNetServerClientPrivPreExecRestart clientPrivPreExecRestart;
|
||||||
virFreeCallback clientPrivFree;
|
virFreeCallback clientPrivFree;
|
||||||
@ -356,7 +320,6 @@ virNetServerPtr virNetServerNew(size_t min_workers,
|
|||||||
void *clientPrivOpaque)
|
void *clientPrivOpaque)
|
||||||
{
|
{
|
||||||
virNetServerPtr srv;
|
virNetServerPtr srv;
|
||||||
struct sigaction sig_action;
|
|
||||||
|
|
||||||
if (virNetServerInitialize() < 0)
|
if (virNetServerInitialize() < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -376,13 +339,10 @@ virNetServerPtr virNetServerNew(size_t min_workers,
|
|||||||
srv->keepaliveInterval = keepaliveInterval;
|
srv->keepaliveInterval = keepaliveInterval;
|
||||||
srv->keepaliveCount = keepaliveCount;
|
srv->keepaliveCount = keepaliveCount;
|
||||||
srv->keepaliveRequired = keepaliveRequired;
|
srv->keepaliveRequired = keepaliveRequired;
|
||||||
srv->sigwrite = srv->sigread = -1;
|
|
||||||
srv->clientPrivNew = clientPrivNew;
|
srv->clientPrivNew = clientPrivNew;
|
||||||
srv->clientPrivPreExecRestart = clientPrivPreExecRestart;
|
srv->clientPrivPreExecRestart = clientPrivPreExecRestart;
|
||||||
srv->clientPrivFree = clientPrivFree;
|
srv->clientPrivFree = clientPrivFree;
|
||||||
srv->clientPrivOpaque = clientPrivOpaque;
|
srv->clientPrivOpaque = clientPrivOpaque;
|
||||||
srv->privileged = geteuid() == 0;
|
|
||||||
srv->autoShutdownInhibitFd = -1;
|
|
||||||
|
|
||||||
if (VIR_STRDUP(srv->mdnsGroupName, mdnsGroupName) < 0)
|
if (VIR_STRDUP(srv->mdnsGroupName, mdnsGroupName) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -394,15 +354,7 @@ virNetServerPtr virNetServerNew(size_t min_workers,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virEventRegisterDefaultImpl() < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
memset(&sig_action, 0, sizeof(sig_action));
|
|
||||||
sig_action.sa_handler = SIG_IGN;
|
|
||||||
sigaction(SIGPIPE, &sig_action, NULL);
|
|
||||||
|
|
||||||
return srv;
|
return srv;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
virObjectUnref(srv);
|
virObjectUnref(srv);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -679,286 +631,6 @@ virJSONValuePtr virNetServerPreExecRestart(virNetServerPtr srv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool virNetServerIsPrivileged(virNetServerPtr srv)
|
|
||||||
{
|
|
||||||
bool priv;
|
|
||||||
virObjectLock(srv);
|
|
||||||
priv = srv->privileged;
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
return priv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void virNetServerAutoShutdown(virNetServerPtr srv,
|
|
||||||
unsigned int timeout)
|
|
||||||
{
|
|
||||||
virObjectLock(srv);
|
|
||||||
|
|
||||||
srv->autoShutdownTimeout = timeout;
|
|
||||||
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_DBUS) && defined(DBUS_TYPE_UNIX_FD)
|
|
||||||
static void virNetServerGotInhibitReply(DBusPendingCall *pending,
|
|
||||||
void *opaque)
|
|
||||||
{
|
|
||||||
virNetServerPtr srv = opaque;
|
|
||||||
DBusMessage *reply;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
virObjectLock(srv);
|
|
||||||
srv->autoShutdownCallingInhibit = false;
|
|
||||||
|
|
||||||
VIR_DEBUG("srv=%p", srv);
|
|
||||||
|
|
||||||
reply = dbus_pending_call_steal_reply(pending);
|
|
||||||
if (reply == NULL)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (dbus_message_get_args(reply, NULL,
|
|
||||||
DBUS_TYPE_UNIX_FD, &fd,
|
|
||||||
DBUS_TYPE_INVALID)) {
|
|
||||||
if (srv->autoShutdownInhibitions) {
|
|
||||||
srv->autoShutdownInhibitFd = fd;
|
|
||||||
} else {
|
|
||||||
/* We stopped the last VM since we made the inhibit call */
|
|
||||||
VIR_FORCE_CLOSE(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbus_message_unref(reply);
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* As per: http://www.freedesktop.org/wiki/Software/systemd/inhibit */
|
|
||||||
static void virNetServerCallInhibit(virNetServerPtr srv,
|
|
||||||
const char *what,
|
|
||||||
const char *who,
|
|
||||||
const char *why,
|
|
||||||
const char *mode)
|
|
||||||
{
|
|
||||||
DBusMessage *message;
|
|
||||||
DBusPendingCall *pendingReply;
|
|
||||||
DBusConnection *systemBus;
|
|
||||||
|
|
||||||
VIR_DEBUG("srv=%p what=%s who=%s why=%s mode=%s",
|
|
||||||
srv, NULLSTR(what), NULLSTR(who), NULLSTR(why), NULLSTR(mode));
|
|
||||||
|
|
||||||
if (!(systemBus = virDBusGetSystemBus()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Only one outstanding call at a time */
|
|
||||||
if (srv->autoShutdownCallingInhibit)
|
|
||||||
return;
|
|
||||||
|
|
||||||
message = dbus_message_new_method_call("org.freedesktop.login1",
|
|
||||||
"/org/freedesktop/login1",
|
|
||||||
"org.freedesktop.login1.Manager",
|
|
||||||
"Inhibit");
|
|
||||||
if (message == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dbus_message_append_args(message,
|
|
||||||
DBUS_TYPE_STRING, &what,
|
|
||||||
DBUS_TYPE_STRING, &who,
|
|
||||||
DBUS_TYPE_STRING, &why,
|
|
||||||
DBUS_TYPE_STRING, &mode,
|
|
||||||
DBUS_TYPE_INVALID);
|
|
||||||
|
|
||||||
pendingReply = NULL;
|
|
||||||
if (dbus_connection_send_with_reply(systemBus, message,
|
|
||||||
&pendingReply,
|
|
||||||
25*1000)) {
|
|
||||||
dbus_pending_call_set_notify(pendingReply,
|
|
||||||
virNetServerGotInhibitReply,
|
|
||||||
srv, NULL);
|
|
||||||
srv->autoShutdownCallingInhibit = true;
|
|
||||||
}
|
|
||||||
dbus_message_unref(message);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void virNetServerAddShutdownInhibition(virNetServerPtr srv)
|
|
||||||
{
|
|
||||||
virObjectLock(srv);
|
|
||||||
srv->autoShutdownInhibitions++;
|
|
||||||
|
|
||||||
VIR_DEBUG("srv=%p inhibitions=%zu", srv, srv->autoShutdownInhibitions);
|
|
||||||
|
|
||||||
#if defined(HAVE_DBUS) && defined(DBUS_TYPE_UNIX_FD)
|
|
||||||
if (srv->autoShutdownInhibitions == 1)
|
|
||||||
virNetServerCallInhibit(srv,
|
|
||||||
"shutdown",
|
|
||||||
_("Libvirt"),
|
|
||||||
_("Virtual machines need to be saved"),
|
|
||||||
"delay");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void virNetServerRemoveShutdownInhibition(virNetServerPtr srv)
|
|
||||||
{
|
|
||||||
virObjectLock(srv);
|
|
||||||
srv->autoShutdownInhibitions--;
|
|
||||||
|
|
||||||
VIR_DEBUG("srv=%p inhibitions=%zu", srv, srv->autoShutdownInhibitions);
|
|
||||||
|
|
||||||
if (srv->autoShutdownInhibitions == 0)
|
|
||||||
VIR_FORCE_CLOSE(srv->autoShutdownInhibitFd);
|
|
||||||
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static sig_atomic_t sigErrors;
|
|
||||||
static int sigLastErrno;
|
|
||||||
static int sigWrite = -1;
|
|
||||||
|
|
||||||
static void
|
|
||||||
virNetServerSignalHandler(int sig, siginfo_t * siginfo,
|
|
||||||
void* context ATTRIBUTE_UNUSED)
|
|
||||||
{
|
|
||||||
int origerrno;
|
|
||||||
int r;
|
|
||||||
siginfo_t tmp;
|
|
||||||
|
|
||||||
if (SA_SIGINFO)
|
|
||||||
tmp = *siginfo;
|
|
||||||
else
|
|
||||||
memset(&tmp, 0, sizeof(tmp));
|
|
||||||
|
|
||||||
/* set the sig num in the struct */
|
|
||||||
tmp.si_signo = sig;
|
|
||||||
|
|
||||||
origerrno = errno;
|
|
||||||
r = safewrite(sigWrite, &tmp, sizeof(tmp));
|
|
||||||
if (r == -1) {
|
|
||||||
sigErrors++;
|
|
||||||
sigLastErrno = errno;
|
|
||||||
}
|
|
||||||
errno = origerrno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
virNetServerSignalEvent(int watch,
|
|
||||||
int fd ATTRIBUTE_UNUSED,
|
|
||||||
int events ATTRIBUTE_UNUSED,
|
|
||||||
void *opaque)
|
|
||||||
{
|
|
||||||
virNetServerPtr srv = opaque;
|
|
||||||
siginfo_t siginfo;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
virObjectLock(srv);
|
|
||||||
|
|
||||||
if (saferead(srv->sigread, &siginfo, sizeof(siginfo)) != sizeof(siginfo)) {
|
|
||||||
virReportSystemError(errno, "%s",
|
|
||||||
_("Failed to read from signal pipe"));
|
|
||||||
virEventRemoveHandle(watch);
|
|
||||||
srv->sigwatch = -1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < srv->nsignals; i++) {
|
|
||||||
if (siginfo.si_signo == srv->signals[i]->signum) {
|
|
||||||
virNetServerSignalFunc func = srv->signals[i]->func;
|
|
||||||
void *funcopaque = srv->signals[i]->opaque;
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
func(srv, &siginfo, funcopaque);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Unexpected signal received: %d"), siginfo.si_signo);
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int virNetServerSignalSetup(virNetServerPtr srv)
|
|
||||||
{
|
|
||||||
int fds[2] = { -1, -1 };
|
|
||||||
|
|
||||||
if (srv->sigwrite != -1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (pipe2(fds, O_CLOEXEC|O_NONBLOCK) < 0) {
|
|
||||||
virReportSystemError(errno, "%s",
|
|
||||||
_("Unable to create signal pipe"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((srv->sigwatch = virEventAddHandle(fds[0],
|
|
||||||
VIR_EVENT_HANDLE_READABLE,
|
|
||||||
virNetServerSignalEvent,
|
|
||||||
srv, NULL)) < 0) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("Failed to add signal handle watch"));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
srv->sigread = fds[0];
|
|
||||||
srv->sigwrite = fds[1];
|
|
||||||
sigWrite = fds[1];
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
VIR_FORCE_CLOSE(fds[0]);
|
|
||||||
VIR_FORCE_CLOSE(fds[1]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int virNetServerAddSignalHandler(virNetServerPtr srv,
|
|
||||||
int signum,
|
|
||||||
virNetServerSignalFunc func,
|
|
||||||
void *opaque)
|
|
||||||
{
|
|
||||||
virNetServerSignalPtr sigdata = NULL;
|
|
||||||
struct sigaction sig_action;
|
|
||||||
|
|
||||||
virObjectLock(srv);
|
|
||||||
|
|
||||||
if (virNetServerSignalSetup(srv) < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (VIR_EXPAND_N(srv->signals, srv->nsignals, 1) < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (VIR_ALLOC(sigdata) < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
sigdata->signum = signum;
|
|
||||||
sigdata->func = func;
|
|
||||||
sigdata->opaque = opaque;
|
|
||||||
|
|
||||||
memset(&sig_action, 0, sizeof(sig_action));
|
|
||||||
sig_action.sa_sigaction = virNetServerSignalHandler;
|
|
||||||
sig_action.sa_flags = SA_SIGINFO;
|
|
||||||
sigemptyset(&sig_action.sa_mask);
|
|
||||||
|
|
||||||
sigaction(signum, &sig_action, &sigdata->oldaction);
|
|
||||||
|
|
||||||
srv->signals[srv->nsignals-1] = sigdata;
|
|
||||||
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
|
||||||
VIR_FREE(sigdata);
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int virNetServerAddService(virNetServerPtr srv,
|
int virNetServerAddService(virNetServerPtr srv,
|
||||||
virNetServerServicePtr svc,
|
virNetServerServicePtr svc,
|
||||||
@ -1023,22 +695,6 @@ int virNetServerSetTLSContext(virNetServerPtr srv,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void virNetServerAutoShutdownTimer(int timerid ATTRIBUTE_UNUSED,
|
|
||||||
void *opaque)
|
|
||||||
{
|
|
||||||
virNetServerPtr srv = opaque;
|
|
||||||
|
|
||||||
virObjectLock(srv);
|
|
||||||
|
|
||||||
if (!srv->autoShutdownInhibitions) {
|
|
||||||
VIR_DEBUG("Automatic shutdown triggered");
|
|
||||||
srv->quit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virNetServerUpdateServicesLocked(virNetServerPtr srv,
|
virNetServerUpdateServicesLocked(virNetServerPtr srv,
|
||||||
bool enabled)
|
bool enabled)
|
||||||
@ -1087,127 +743,16 @@ virNetServerCheckLimits(virNetServerPtr srv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void virNetServerRun(virNetServerPtr srv)
|
|
||||||
{
|
|
||||||
int timerid = -1;
|
|
||||||
bool timerActive = false;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
virObjectLock(srv);
|
|
||||||
|
|
||||||
if (srv->mdns &&
|
|
||||||
virNetServerMDNSStart(srv->mdns) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
srv->quit = false;
|
|
||||||
|
|
||||||
if (srv->autoShutdownTimeout &&
|
|
||||||
(timerid = virEventAddTimeout(-1,
|
|
||||||
virNetServerAutoShutdownTimer,
|
|
||||||
srv, NULL)) < 0) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("Failed to register shutdown timeout"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We are accepting connections now. Notify systemd
|
|
||||||
* so it can start dependent services. */
|
|
||||||
virSystemdNotifyStartup();
|
|
||||||
|
|
||||||
VIR_DEBUG("srv=%p quit=%d", srv, srv->quit);
|
|
||||||
while (!srv->quit) {
|
|
||||||
/* A shutdown timeout is specified, so check
|
|
||||||
* if any drivers have active state, if not
|
|
||||||
* shutdown after timeout seconds
|
|
||||||
*/
|
|
||||||
if (srv->autoShutdownTimeout) {
|
|
||||||
if (timerActive) {
|
|
||||||
if (srv->clients) {
|
|
||||||
VIR_DEBUG("Deactivating shutdown timer %d", timerid);
|
|
||||||
virEventUpdateTimeout(timerid, -1);
|
|
||||||
timerActive = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!srv->clients) {
|
|
||||||
VIR_DEBUG("Activating shutdown timer %d", timerid);
|
|
||||||
virEventUpdateTimeout(timerid,
|
|
||||||
srv->autoShutdownTimeout * 1000);
|
|
||||||
timerActive = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
if (virEventRunDefaultImpl() < 0) {
|
|
||||||
virObjectLock(srv);
|
|
||||||
VIR_DEBUG("Loop iteration error, exiting");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
virObjectLock(srv);
|
|
||||||
|
|
||||||
reprocess:
|
|
||||||
for (i = 0; i < srv->nclients; i++) {
|
|
||||||
/* Coverity 5.3.0 couldn't see that srv->clients is non-NULL
|
|
||||||
* if srv->nclients is non-zero. */
|
|
||||||
sa_assert(srv->clients);
|
|
||||||
if (virNetServerClientWantClose(srv->clients[i]))
|
|
||||||
virNetServerClientClose(srv->clients[i]);
|
|
||||||
if (virNetServerClientIsClosed(srv->clients[i])) {
|
|
||||||
virNetServerClientPtr client = srv->clients[i];
|
|
||||||
|
|
||||||
VIR_DELETE_ELEMENT(srv->clients, i, srv->nclients);
|
|
||||||
|
|
||||||
if (virNetServerClientNeedAuth(client))
|
|
||||||
virNetServerTrackCompletedAuthLocked(srv);
|
|
||||||
|
|
||||||
virNetServerCheckLimits(srv);
|
|
||||||
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
virObjectUnref(client);
|
|
||||||
virObjectLock(srv);
|
|
||||||
|
|
||||||
goto reprocess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void virNetServerQuit(virNetServerPtr srv)
|
|
||||||
{
|
|
||||||
virObjectLock(srv);
|
|
||||||
|
|
||||||
VIR_DEBUG("Quit requested %p", srv);
|
|
||||||
srv->quit = true;
|
|
||||||
|
|
||||||
virObjectUnlock(srv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void virNetServerDispose(void *obj)
|
void virNetServerDispose(void *obj)
|
||||||
{
|
{
|
||||||
virNetServerPtr srv = obj;
|
virNetServerPtr srv = obj;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
VIR_FORCE_CLOSE(srv->autoShutdownInhibitFd);
|
|
||||||
|
|
||||||
for (i = 0; i < srv->nservices; i++)
|
for (i = 0; i < srv->nservices; i++)
|
||||||
virNetServerServiceToggle(srv->services[i], false);
|
virNetServerServiceToggle(srv->services[i], false);
|
||||||
|
|
||||||
virThreadPoolFree(srv->workers);
|
virThreadPoolFree(srv->workers);
|
||||||
|
|
||||||
for (i = 0; i < srv->nsignals; i++) {
|
|
||||||
sigaction(srv->signals[i]->signum, &srv->signals[i]->oldaction, NULL);
|
|
||||||
VIR_FREE(srv->signals[i]);
|
|
||||||
}
|
|
||||||
VIR_FREE(srv->signals);
|
|
||||||
VIR_FORCE_CLOSE(srv->sigread);
|
|
||||||
VIR_FORCE_CLOSE(srv->sigwrite);
|
|
||||||
if (srv->sigwatch > 0)
|
|
||||||
virEventRemoveHandle(srv->sigwatch);
|
|
||||||
|
|
||||||
for (i = 0; i < srv->nservices; i++)
|
for (i = 0; i < srv->nservices; i++)
|
||||||
virObjectUnref(srv->services[i]);
|
virObjectUnref(srv->services[i]);
|
||||||
VIR_FREE(srv->services);
|
VIR_FREE(srv->services);
|
||||||
@ -1280,3 +825,62 @@ size_t virNetServerTrackCompletedAuth(virNetServerPtr srv)
|
|||||||
virObjectUnlock(srv);
|
virObjectUnlock(srv);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
virNetServerHasClients(virNetServerPtr srv)
|
||||||
|
{
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
virObjectLock(srv);
|
||||||
|
ret = !!srv->nclients;
|
||||||
|
virObjectUnlock(srv);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
virNetServerProcessClients(virNetServerPtr srv)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
virObjectLock(srv);
|
||||||
|
|
||||||
|
reprocess:
|
||||||
|
for (i = 0; i < srv->nclients; i++) {
|
||||||
|
/* Coverity 5.3.0 couldn't see that srv->clients is non-NULL
|
||||||
|
* if srv->nclients is non-zero. */
|
||||||
|
sa_assert(srv->clients);
|
||||||
|
if (virNetServerClientWantClose(srv->clients[i]))
|
||||||
|
virNetServerClientClose(srv->clients[i]);
|
||||||
|
if (virNetServerClientIsClosed(srv->clients[i])) {
|
||||||
|
virNetServerClientPtr client = srv->clients[i];
|
||||||
|
|
||||||
|
VIR_DELETE_ELEMENT(srv->clients, i, srv->nclients);
|
||||||
|
|
||||||
|
if (virNetServerClientNeedAuth(client))
|
||||||
|
virNetServerTrackCompletedAuthLocked(srv);
|
||||||
|
|
||||||
|
virNetServerCheckLimits(srv);
|
||||||
|
|
||||||
|
virObjectUnlock(srv);
|
||||||
|
virObjectUnref(client);
|
||||||
|
virObjectLock(srv);
|
||||||
|
|
||||||
|
goto reprocess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virObjectUnlock(srv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virNetServerStart(virNetServerPtr srv)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Do whatever needs to be done before starting.
|
||||||
|
*/
|
||||||
|
if (!srv->mdns)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return virNetServerMDNSStart(srv->mdns);
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* virnetserver.h: generic network RPC server
|
* virnetserver.h: generic network RPC server
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2011 Red Hat, Inc.
|
* Copyright (C) 2006-2015 Red Hat, Inc.
|
||||||
* Copyright (C) 2006 Daniel P. Berrange
|
* Copyright (C) 2006 Daniel P. Berrange
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -24,8 +24,6 @@
|
|||||||
#ifndef __VIR_NET_SERVER_H__
|
#ifndef __VIR_NET_SERVER_H__
|
||||||
# define __VIR_NET_SERVER_H__
|
# define __VIR_NET_SERVER_H__
|
||||||
|
|
||||||
# include <signal.h>
|
|
||||||
|
|
||||||
# ifdef WITH_GNUTLS
|
# ifdef WITH_GNUTLS
|
||||||
# include "virnettlscontext.h"
|
# include "virnettlscontext.h"
|
||||||
# endif
|
# endif
|
||||||
@ -35,6 +33,9 @@
|
|||||||
# include "virobject.h"
|
# include "virobject.h"
|
||||||
# include "virjson.h"
|
# include "virjson.h"
|
||||||
|
|
||||||
|
typedef struct _virNetServer virNetServer;
|
||||||
|
typedef virNetServer *virNetServerPtr;
|
||||||
|
|
||||||
virNetServerPtr virNetServerNew(size_t min_workers,
|
virNetServerPtr virNetServerNew(size_t min_workers,
|
||||||
size_t max_workers,
|
size_t max_workers,
|
||||||
size_t priority_workers,
|
size_t priority_workers,
|
||||||
@ -56,25 +57,10 @@ virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object,
|
|||||||
virFreeCallback clientPrivFree,
|
virFreeCallback clientPrivFree,
|
||||||
void *clientPrivOpaque);
|
void *clientPrivOpaque);
|
||||||
|
|
||||||
|
void virNetServerClose(virNetServerPtr srv);
|
||||||
|
|
||||||
virJSONValuePtr virNetServerPreExecRestart(virNetServerPtr srv);
|
virJSONValuePtr virNetServerPreExecRestart(virNetServerPtr srv);
|
||||||
|
|
||||||
typedef int (*virNetServerAutoShutdownFunc)(virNetServerPtr srv, void *opaque);
|
|
||||||
|
|
||||||
bool virNetServerIsPrivileged(virNetServerPtr srv);
|
|
||||||
|
|
||||||
void virNetServerAutoShutdown(virNetServerPtr srv,
|
|
||||||
unsigned int timeout);
|
|
||||||
|
|
||||||
void virNetServerAddShutdownInhibition(virNetServerPtr srv);
|
|
||||||
void virNetServerRemoveShutdownInhibition(virNetServerPtr srv);
|
|
||||||
|
|
||||||
typedef void (*virNetServerSignalFunc)(virNetServerPtr srv, siginfo_t *info, void *opaque);
|
|
||||||
|
|
||||||
int virNetServerAddSignalHandler(virNetServerPtr srv,
|
|
||||||
int signum,
|
|
||||||
virNetServerSignalFunc func,
|
|
||||||
void *opaque);
|
|
||||||
|
|
||||||
int virNetServerAddService(virNetServerPtr srv,
|
int virNetServerAddService(virNetServerPtr srv,
|
||||||
virNetServerServicePtr svc,
|
virNetServerServicePtr svc,
|
||||||
const char *mdnsEntryName);
|
const char *mdnsEntryName);
|
||||||
@ -90,18 +76,18 @@ int virNetServerSetTLSContext(virNetServerPtr srv,
|
|||||||
virNetTLSContextPtr tls);
|
virNetTLSContextPtr tls);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
void virNetServerUpdateServices(virNetServerPtr srv,
|
|
||||||
bool enabled);
|
|
||||||
|
|
||||||
void virNetServerRun(virNetServerPtr srv);
|
|
||||||
|
|
||||||
void virNetServerQuit(virNetServerPtr srv);
|
|
||||||
|
|
||||||
void virNetServerClose(virNetServerPtr srv);
|
|
||||||
|
|
||||||
bool virNetServerKeepAliveRequired(virNetServerPtr srv);
|
bool virNetServerKeepAliveRequired(virNetServerPtr srv);
|
||||||
|
|
||||||
size_t virNetServerTrackPendingAuth(virNetServerPtr srv);
|
size_t virNetServerTrackPendingAuth(virNetServerPtr srv);
|
||||||
size_t virNetServerTrackCompletedAuth(virNetServerPtr srv);
|
size_t virNetServerTrackCompletedAuth(virNetServerPtr srv);
|
||||||
|
|
||||||
#endif
|
int virNetServerAddClient(virNetServerPtr srv,
|
||||||
|
virNetServerClientPtr client);
|
||||||
|
bool virNetServerHasClients(virNetServerPtr srv);
|
||||||
|
void virNetServerProcessClients(virNetServerPtr srv);
|
||||||
|
|
||||||
|
void virNetServerUpdateServices(virNetServerPtr srv, bool enabled);
|
||||||
|
|
||||||
|
int virNetServerStart(virNetServerPtr srv);
|
||||||
|
|
||||||
|
#endif /* __VIR_NET_SERVER_H__ */
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
# include "virnetserverclient.h"
|
# include "virnetserverclient.h"
|
||||||
# include "virobject.h"
|
# include "virobject.h"
|
||||||
|
|
||||||
|
typedef struct _virNetDaemon virNetDaemon;
|
||||||
|
typedef virNetDaemon *virNetDaemonPtr;
|
||||||
|
|
||||||
typedef struct _virNetServer virNetServer;
|
typedef struct _virNetServer virNetServer;
|
||||||
typedef virNetServer *virNetServerPtr;
|
typedef virNetServer *virNetServerPtr;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user