Add support for admin API in libvirt daemon

For this to pe properly separated from other protocols used by the
server, there is second server added which allows access to the whole
virNetDaemon to its clients.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
Martin Kletzander 2015-04-15 16:23:55 +02:00
parent beb0eda2e3
commit d5f4241bbc
7 changed files with 294 additions and 13 deletions

3
cfg.mk
View File

@ -1072,6 +1072,7 @@ sc_po_check: \
$(srcdir)/daemon/remote_dispatch.h \ $(srcdir)/daemon/remote_dispatch.h \
$(srcdir)/daemon/qemu_dispatch.h \ $(srcdir)/daemon/qemu_dispatch.h \
$(srcdir)/src/remote/remote_client_bodies.h \ $(srcdir)/src/remote/remote_client_bodies.h \
$(srcdir)/daemon/admin_dispatch.h \
$(srcdir)/src/admin/admin_client.h $(srcdir)/src/admin/admin_client.h
$(srcdir)/daemon/remote_dispatch.h: $(srcdir)/src/remote/remote_protocol.x $(srcdir)/daemon/remote_dispatch.h: $(srcdir)/src/remote/remote_protocol.x
$(MAKE) -C daemon remote_dispatch.h $(MAKE) -C daemon remote_dispatch.h
@ -1079,6 +1080,8 @@ $(srcdir)/daemon/qemu_dispatch.h: $(srcdir)/src/remote/qemu_protocol.x
$(MAKE) -C daemon qemu_dispatch.h $(MAKE) -C daemon qemu_dispatch.h
$(srcdir)/src/remote/remote_client_bodies.h: $(srcdir)/src/remote/remote_protocol.x $(srcdir)/src/remote/remote_client_bodies.h: $(srcdir)/src/remote/remote_protocol.x
$(MAKE) -C src remote/remote_client_bodies.h $(MAKE) -C src remote/remote_client_bodies.h
$(srcdir)/daemon/admin_dispatch.h: $(srcdir)/src/admin/admin_protocol.x
$(MAKE) -C daemon admin_dispatch.h
$(srcdir)/src/admin/admin_client.h: $(srcdir)/src/admin/admin_protocol.x $(srcdir)/src/admin/admin_client.h: $(srcdir)/src/admin/admin_protocol.x
$(MAKE) -C src admin/admin_client.h $(MAKE) -C src admin/admin_client.h

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
## Copyright (C) 2005-2014 Red Hat, Inc. ## Copyright (C) 2005-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
@ -25,6 +25,7 @@ INCLUDES = \
-I$(top_srcdir)/src/conf \ -I$(top_srcdir)/src/conf \
-I$(top_srcdir)/src/rpc \ -I$(top_srcdir)/src/rpc \
-I$(top_srcdir)/src/remote \ -I$(top_srcdir)/src/remote \
-I$(top_srcdir)/src/admin \
-I$(top_srcdir)/src/access \ -I$(top_srcdir)/src/access \
$(GETTEXT_CPPFLAGS) $(GETTEXT_CPPFLAGS)
@ -34,6 +35,7 @@ DAEMON_GENERATED = \
remote_dispatch.h \ remote_dispatch.h \
lxc_dispatch.h \ lxc_dispatch.h \
qemu_dispatch.h \ qemu_dispatch.h \
admin_dispatch.h \
$(NULL) $(NULL)
DAEMON_SOURCES = \ DAEMON_SOURCES = \
@ -49,6 +51,7 @@ EXTRA_DIST = \
remote_dispatch.h \ remote_dispatch.h \
lxc_dispatch.h \ lxc_dispatch.h \
qemu_dispatch.h \ qemu_dispatch.h \
admin_dispatch.h \
libvirtd.conf \ libvirtd.conf \
libvirtd.init.in \ libvirtd.init.in \
libvirtd.upstart \ libvirtd.upstart \
@ -78,6 +81,7 @@ BUILT_SOURCES =
REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x
LXC_PROTOCOL = $(top_srcdir)/src/remote/lxc_protocol.x LXC_PROTOCOL = $(top_srcdir)/src/remote/lxc_protocol.x
QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x
ADMIN_PROTOCOL = $(top_srcdir)/src/admin/admin_protocol.x
remote_dispatch.h: $(top_srcdir)/src/rpc/gendispatch.pl \ remote_dispatch.h: $(top_srcdir)/src/rpc/gendispatch.pl \
$(REMOTE_PROTOCOL) $(REMOTE_PROTOCOL)
@ -97,6 +101,12 @@ qemu_dispatch.h: $(top_srcdir)/src/rpc/gendispatch.pl \
--mode=server qemu QEMU $(QEMU_PROTOCOL) \ --mode=server qemu QEMU $(QEMU_PROTOCOL) \
> $(srcdir)/qemu_dispatch.h > $(srcdir)/qemu_dispatch.h
admin_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(ADMIN_PROTOCOL)
$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl \
--mode=server admin ADMIN $(ADMIN_PROTOCOL) \
> $(srcdir)/admin_dispatch.h
if WITH_LIBVIRTD if WITH_LIBVIRTD
# Build a convenience library, for reuse in tests/libvirtdconftest # Build a convenience library, for reuse in tests/libvirtdconftest
@ -116,6 +126,25 @@ libvirtd_conf_la_LDFLAGS = \
$(NULL) $(NULL)
libvirtd_conf_la_LIBADD = $(LIBXML_LIBS) libvirtd_conf_la_LIBADD = $(LIBXML_LIBS)
noinst_LTLIBRARIES += libvirtd_admin.la
libvirtd_admin_la_SOURCES = \
admin_server.c \
../src/admin/admin_protocol.c
libvirtd_admin_la_CFLAGS = \
$(AM_CFLAGS) \
$(XDR_CFLAGS) \
$(PIE_CFLAGS) \
$(WARN_CFLAGS) \
$(LIBXML_CFLAGS) \
$(COVERAGE_CFLAGS)
libvirtd_admin_la_LDFLAGS = \
$(PIE_LDFLAGS) \
$(RELRO_LDFLAGS) \
$(COVERAGE_LDFLAGS) \
$(NO_INDIRECT_LDFLAGS)
man8_MANS = libvirtd.8 man8_MANS = libvirtd.8
sbin_PROGRAMS = libvirtd sbin_PROGRAMS = libvirtd
@ -168,6 +197,7 @@ endif WITH_DTRACE_PROBES
libvirtd_LDADD += \ libvirtd_LDADD += \
libvirtd_conf.la \ libvirtd_conf.la \
libvirtd_admin.la \
../src/libvirt-lxc.la \ ../src/libvirt-lxc.la \
../src/libvirt-qemu.la \ ../src/libvirt-qemu.la \
../src/libvirt_driver_remote.la \ ../src/libvirt_driver_remote.la \

