From: "Daniel P. Berrange" <berrange(a)redhat.com>
Add the infrastructure for the libvirt-lxc.la library to
the remote protocol client and daemon
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
daemon/Makefile.am | 13 +++++-
daemon/libvirtd.c | 14 ++++++
daemon/libvirtd.h | 1 +
daemon/remote.c | 52 +++++++++++++++++++++
daemon/remote.h | 3 ++
src/Makefile.am | 15 +++++-
src/remote/lxc_protocol.x | 50 ++++++++++++++++++++
src/remote/remote_driver.c | 112 ++++++++++++++++++++++++++++++++++++---------
8 files changed, 235 insertions(+), 25 deletions(-)
create mode 100644 src/remote/lxc_protocol.x
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 18a4bca..88a27f2 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -17,7 +17,9 @@ CLEANFILES =
DAEMON_GENERATED = \
$(srcdir)/remote_dispatch.h \
- $(srcdir)/qemu_dispatch.h
+ $(srcdir)/lxc_dispatch.h \
+ $(srcdir)/qemu_dispatch.h \
+ $(NULL)
DAEMON_SOURCES = \
libvirtd.c libvirtd.h \
@@ -25,12 +27,14 @@ DAEMON_SOURCES = \
remote.c remote.h \
stream.c stream.h \
../src/remote/remote_protocol.c \
+ ../src/remote/lxc_protocol.c \
../src/remote/qemu_protocol.c \
$(DAEMON_GENERATED)
DISTCLEANFILES =
EXTRA_DIST = \
remote_dispatch.h \
+ lxc_dispatch.h \
qemu_dispatch.h \
libvirtd.conf \
libvirtd.init.in \
@@ -53,6 +57,7 @@ EXTRA_DIST = \
BUILT_SOURCES =
REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x
+LXC_PROTOCOL = $(top_srcdir)/src/remote/lxc_protocol.x
QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x
$(srcdir)/remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
@@ -60,6 +65,11 @@ $(srcdir)/remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b remote REMOTE \
$(REMOTE_PROTOCOL) > $@
+$(srcdir)/lxc_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
+ $(LXC_PROTOCOL)
+ $(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b lxc LXC \
+ $(LXC_PROTOCOL) > $@
+
$(srcdir)/qemu_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(QEMU_PROTOCOL)
$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b qemu QEMU \
@@ -116,6 +126,7 @@ libvirtd_LDADD += ../src/libvirt_probes.lo
endif
libvirtd_LDADD += \
+ ../src/libvirt-lxc.la \
../src/libvirt-qemu.la
if ! WITH_DRIVER_MODULES
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index fa4d129..0513312 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -103,6 +103,7 @@ virNetSASLContextPtr saslCtxt = NULL;
#endif
virNetServerProgramPtr remoteProgram = NULL;
virNetServerProgramPtr qemuProgram = NULL;
+virNetServerProgramPtr lxcProgram = NULL;
enum {
VIR_DAEMON_ERR_NONE = 0,
@@ -1349,6 +1350,18 @@ int main(int argc, char **argv) {
goto cleanup;
}
+ if (!(lxcProgram = virNetServerProgramNew(LXC_PROGRAM,
+ LXC_PROTOCOL_VERSION,
+ lxcProcs,
+ lxcNProcs))) {
+ ret = VIR_DAEMON_ERR_INIT;
+ goto cleanup;
+ }
+ if (virNetServerAddProgram(srv, lxcProgram) < 0) {
+ ret = VIR_DAEMON_ERR_INIT;
+ goto cleanup;
+ }
+
if (!(qemuProgram = virNetServerProgramNew(QEMU_PROGRAM,
QEMU_PROTOCOL_VERSION,
qemuProcs,
@@ -1454,6 +1467,7 @@ int main(int argc, char **argv) {
cleanup:
virNetlinkEventServiceStopAll();
virObjectUnref(remoteProgram);
+ virObjectUnref(lxcProgram);
virObjectUnref(qemuProgram);
virNetServerClose(srv);
virObjectUnref(srv);
diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h
index 69a77ea..6254208 100644
--- a/daemon/libvirtd.h
+++ b/daemon/libvirtd.h
@@ -32,6 +32,7 @@
# include <rpc/types.h>
# include <rpc/xdr.h>
# include "remote_protocol.h"
+# include "lxc_protocol.h"
# include "qemu_protocol.h"
# include "virlog.h"
# include "virthread.h"
diff --git a/daemon/remote.c b/daemon/remote.c
index a69dc5d..a4cedbb 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -50,6 +50,7 @@
#include "virprocess.h"
#include "remote_protocol.h"
#include "qemu_protocol.h"
+#include "lxc_protocol.h"
#define VIR_FROM_THIS VIR_FROM_RPC
@@ -105,6 +106,7 @@ remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors,
#include "remote_dispatch.h"
#include "qemu_dispatch.h"
+#include "lxc_dispatch.h"
/* Prototypes */
@@ -4618,6 +4620,56 @@ cleanup:
return rv;
}
+static int
+lxcDispatchDomainOpenNamespace(virNetServerPtr server ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client ATTRIBUTE_UNUSED,
+ virNetMessagePtr msg ATTRIBUTE_UNUSED,
+ virNetMessageErrorPtr rerr,
+ lxc_domain_open_namespace_args *args)
+{
+ int rv = -1;
+ struct daemonClientPrivate *priv =
+ virNetServerClientGetPrivateData(client);
+ int *fdlist = NULL;
+ int ret;
+ virDomainPtr dom = NULL;
+ size_t i;
+
+ if (!priv->conn) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not
open"));
+ goto cleanup;
+ }
+
+ if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
+ goto cleanup;
+
+ ret = virDomainLxcOpenNamespace(dom,
+ &fdlist,
+ args->flags);
+ if (ret < 0)
+ goto cleanup;
+
+ /* We shouldn't have received any from the client,
+ * but in case they're playing games with us, prevent
+ * a resource leak
+ */
+ for (i = 0 ; i < msg->nfds ; i++)
+ VIR_FORCE_CLOSE(msg->fds[i]);
+ VIR_FREE(msg->fds);
+ msg->nfds = 0;
+
+ msg->fds = fdlist;
+ msg->nfds = ret;
+
+ rv = 1;
+
+cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ virDomainFree(dom);
+ return rv;
+}
+
/*----- Helpers. -----*/
/* get_nonnull_domain and get_nonnull_network turn an on-wire
diff --git a/daemon/remote.h b/daemon/remote.h
index 493171f..d42a19e 100644
--- a/daemon/remote.h
+++ b/daemon/remote.h
@@ -32,6 +32,9 @@
extern virNetServerProgramProc remoteProcs[];
extern size_t remoteNProcs;
+extern virNetServerProgramProc lxcProcs[];
+extern size_t lxcNProcs;
+
extern virNetServerProgramProc qemuProcs[];
extern size_t qemuNProcs;
diff --git a/src/Makefile.am b/src/Makefile.am
index 13b7e30..d0f431e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -272,19 +272,28 @@ REMOTE_DRIVER_GENERATED = \
$(srcdir)/remote/remote_protocol.c \
$(srcdir)/remote/remote_protocol.h \
$(srcdir)/remote/remote_client_bodies.h \
+ $(srcdir)/remote/lxc_protocol.c \
+ $(srcdir)/remote/lxc_protocol.h \
+ $(srcdir)/remote/lxc_client_bodies.h \
$(srcdir)/remote/qemu_protocol.c \
$(srcdir)/remote/qemu_protocol.h \
$(srcdir)/remote/qemu_client_bodies.h
REMOTE_PROTOCOL = $(srcdir)/remote/remote_protocol.x
+LXC_PROTOCOL = $(srcdir)/remote/lxc_protocol.x
QEMU_PROTOCOL = $(srcdir)/remote/qemu_protocol.x
-REMOTE_DRIVER_PROTOCOL = $(REMOTE_PROTOCOL) $(QEMU_PROTOCOL)
+REMOTE_DRIVER_PROTOCOL = $(REMOTE_PROTOCOL) $(QEMU_PROTOCOL) $(LXC_PROTOCOL)
$(srcdir)/remote/remote_client_bodies.h: $(srcdir)/rpc/gendispatch.pl \
$(REMOTE_PROTOCOL)
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl \
-k remote REMOTE $(REMOTE_PROTOCOL) > $@
+$(srcdir)/remote/lxc_client_bodies.h: $(srcdir)/rpc/gendispatch.pl \
+ $(LXC_PROTOCOL)
+ $(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl \
+ -k lxc LXC $(LXC_PROTOCOL) > $@
+
$(srcdir)/remote/qemu_client_bodies.h: $(srcdir)/rpc/gendispatch.pl \
$(QEMU_PROTOCOL)
$(AM_V_GEN)$(PERL) -w $(srcdir)/rpc/gendispatch.pl \
@@ -374,6 +383,7 @@ EXTRA_DIST += check-symfile.pl check-symsorting.pl
PROTOCOL_STRUCTS = \
$(srcdir)/remote_protocol-structs \
+ $(srcdir)/lxc_protocol-structs \
$(srcdir)/qemu_protocol-structs \
$(srcdir)/virnetprotocol-structs \
$(srcdir)/virkeepaliveprotocol-structs
@@ -382,7 +392,7 @@ check-protocol: $(PROTOCOL_STRUCTS)
$(PROTOCOL_STRUCTS:structs=struct)
# The .o file that pdwtags parses is created as a side effect of running
# libtool; but from make's perspective we depend on the .lo file.
-$(srcdir)/remote_protocol-struct $(srcdir)/qemu_protocol-struct: \
+$(srcdir)/remote_protocol-struct $(srcdir)/qemu_protocol-struct
$(srcdir)/lxc_protocol-struct: \
$(srcdir)/%-struct: libvirt_driver_remote_la-%.lo
$(PDWTAGS)
$(srcdir)/virnetprotocol-struct $(srcdir)/virkeepaliveprotocol-struct: \
@@ -1546,6 +1556,7 @@ tapset_DATA = libvirt_probes.stp libvirt_qemu_probes.stp
libvirt_functions.stp
RPC_PROBE_FILES = $(srcdir)/rpc/virnetprotocol.x \
$(srcdir)/rpc/virkeepaliveprotocol.x \
$(srcdir)/remote/remote_protocol.x \
+ $(srcdir)/remote/lxc_protocol.x \
$(srcdir)/remote/qemu_protocol.x
libvirt_functions.stp: $(RPC_PROBE_FILES) $(srcdir)/rpc/gensystemtap.pl
diff --git a/src/remote/lxc_protocol.x b/src/remote/lxc_protocol.x
new file mode 100644
index 0000000..f2e0b44
--- /dev/null
+++ b/src/remote/lxc_protocol.x
@@ -0,0 +1,50 @@
+/* -*- c -*-
+ * lxc_protocol.x: private protocol for communicating between
+ * remote_internal driver and libvirtd. This protocol is
+ * internal and may change at any time.
+ *
+ * Copyright (C) 2010-2012 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: Chris Lalancette <clalance(a)redhat.com>
+ */
+
+%#include "internal.h"
+%#include "remote_protocol.h"
+%#include <arpa/inet.h>
+
+/*----- Protocol. -----*/
+struct lxc_domain_open_namespace_args {
+ remote_nonnull_domain dom;
+ unsigned int flags;
+};
+
+
+/* Define the program number, protocol version and procedure numbers here. */
+const LXC_PROGRAM = 0x00068000;
+const LXC_PROTOCOL_VERSION = 1;
+
+enum lxc_procedure {
+ /* Each function must have a three-word comment. The first word is
+ * whether gendispatch.pl handles daemon, the second whether
+ * it handles src/remote.
+ * The last argument describes priority of API. There are two accepted
+ * values: low, high; Each API that might eventually access hypervisor's
+ * monitor (and thus block) MUST fall into low priority. However, there
+ * are some exceptions to this rule, e.g. domainDestroy. Other APIs MAY
+ * be marked as high priority. If in doubt, it's safe to choose low. */
+ LXC_PROC_DOMAIN_OPEN_NAMESPACE = 1 /* skipgen skipgen priority:low */
+};
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index ae861cc..5f9b936 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -37,6 +37,7 @@
#include "virbuffer.h"
#include "remote_driver.h"
#include "remote_protocol.h"
+#include "lxc_protocol.h"
#include "qemu_protocol.h"
#include "viralloc.h"
#include "virutil.h"
@@ -77,6 +78,7 @@ struct private_data {
virNetClientPtr client;
virNetClientProgramPtr remoteProgram;
virNetClientProgramPtr qemuProgram;
+ virNetClientProgramPtr lxcProgram;
int counter; /* Serial number for RPC */
@@ -93,6 +95,7 @@ struct private_data {
enum {
REMOTE_CALL_QEMU = (1 << 0),
+ REMOTE_CALL_LXC = (1 << 1),
};
@@ -110,10 +113,13 @@ static int call(virConnectPtr conn, struct private_data *priv,
unsigned int flags, int proc_nr,
xdrproc_t args_filter, char *args,
xdrproc_t ret_filter, char *ret);
-static int callWithFD(virConnectPtr conn, struct private_data *priv,
- unsigned int flags, int fd, int proc_nr,
- xdrproc_t args_filter, char *args,
- xdrproc_t ret_filter, char *ret);
+static int callFull(virConnectPtr conn, struct private_data *priv,
+ unsigned int flags,
+ int *fdin, size_t fdinlen,
+ int **fdout, size_t *fdoutlen,
+ int proc_nr,
+ xdrproc_t args_filter, char *args,
+ xdrproc_t ret_filter, char *ret);
static int remoteAuthenticate(virConnectPtr conn, struct private_data *priv,
virConnectAuthPtr auth, const char *authtype);
#if HAVE_SASL
@@ -757,6 +763,12 @@ doRemoteOpen(virConnectPtr conn,
ARRAY_CARDINALITY(remoteDomainEvents),
conn)))
goto failed;
+ if (!(priv->lxcProgram = virNetClientProgramNew(LXC_PROGRAM,
+ LXC_PROTOCOL_VERSION,
+ NULL,
+ 0,
+ NULL)))
+ goto failed;
if (!(priv->qemuProgram = virNetClientProgramNew(QEMU_PROGRAM,
QEMU_PROTOCOL_VERSION,
NULL,
@@ -765,6 +777,7 @@ doRemoteOpen(virConnectPtr conn,
goto failed;
if (virNetClientAddProgram(priv->client, priv->remoteProgram) < 0 ||
+ virNetClientAddProgram(priv->client, priv->lxcProgram) < 0 ||
virNetClientAddProgram(priv->client, priv->qemuProgram) < 0)
goto failed;
@@ -849,6 +862,7 @@ no_memory:
failed:
virObjectUnref(priv->remoteProgram);
+ virObjectUnref(priv->lxcProgram);
virObjectUnref(priv->qemuProgram);
virNetClientClose(priv->client);
virObjectUnref(priv->client);
@@ -1011,8 +1025,9 @@ doRemoteClose(virConnectPtr conn, struct private_data *priv)
virObjectUnref(priv->client);
priv->client = NULL;
virObjectUnref(priv->remoteProgram);
+ virObjectUnref(priv->lxcProgram);
virObjectUnref(priv->qemuProgram);
- priv->remoteProgram = priv->qemuProgram = NULL;
+ priv->remoteProgram = priv->qemuProgram = priv->lxcProgram = NULL;
/* Free hostname copy */
VIR_FREE(priv->hostname);
@@ -5393,6 +5408,8 @@ remoteDomainOpenGraphics(virDomainPtr dom,
int rv = -1;
remote_domain_open_graphics_args args;
struct private_data *priv = dom->conn->privateData;
+ int fdin[] = { fd };
+ size_t fdinlen = ARRAY_CARDINALITY(fdin);
remoteDriverLock(priv);
@@ -5400,9 +5417,12 @@ remoteDomainOpenGraphics(virDomainPtr dom,
args.idx = idx;
args.flags = flags;
- if (callWithFD(dom->conn, priv, 0, fd, REMOTE_PROC_DOMAIN_OPEN_GRAPHICS,
- (xdrproc_t) xdr_remote_domain_open_graphics_args, (char *) &args,
- (xdrproc_t) xdr_void, NULL) == -1)
+ if (callFull(dom->conn, priv, 0,
+ fdin, fdinlen,
+ NULL, NULL,
+ REMOTE_PROC_DOMAIN_OPEN_GRAPHICS,
+ (xdrproc_t) xdr_remote_domain_open_graphics_args, (char *) &args,
+ (xdrproc_t) xdr_void, NULL) == -1)
goto done;
rv = 0;
@@ -5507,6 +5527,7 @@ done:
}
#include "remote_client_bodies.h"
+#include "lxc_client_bodies.h"
#include "qemu_client_bodies.h"
/*
@@ -5514,22 +5535,30 @@ done:
* send that to the server and wait for reply
*/
static int
-callWithFD(virConnectPtr conn ATTRIBUTE_UNUSED,
- struct private_data *priv,
- unsigned int flags,
- int fd,
- int proc_nr,
- xdrproc_t args_filter, char *args,
- xdrproc_t ret_filter, char *ret)
+callFull(virConnectPtr conn ATTRIBUTE_UNUSED,
+ struct private_data *priv,
+ unsigned int flags,
+ int *fdin,
+ size_t fdinlen,
+ int **fdout,
+ size_t *fdoutlen,
+ int proc_nr,
+ xdrproc_t args_filter, char *args,
+ xdrproc_t ret_filter, char *ret)
{
int rv;
- virNetClientProgramPtr prog = flags & REMOTE_CALL_QEMU ? priv->qemuProgram :
priv->remoteProgram;
+ virNetClientProgramPtr prog;
int counter = priv->counter++;
virNetClientPtr client = priv->client;
- int fds[] = { fd };
- size_t nfds = fd == -1 ? 0 : 1;
priv->localUses++;
+ if (flags & REMOTE_CALL_QEMU)
+ prog = priv->qemuProgram;
+ else if (flags & REMOTE_CALL_LXC)
+ prog = priv->lxcProgram;
+ else
+ prog = priv->remoteProgram;
+
/* Unlock, so that if we get any async events/stream data
* while processing the RPC, we don't deadlock when our
* callbacks for those are invoked
@@ -5539,7 +5568,8 @@ callWithFD(virConnectPtr conn ATTRIBUTE_UNUSED,
client,
counter,
proc_nr,
- nfds, nfds ? fds : NULL, NULL, NULL,
+ fdinlen, fdin,
+ fdoutlen, fdout,
args_filter, args,
ret_filter, ret);
remoteDriverLock(priv);
@@ -5556,9 +5586,12 @@ call(virConnectPtr conn,
xdrproc_t args_filter, char *args,
xdrproc_t ret_filter, char *ret)
{
- return callWithFD(conn, priv, flags, -1, proc_nr,
- args_filter, args,
- ret_filter, ret);
+ return callFull(conn, priv, flags,
+ NULL, 0,
+ NULL, NULL,
+ proc_nr,
+ args_filter, args,
+ ret_filter, ret);
}
@@ -5834,6 +5867,40 @@ done:
return rv;
}
+
+static int
+remoteDomainLxcOpenNamespace(virDomainPtr domain,
+ int **fdlist,
+ unsigned int flags)
+{
+ int rv = -1;
+ lxc_domain_open_namespace_args args;
+ struct private_data *priv = domain->conn->privateData;
+ size_t nfds = 0;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_domain(&args.dom, domain);
+ args.flags = flags;
+
+ *fdlist = NULL;
+
+ if (callFull(domain->conn, priv, REMOTE_CALL_LXC,
+ NULL, 0,
+ fdlist, &nfds,
+ LXC_PROC_DOMAIN_OPEN_NAMESPACE,
+ (xdrproc_t) xdr_lxc_domain_open_namespace_args, (char *) &args,
+ (xdrproc_t) xdr_void, NULL) == -1)
+ goto done;
+
+ rv = nfds;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+
static void
remoteDomainEventQueue(struct private_data *priv, virDomainEventPtr event)
{
@@ -6153,6 +6220,7 @@ static virDriver remote_driver = {
.nodeGetMemoryParameters = remoteNodeGetMemoryParameters, /* 0.10.2 */
.nodeGetCPUMap = remoteNodeGetCPUMap, /* 1.0.0 */
.domainFSTrim = remoteDomainFSTrim, /* 1.0.1 */
+ .domainLxcOpenNamespace = remoteDomainLxcOpenNamespace, /* 1.0.2 */
};
static virNetworkDriver network_driver = {
--
1.7.11.7