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

Convert libvirtd over to the new RPC handling APIs

This guts the libvirtd daemon, removing all its networking and
RPC handling code. Instead it calls out to the new virServerPtr
APIs for all its RPC & networking work

As a fallout all libvirtd daemon error reporting now takes place
via the normal internal error reporting APIs. There is no need
to call separate error reporting APIs in RPC code, nor should
code use VIR_WARN/VIR_ERROR for reporting fatal problems anymore.

* daemon/qemu_dispatch_*.h, daemon/remote_dispatch_*.h: Remove
  old generated dispatcher code
* daemon/qemu_dispatch.h, daemon/remote_dispatch.h: New dispatch
  code
* daemon/dispatch.c, daemon/dispatch.h: Remove obsoleted code
* daemon/remote.c, daemon/remote.h: Rewrite for new dispatch
  APIs
* daemon/libvirtd.c, daemon/libvirtd.h: Remove all networking
  code
* daemon/stream.c, daemon/stream.h: Update for new APIs
* daemon/Makefile.am: Link to libvirt-net-rpc-server.la
上级 c1b22644
......@@ -34,7 +34,7 @@
/config.sub
/configure
/configure.lineno
/daemon/*_dispatch_*.h
/daemon/*_dispatch.h
/docs/hvsupport.html.in
/gnulib/
/libtool
......
......@@ -299,17 +299,6 @@ if test x"$enable_debug" = x"yes"; then
fi
AC_MSG_CHECKING([where to write libvirtd PID file])
AC_ARG_WITH([remote-pid-file], [AC_HELP_STRING([--with-remote-pid-file=@<:@pidfile|none@:>@], [PID file for libvirtd])])
if test "x$with_remote_pid_file" = "x" ; then
REMOTE_PID_FILE="$localstatedir/run/libvirtd.pid"
elif test "x$with_remote_pid_file" = "xnone" ; then
REMOTE_PID_FILE=""
else
REMOTE_PID_FILE="$with_remote_pid_file"
fi
AC_SUBST([REMOTE_PID_FILE])
AC_MSG_RESULT($REMOTE_PID_FILE)
dnl
dnl init script flavor
......
......@@ -3,33 +3,21 @@
CLEANFILES =
DAEMON_GENERATED = \
$(srcdir)/remote_dispatch_prototypes.h \
$(srcdir)/remote_dispatch_table.h \
$(srcdir)/remote_dispatch_args.h \
$(srcdir)/remote_dispatch_ret.h \
$(srcdir)/remote_dispatch_bodies.h \
$(srcdir)/qemu_dispatch_prototypes.h \
$(srcdir)/qemu_dispatch_table.h \
$(srcdir)/qemu_dispatch_args.h \
$(srcdir)/qemu_dispatch_ret.h \
$(srcdir)/qemu_dispatch_bodies.h
$(srcdir)/remote_dispatch.h \
$(srcdir)/qemu_dispatch.h
DAEMON_SOURCES = \
libvirtd.c libvirtd.h \
remote.c remote.h \
dispatch.c dispatch.h \
stream.c stream.h \
../src/remote/remote_protocol.c \
../src/remote/qemu_protocol.c \
$(DAEMON_GENERATED)
AVAHI_SOURCES = \
mdns.c mdns.h
DISTCLEANFILES =
EXTRA_DIST = \
remote_dispatch_bodies.h \
qemu_dispatch_bodies.h \
remote_dispatch.h \
qemu_dispatch.h \
libvirtd.conf \
libvirtd.init.in \
libvirtd.upstart \
......@@ -47,7 +35,6 @@ EXTRA_DIST = \
libvirtd.pod.in \
libvirtd.8.in \
libvirtd.stp \
$(AVAHI_SOURCES) \
$(DAEMON_SOURCES)
BUILT_SOURCES =
......@@ -55,52 +42,12 @@ BUILT_SOURCES =
REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x
QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x
$(srcdir)/remote_dispatch_prototypes.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(REMOTE_PROTOCOL)
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -c -p remote \
$(REMOTE_PROTOCOL) > $@
$(srcdir)/remote_dispatch_table.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(REMOTE_PROTOCOL)
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -c -t remote \
$(REMOTE_PROTOCOL) > $@
$(srcdir)/remote_dispatch_args.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(REMOTE_PROTOCOL)
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -c -a remote \
$(REMOTE_PROTOCOL) > $@
$(srcdir)/remote_dispatch_ret.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(REMOTE_PROTOCOL)
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -c -r remote \
$(REMOTE_PROTOCOL) > $@
$(srcdir)/remote_dispatch_bodies.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(srcdir)/remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(REMOTE_PROTOCOL)
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -c -b remote \
$(REMOTE_PROTOCOL) > $@
$(srcdir)/qemu_dispatch_prototypes.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(QEMU_PROTOCOL)
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -p qemu \
$(QEMU_PROTOCOL) > $@
$(srcdir)/qemu_dispatch_table.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(QEMU_PROTOCOL)
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -t qemu \
$(QEMU_PROTOCOL) > $@
$(srcdir)/qemu_dispatch_args.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(QEMU_PROTOCOL)
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -a qemu \
$(QEMU_PROTOCOL) > $@
$(srcdir)/qemu_dispatch_ret.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(QEMU_PROTOCOL)
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -r qemu \
$(QEMU_PROTOCOL) > $@
$(srcdir)/qemu_dispatch_bodies.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(srcdir)/qemu_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(QEMU_PROTOCOL)
$(AM_V_GEN)perl -w $(srcdir)/../src/rpc/gendispatch.pl -b qemu \
$(QEMU_PROTOCOL) > $@
......@@ -137,6 +84,7 @@ libvirtd_CFLAGS = \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/util \
-I$(top_srcdir)/src/conf \
-I$(top_srcdir)/src/rpc \
-I$(top_srcdir)/src/remote \
$(LIBXML_CFLAGS) $(GNUTLS_CFLAGS) $(SASL_CFLAGS) \
$(XDR_CFLAGS) $(POLKIT_CFLAGS) \
......@@ -155,7 +103,10 @@ libvirtd_LDADD = \
$(SASL_LIBS) \
$(POLKIT_LIBS)
libvirtd_LDADD += ../src/libvirt-qemu.la
libvirtd_LDADD += \
../src/libvirt-net-rpc-server.la \
../src/libvirt-net-rpc.la \
../src/libvirt-qemu.la
if ! WITH_DRIVER_MODULES
if WITH_QEMU
......@@ -211,12 +162,6 @@ policyfile = libvirtd.policy-1
endif
endif
if HAVE_AVAHI
libvirtd_SOURCES += $(AVAHI_SOURCES)
libvirtd_CFLAGS += $(AVAHI_CFLAGS)
libvirtd_LDADD += $(AVAHI_LIBS)
endif
if WITH_DTRACE
libvirtd_LDADD += probes.o
nodist_libvirtd_SOURCES = probes.h
......
此差异已折叠。
/*
* dispatch.h: RPC message dispatching infrastructure
*
* Copyright (C) 2007, 2008, 2009 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Richard W.M. Jones <rjones@redhat.com>
* Author: Daniel P. Berrange <berrange@redhat.com>
*/
#ifndef __LIBVIRTD_DISPATCH_H__
# define __LIBVIRTD_DISPATCH_H__
# include "libvirtd.h"
int
remoteDecodeClientMessageHeader (struct qemud_client_message *req);
int
remoteEncodeClientMessageHeader (struct qemud_client_message *req);
int
remoteDispatchClientRequest (struct qemud_server *server,
struct qemud_client *client,
struct qemud_client_message *req);
void remoteDispatchFormatError (remote_error *rerr,
const char *fmt, ...)
ATTRIBUTE_FMT_PRINTF(2, 3);
void remoteDispatchAuthError (remote_error *rerr);
void remoteDispatchGenericError (remote_error *rerr);
void remoteDispatchError(remote_error *rerr);
int
remoteSerializeReplyError(struct qemud_client *client,
remote_error *rerr,
remote_message_header *req);
int
remoteSerializeStreamError(struct qemud_client *client,
remote_error *rerr,
int proc,
int serial);
int
remoteSendStreamData(struct qemud_client *client,
struct qemud_client_stream *stream,
const char *data,
unsigned int len);
#endif /* __LIBVIRTD_DISPATCH_H__ */
此差异已折叠。
......@@ -27,13 +27,6 @@
# include <config.h>
# include <gnutls/gnutls.h>
# include <gnutls/x509.h>
# include "gnutls_1_0_compat.h"
# if HAVE_SASL
# include <sasl/sasl.h>
# endif
# if HAVE_POLKIT0
# include <dbus/dbus.h>
# endif
......@@ -45,6 +38,8 @@
# include "logging.h"
# include "threads.h"
# include "network.h"
# include "virnetsaslcontext.h"
# include "virnetserverprogram.h"
# if WITH_DTRACE
# ifndef LIBVIRTD_PROBES_H
......@@ -63,230 +58,37 @@
#NAME ": " FMT, __VA_ARGS__);
# endif
# ifdef __GNUC__
# ifdef HAVE_ANSIDECL_H
# include <ansidecl.h>
# endif
# ifndef __GNUC_PREREQ
# if defined __GNUC__ && defined __GNUC_MINOR__
# define __GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
# else
# define __GNUC_PREREQ(maj,min) 0
# endif
# endif
/**
* ATTRIBUTE_UNUSED:
*
* Macro to flag conciously unused parameters to functions
*/
# ifndef ATTRIBUTE_UNUSED
# define ATTRIBUTE_UNUSED __attribute__((__unused__))
# endif
/**
* ATTRIBUTE_FMT_PRINTF
*
* Macro used to check printf like functions, if compiling
* with gcc.
*
* We use gnulib which guarentees we always have GNU style
* printf format specifiers even on broken Win32 platforms
* hence we have to force 'gnu_printf' for new GCC
*/
# ifndef ATTRIBUTE_FMT_PRINTF
# if __GNUC_PREREQ (4, 4)
# define ATTRIBUTE_FMT_PRINTF(fmtpos,argpos) __attribute__((__format__ (gnu_printf, fmtpos,argpos)))
# else
# define ATTRIBUTE_FMT_PRINTF(fmtpos,argpos) __attribute__((__format__ (printf, fmtpos,argpos)))
# endif
# endif
# ifndef ATTRIBUTE_RETURN_CHECK
# if __GNUC_PREREQ (3, 4)
# define ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__))
# else
# define ATTRIBUTE_RETURN_CHECK
# endif
# endif
# else
# ifndef ATTRIBUTE_UNUSED
# define ATTRIBUTE_UNUSED
# endif
# ifndef ATTRIBUTE_FMT_PRINTF
# define ATTRIBUTE_FMT_PRINTF(...)
# endif
# ifndef ATTRIBUTE_RETURN_CHECK
# define ATTRIBUTE_RETURN_CHECK
# endif
# endif
/* Whether we're passing reads & writes through a sasl SSF */
enum qemud_sasl_ssf {
QEMUD_SASL_SSF_NONE = 0,
QEMUD_SASL_SSF_READ = 1,
QEMUD_SASL_SSF_WRITE = 2,
};
enum qemud_sock_type {
QEMUD_SOCK_TYPE_UNIX = 0,
QEMUD_SOCK_TYPE_TCP = 1,
QEMUD_SOCK_TYPE_TLS = 2,
};
struct qemud_client_message {
char buffer [REMOTE_MESSAGE_MAX + REMOTE_MESSAGE_HEADER_XDR_LEN];
unsigned int bufferLength;
unsigned int bufferOffset;
unsigned int async : 1;
unsigned int streamTX : 1;
remote_message_header hdr;
struct qemud_client_message *next;
};
struct qemud_client;
/* Allow for filtering of incoming messages to a custom
* dispatch processing queue, instead of client->dx.
*/
typedef int (*qemud_client_filter_func)(struct qemud_client *client,
struct qemud_client_message *msg, void *opaque);
struct qemud_client_filter {
qemud_client_filter_func query;
void *opaque;
struct qemud_client_filter *next;
};
struct qemud_client_stream {
virStreamPtr st;
int procedure;
int serial;
unsigned int recvEOF : 1;
unsigned int closed : 1;
struct qemud_client_filter filter;
struct qemud_client_message *rx;
int tx;
struct qemud_client_stream *next;
};
typedef struct daemonClientStream daemonClientStream;
typedef daemonClientStream *daemonClientStreamPtr;
typedef struct daemonClientPrivate daemonClientPrivate;
typedef daemonClientPrivate *daemonClientPrivatePtr;
/* Stores the per-client connection state */
struct qemud_client {
struct daemonClientPrivate {
/* Hold while accessing any data except conn */
virMutex lock;
int magic;
int fd;
int watch;
unsigned int readonly :1;
unsigned int closing :1;
int domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LAST];
virSocketAddr addr;
const char *addrstr;
int type; /* qemud_sock_type */
gnutls_session_t tlssession;
int auth;
unsigned int handshake :1; /* If we're in progress for TLS handshake */
# if HAVE_SASL
sasl_conn_t *saslconn;
int saslSSF;
const char *saslDecoded;
unsigned int saslDecodedLength;
unsigned int saslDecodedOffset;
const char *saslEncoded;
unsigned int saslEncodedLength;
unsigned int saslEncodedOffset;
char *saslUsername;
char saslTemporary[8192]; /* temorary holds data to be decoded */
# endif
/* Count of meages in 'dx' or 'tx' queue
* ie RPC calls in progress. Does not count
* async events which are not used for
* throttling calculations */
int nrequests;
/* Zero or one messages being received. Zero if
* nrequests >= max_clients and throttling */
struct qemud_client_message *rx;
/* Zero or many messages waiting for a worker
* to process them */
struct qemud_client_message *dx;
/* Zero or many messages waiting for transmit
* back to client, including async events */
struct qemud_client_message *tx;
/* Filters to capture messages that would otherwise
* end up on the 'dx' queue */
struct qemud_client_filter *filters;
/* Data streams */
struct qemud_client_stream *streams;
virNetSASLSessionPtr sasl;
/* This is only valid if a remote open call has been made on this
* connection, otherwise it will be NULL. Also if remote close is
* called, it will be set back to NULL if that succeeds.
*/
virConnectPtr conn;
int refs;
};
# define QEMUD_CLIENT_MAGIC 0x7788aaee
struct qemud_socket {
char *path;
virSocketAddr addr;
const char *addrstr;
int fd;
int watch;
int readonly;
int type; /* qemud_sock_type */
int auth;
struct qemud_socket *next;
daemonClientStreamPtr streams;
};
struct qemud_worker {
pthread_t thread;
unsigned int hasThread :1;
unsigned int processingCall :1;
unsigned int quitRequest :1;
/* back-pointer to our server */
struct qemud_server *server;
};
extern virNetSASLContextPtr saslCtxt;
extern virNetServerProgramPtr remoteProgram;
extern virNetServerProgramPtr qemuProgram;
/* Main server state */
struct qemud_server {
virMutex lock;
virCond job;
int privileged;
size_t nworkers;
size_t nactiveworkers;
struct qemud_worker *workers;
size_t nsockets;
struct qemud_socket *sockets;
size_t nclients;
size_t nclients_max;
struct qemud_client **clients;
int sigread;
int sigwrite;
char *logDir;
......@@ -304,27 +106,6 @@ struct qemud_server {
# endif
};
void qemudLog(int priority, const char *fmt, ...)
ATTRIBUTE_FMT_PRINTF(2,3);
int qemudRegisterClientEvent(struct qemud_server *server,
struct qemud_client *client);
void qemudUpdateClientEvent(struct qemud_client *client);
void qemudDispatchClientFailure(struct qemud_client *client);
void
qemudClientMessageQueuePush(struct qemud_client_message **queue,
struct qemud_client_message *msg);
struct qemud_client_message *
qemudClientMessageQueueServe(struct qemud_client_message **queue);
void
qemudClientMessageRelease(struct qemud_client *client,
struct qemud_client_message *msg);
# if HAVE_POLKIT
int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid);
......
此差异已折叠。
......@@ -24,62 +24,20 @@
#ifndef __LIBVIRTD_REMOTE_H__
# define __LIBVIRTD_REMOTE_H__
# include "remote_protocol.h"
# include "rpc/virnetserverprogram.h"
# include "rpc/virnetserverclient.h"
# include "libvirtd.h"
typedef union {
# include "remote_dispatch_args.h"
} dispatch_args;
verify(sizeof(dispatch_args) > 0);
typedef union {
# include "remote_dispatch_ret.h"
} dispatch_ret;
verify(sizeof(dispatch_ret) > 0);
typedef union {
# include "qemu_dispatch_args.h"
} qemu_dispatch_args;
verify(sizeof(qemu_dispatch_args) > 0);
typedef union {
# include "qemu_dispatch_ret.h"
} qemu_dispatch_ret;
verify(sizeof(qemu_dispatch_ret) > 0);
/**
* When the RPC handler is called:
*
* - Server object is unlocked
* - Client object is unlocked
*
* Both must be locked before use. Server lock must
* be held before attempting to lock client.
*
* Without any locking, it is safe to use:
*
* 'conn', 'rerr', 'args and 'ret'
*/
typedef int (*dispatch_fn) (struct qemud_server *server,
struct qemud_client *client,
virConnectPtr conn,
remote_message_header *hdr,
remote_error *err,
dispatch_args *args,
dispatch_ret *ret);
typedef struct {
dispatch_fn fn;
xdrproc_t args_filter;
xdrproc_t ret_filter;
} dispatch_data;
const dispatch_data const *remoteGetDispatchData(int proc);
const dispatch_data const *qemuGetDispatchData(int proc);
extern virNetServerProgramProc remoteProcs[];
extern size_t remoteNProcs;
extern virNetServerProgramErrorHander remoteErr;
extern virNetServerProgramProc qemuProcs[];
extern size_t qemuNProcs;
extern virNetServerProgramErrorHander qemuErr;
int remoteClientInitHook(virNetServerPtr srv,
virNetServerClientPtr client);
#endif /* __LIBVIRTD_REMOTE_H__ */
此差异已折叠。
......@@ -28,27 +28,21 @@
struct qemud_client_stream *
remoteCreateClientStream(virConnectPtr conn,
remote_message_header *hdr);
daemonClientStream *
daemonCreateClientStream(virNetServerClientPtr client,
virStreamPtr st,
virNetServerProgramPtr prog,
virNetMessageHeaderPtr hdr);
void remoteFreeClientStream(struct qemud_client *client,
struct qemud_client_stream *stream);
int daemonFreeClientStream(virNetServerClientPtr client,
daemonClientStream *stream);
int remoteAddClientStream(struct qemud_client *client,
struct qemud_client_stream *stream,
int transmit);
struct qemud_client_stream *
remoteFindClientStream(struct qemud_client *client,
virStreamPtr stream);
int daemonAddClientStream(virNetServerClientPtr client,
daemonClientStream *stream,
bool transmit);
int
remoteRemoveClientStream(struct qemud_client *client,
struct qemud_client_stream *stream);
void
remoteStreamMessageFinished(struct qemud_client *client,
struct qemud_client_message *msg);
daemonRemoveClientStream(virNetServerClientPtr client,
daemonClientStream *stream);
#endif /* __LIBVIRTD_STREAM_H__ */
daemon/dispatch.c
daemon/libvirtd.c
daemon/remote.c
daemon/remote_dispatch_bodies.h
......
此差异已折叠。
......@@ -51,6 +51,9 @@ void virNetMessageFree(virNetMessagePtr msg)
if (!msg)
return;
if (msg->cb)
msg->cb(msg, msg->opaque);
VIR_DEBUG("msg=%p", msg);
VIR_FREE(msg);
......
......@@ -29,6 +29,8 @@ typedef struct virNetMessageError *virNetMessageErrorPtr;
typedef struct _virNetMessage virNetMessage;
typedef virNetMessage *virNetMessagePtr;
typedef void (*virNetMessageFreeCallback)(virNetMessagePtr msg, void *opaque);
/* Never allocate this (huge) buffer on the stack. Always
* use virNetMessageNew() to allocate on the heap
*/
......@@ -39,6 +41,9 @@ struct _virNetMessage {
virNetMessageHeader header;
virNetMessageFreeCallback cb;
void *opaque;
virNetMessagePtr next;
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册