117
daemon/admin_server.c Normal file
View File

@ -0,0 +1,117 @@
/*
* admin_server.c:
*
* Copyright (C) 2014-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 "internal.h"
#include "libvirtd.h"
#include "libvirt_internal.h"
#include "admin_protocol.h"
#include "admin_server.h"
#include "datatypes.h"
#include "viralloc.h"
#include "virerror.h"
#include "virlog.h"
#include "virnetdaemon.h"
#include "virnetserver.h"
#include "virstring.h"
#include "virthreadjob.h"
#define VIR_FROM_THIS VIR_FROM_ADMIN
VIR_LOG_INIT("daemon.admin");
void
remoteAdmClientFreeFunc(void *data)
{
struct daemonAdmClientPrivate *priv = data;
virMutexDestroy(&priv->lock);
virObjectUnref(priv->dmn);
VIR_FREE(priv);
}
void *
remoteAdmClientInitHook(virNetServerClientPtr client ATTRIBUTE_UNUSED,
void *opaque)
{
struct daemonAdmClientPrivate *priv;
if (VIR_ALLOC(priv) < 0)
return NULL;
if (virMutexInit(&priv->lock) < 0) {
VIR_FREE(priv);
virReportSystemError(errno, "%s", _("unable to init mutex"));
return NULL;
}
/*
* We don't necessarily need to ref this object right now as there
* must be one ref being held throughout the life of the daemon,
* but let's just be safe for future.
*/
priv->dmn = virObjectRef(opaque);
return priv;
}
/* Functions */
static int
adminDispatchConnectOpen(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr,
struct admin_connect_open_args *args)
{
unsigned int flags;
struct daemonAdmClientPrivate *priv =
virNetServerClientGetPrivateData(client);
int ret = -1;
VIR_DEBUG("priv=%p dmn=%p", priv, priv->dmn);
virMutexLock(&priv->lock);
flags = args->flags;
virCheckFlagsGoto(0, cleanup);
ret = 0;
cleanup:
if (ret < 0)
virNetMessageSaveError(rerr);
virMutexUnlock(&priv->lock);
return ret;
}
static int
adminDispatchConnectClose(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED)
{
virNetServerClientDelayedClose(client);
return 0;
}
#include "admin_dispatch.h"

36
daemon/admin_server.h Normal file
View File

@ -0,0 +1,36 @@
/*
* admin_server.h
*
* Copyright (C) 2014 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 __LIBVIRTD_ADMIN_H__
# define __LIBVIRTD_ADMIN_H__
# include "rpc/virnetserverprogram.h"
# include "rpc/virnetserverclient.h"
extern virNetServerProgramProc adminProcs[];
extern size_t adminNProcs;
void remoteAdmClientFreeFunc(void *data);
void *remoteAdmClientInitHook(virNetServerClientPtr client, void *opaque);
#endif /* __ADMIN_REMOTE_H__ */

View File

@ -44,6 +44,7 @@
#include "libvirtd.h" #include "libvirtd.h"
#include "libvirtd-config.h" #include "libvirtd-config.h"
#include "admin_server.h"
#include "viruuid.h" #include "viruuid.h"
#include "remote_driver.h" #include "remote_driver.h"
#include "viralloc.h" #include "viralloc.h"
@ -112,6 +113,7 @@ VIR_LOG_INIT("daemon.libvirtd");
virNetSASLContextPtr saslCtxt = NULL; virNetSASLContextPtr saslCtxt = NULL;
#endif #endif
virNetServerProgramPtr remoteProgram = NULL; virNetServerProgramPtr remoteProgram = NULL;
virNetServerProgramPtr adminProgram = NULL;
virNetServerProgramPtr qemuProgram = NULL; virNetServerProgramPtr qemuProgram = NULL;
virNetServerProgramPtr lxcProgram = NULL; virNetServerProgramPtr lxcProgram = NULL;
@ -253,18 +255,24 @@ static int
daemonUnixSocketPaths(struct daemonConfig *config, daemonUnixSocketPaths(struct daemonConfig *config,
bool privileged, bool privileged,
char **sockfile, char **sockfile,
char **rosockfile) char **rosockfile,
char **admsockfile)
{ {
if (config->unix_sock_dir) { if (config->unix_sock_dir) {
if (virAsprintf(sockfile, "%s/libvirt-sock", config->unix_sock_dir) < 0) if (virAsprintf(sockfile, "%s/libvirt-sock", config->unix_sock_dir) < 0)
goto error; goto error;
if (privileged &&
virAsprintf(rosockfile, "%s/libvirt-sock-ro", config->unix_sock_dir) < 0) if (privileged) {
goto error; if (virAsprintf(rosockfile, "%s/libvirt-sock-ro", config->unix_sock_dir) < 0)
goto error;
if (virAsprintf(admsockfile, "%s/libvirt-admin-sock", config->unix_sock_dir) < 0)
goto error;
}
} else { } else {
if (privileged) { if (privileged) {
if (VIR_STRDUP(*sockfile, LOCALSTATEDIR "/run/libvirt/libvirt-sock") < 0 || if (VIR_STRDUP(*sockfile, LOCALSTATEDIR "/run/libvirt/libvirt-sock") < 0 ||
VIR_STRDUP(*rosockfile, LOCALSTATEDIR "/run/libvirt/libvirt-sock-ro") < 0) VIR_STRDUP(*rosockfile, LOCALSTATEDIR "/run/libvirt/libvirt-sock-ro") < 0 ||
VIR_STRDUP(*admsockfile, LOCALSTATEDIR "/run/libvirt/libvirt-admin-sock") < 0)
goto error; goto error;
} else { } else {
char *rundir = NULL; char *rundir = NULL;
@ -280,7 +288,8 @@ daemonUnixSocketPaths(struct daemonConfig *config,
} }
umask(old_umask); umask(old_umask);
if (virAsprintf(sockfile, "%s/libvirt-sock", rundir) < 0) { if (virAsprintf(sockfile, "%s/libvirt-sock", rundir) < 0 ||
virAsprintf(admsockfile, "%s/libvirt-admin-sock", rundir) < 0) {
VIR_FREE(rundir); VIR_FREE(rundir);
goto error; goto error;
} }
@ -427,13 +436,16 @@ static void daemonInitialize(void)
static int ATTRIBUTE_NONNULL(3) static int ATTRIBUTE_NONNULL(3)
daemonSetupNetworking(virNetServerPtr srv, daemonSetupNetworking(virNetServerPtr srv,
virNetServerPtr srvAdm,
struct daemonConfig *config, struct daemonConfig *config,
const char *sock_path, const char *sock_path,
const char *sock_path_ro, const char *sock_path_ro,
const char *sock_path_adm,
bool ipsock, bool ipsock,
bool privileged) bool privileged)
{ {
virNetServerServicePtr svc = NULL; virNetServerServicePtr svc = NULL;
virNetServerServicePtr svcAdm = NULL;
virNetServerServicePtr svcRO = NULL; virNetServerServicePtr svcRO = NULL;
virNetServerServicePtr svcTCP = NULL; virNetServerServicePtr svcTCP = NULL;
#if WITH_GNUTLS #if WITH_GNUTLS
@ -442,6 +454,7 @@ daemonSetupNetworking(virNetServerPtr srv,
gid_t unix_sock_gid = 0; gid_t unix_sock_gid = 0;
int unix_sock_ro_mask = 0; int unix_sock_ro_mask = 0;
int unix_sock_rw_mask = 0; int unix_sock_rw_mask = 0;
int unix_sock_adm_mask = 0;
unsigned int cur_fd = STDERR_FILENO + 1; unsigned int cur_fd = STDERR_FILENO + 1;
unsigned int nfds = virGetListenFDs(); unsigned int nfds = virGetListenFDs();
@ -461,6 +474,11 @@ daemonSetupNetworking(virNetServerPtr srv,
goto error; goto error;
} }
if (virStrToLong_i(config->unix_sock_admin_perms, NULL, 8, &unix_sock_adm_mask) != 0) {
VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_admin_perms);
goto error;
}
if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) { if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) {
VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms); VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms);
goto error; goto error;
@ -503,6 +521,24 @@ daemonSetupNetworking(virNetServerPtr srv,
virNetServerAddService(srv, svcRO, NULL) < 0) virNetServerAddService(srv, svcRO, NULL) < 0)
goto error; goto error;
if (sock_path_adm) {
VIR_DEBUG("Registering unix socket %s", sock_path_adm);
if (!(svcAdm = virNetServerServiceNewUNIX(sock_path_adm,
unix_sock_adm_mask,
unix_sock_gid,
REMOTE_AUTH_NONE,
#if WITH_GNUTLS
NULL,
#endif
true,
config->admin_max_queued_clients,
config->admin_max_client_requests)))
goto error;
}
if (virNetServerAddService(srvAdm, svcAdm, NULL) < 0)
goto error;
if (ipsock) { if (ipsock) {
if (config->listen_tcp) { if (config->listen_tcp) {
VIR_DEBUG("Registering TCP socket %s:%s", VIR_DEBUG("Registering TCP socket %s:%s",
@ -602,6 +638,7 @@ daemonSetupNetworking(virNetServerPtr srv,
virObjectUnref(svcTCP); virObjectUnref(svcTCP);
virObjectUnref(svc); virObjectUnref(svc);
virObjectUnref(svcRO); virObjectUnref(svcRO);
virObjectUnref(svcAdm);
return -1; return -1;
} }
@ -1102,6 +1139,7 @@ daemonUsage(const char *argv0, bool privileged)
int main(int argc, char **argv) { int main(int argc, char **argv) {
virNetDaemonPtr dmn = NULL; virNetDaemonPtr dmn = NULL;
virNetServerPtr srv = NULL; virNetServerPtr srv = NULL;
virNetServerPtr srvAdm = NULL;
char *remote_config_file = NULL; char *remote_config_file = NULL;
int statuswrite = -1; int statuswrite = -1;
int ret = 1; int ret = 1;
@ -1109,6 +1147,7 @@ int main(int argc, char **argv) {
char *pid_file = NULL; char *pid_file = NULL;
char *sock_file = NULL; char *sock_file = NULL;
char *sock_file_ro = NULL; char *sock_file_ro = NULL;
char *sock_file_adm = NULL;
int timeout = -1; /* -t: Shutdown timeout */ int timeout = -1; /* -t: Shutdown timeout */
int verbose = 0; int verbose = 0;
int godaemon = 0; int godaemon = 0;
@ -1276,12 +1315,15 @@ int main(int argc, char **argv) {
if (daemonUnixSocketPaths(config, if (daemonUnixSocketPaths(config,
privileged, privileged,
&sock_file, &sock_file,
&sock_file_ro) < 0) { &sock_file_ro,
&sock_file_adm) < 0) {
VIR_ERROR(_("Can't determine socket paths")); VIR_ERROR(_("Can't determine socket paths"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
VIR_DEBUG("Decided on socket paths '%s' and '%s'", VIR_DEBUG("Decided on socket paths '%s', '%s' and '%s'",
sock_file, NULLSTR(sock_file_ro)); sock_file,
NULLSTR(sock_file_ro),
NULLSTR(sock_file_adm));
if (godaemon) { if (godaemon) {
char ebuf[1024]; char ebuf[1024];
@ -1413,6 +1455,40 @@ int main(int argc, char **argv) {
goto cleanup; goto cleanup;
} }
if (!(srvAdm = virNetServerNew(config->admin_min_workers,
config->admin_max_workers,
0,
config->admin_max_clients,
0,
config->admin_keepalive_interval,
config->admin_keepalive_count,
!!config->admin_keepalive_required,
NULL,
remoteAdmClientInitHook,
NULL,
remoteAdmClientFreeFunc,
dmn))) {
ret = VIR_DAEMON_ERR_INIT;
goto cleanup;
}
if (virNetDaemonAddServer(dmn, srvAdm) < 0) {
ret = VIR_DAEMON_ERR_INIT;
goto cleanup;
}
if (!(adminProgram = virNetServerProgramNew(ADMIN_PROGRAM,
ADMIN_PROTOCOL_VERSION,
adminProcs,
adminNProcs))) {
ret = VIR_DAEMON_ERR_INIT;
goto cleanup;
}
if (virNetServerAddProgram(srvAdm, adminProgram) < 0) {
ret = VIR_DAEMON_ERR_INIT;
goto cleanup;
}
if (timeout != -1) { if (timeout != -1) {
VIR_DEBUG("Registering shutdown timeout %d", timeout); VIR_DEBUG("Registering shutdown timeout %d", timeout);
virNetDaemonAutoShutdown(dmn, timeout); virNetDaemonAutoShutdown(dmn, timeout);
@ -1453,8 +1529,11 @@ int main(int argc, char **argv) {
virHookCall(VIR_HOOK_DRIVER_DAEMON, "-", VIR_HOOK_DAEMON_OP_START, virHookCall(VIR_HOOK_DRIVER_DAEMON, "-", VIR_HOOK_DAEMON_OP_START,
0, "start", NULL, NULL); 0, "start", NULL, NULL);
if (daemonSetupNetworking(srv, config, if (daemonSetupNetworking(srv, srvAdm,
sock_file, sock_file_ro, config,
sock_file,
sock_file_ro,
sock_file_adm,
ipsock, privileged) < 0) { ipsock, privileged) < 0) {
ret = VIR_DAEMON_ERR_NETWORK; ret = VIR_DAEMON_ERR_NETWORK;
goto cleanup; goto cleanup;
@ -1507,9 +1586,11 @@ int main(int argc, char **argv) {
virObjectUnref(remoteProgram); virObjectUnref(remoteProgram);
virObjectUnref(lxcProgram); virObjectUnref(lxcProgram);
virObjectUnref(qemuProgram); virObjectUnref(qemuProgram);
virObjectUnref(adminProgram);
virNetDaemonClose(dmn); virNetDaemonClose(dmn);
virObjectUnref(dmn); virObjectUnref(dmn);
virObjectUnref(srv); virObjectUnref(srv);
virObjectUnref(srvAdm);
virNetlinkShutdown(); virNetlinkShutdown();
if (statuswrite != -1) { if (statuswrite != -1) {
if (ret != 0) { if (ret != 0) {
@ -1526,6 +1607,7 @@ int main(int argc, char **argv) {
VIR_FREE(sock_file); VIR_FREE(sock_file);
VIR_FREE(sock_file_ro); VIR_FREE(sock_file_ro);
VIR_FREE(sock_file_adm);
VIR_FREE(pid_file); VIR_FREE(pid_file);
VIR_FREE(remote_config_file); VIR_FREE(remote_config_file);
VIR_FREE(run_dir); VIR_FREE(run_dir);

View File

@ -1,7 +1,7 @@
/* /*
* libvirtd.h: daemon data structure definitions * libvirtd.h: daemon data structure definitions
* *
* 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
@ -30,9 +30,11 @@
# include <rpc/types.h> # include <rpc/types.h>
# include <rpc/xdr.h> # include <rpc/xdr.h>
# include "remote_protocol.h" # include "remote_protocol.h"
# include "admin_protocol.h"
# include "lxc_protocol.h" # include "lxc_protocol.h"
# include "qemu_protocol.h" # include "qemu_protocol.h"
# include "virthread.h" # include "virthread.h"
# if WITH_SASL # if WITH_SASL
# include "virnetsaslcontext.h" # include "virnetsaslcontext.h"
# endif # endif
@ -42,6 +44,8 @@ typedef struct daemonClientStream daemonClientStream;
typedef daemonClientStream *daemonClientStreamPtr; typedef daemonClientStream *daemonClientStreamPtr;
typedef struct daemonClientPrivate daemonClientPrivate; typedef struct daemonClientPrivate daemonClientPrivate;
typedef daemonClientPrivate *daemonClientPrivatePtr; typedef daemonClientPrivate *daemonClientPrivatePtr;
typedef struct daemonAdmClientPrivate daemonAdmClientPrivate;
typedef daemonAdmClientPrivate *daemonAdmClientPrivatePtr;
typedef struct daemonClientEventCallback daemonClientEventCallback; typedef struct daemonClientEventCallback daemonClientEventCallback;
typedef daemonClientEventCallback *daemonClientEventCallbackPtr; typedef daemonClientEventCallback *daemonClientEventCallbackPtr;
@ -71,6 +75,14 @@ struct daemonClientPrivate {
bool keepalive_supported; bool keepalive_supported;
}; };
/* Separate private data for admin connection */
struct daemonAdmClientPrivate {
/* Just a placeholder, not that there is anything to be locked */
virMutex lock;
virNetDaemonPtr dmn;
};
# if WITH_SASL # if WITH_SASL
extern virNetSASLContextPtr saslCtxt; extern virNetSASLContextPtr saslCtxt;
# endif # endif

View File

@ -1,3 +1,4 @@
daemon/admin_server.c
daemon/libvirtd-config.c daemon/libvirtd-config.c
daemon/libvirtd.c daemon/libvirtd.c
daemon/qemu_dispatch.h daemon/qemu_dispatch.h