From d442599a807185f968d4dc1f14b96d296fa36104 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 21 Oct 2011 12:49:23 +0100 Subject: [PATCH] Implement RPC driver support for virDomainOpenGraphics Since it needs to access file descriptors passed in the msg, the RPC driver for virDomainOpenGraphics needs to be manually implemented. * daemon/remote.c: RPC server dispatcher * src/remote/remote_driver.c: RPC client dispatcher * src/remote/remote_protocol.x: Define protocol --- daemon/remote.c | 43 +++++++++++++++++++++ src/remote/remote_driver.c | 73 ++++++++++++++++++++++++++++++------ src/remote/remote_protocol.x | 9 ++++- src/remote_protocol-structs | 6 +++ 4 files changed, 119 insertions(+), 12 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index f0dd63fc60..f5141b959f 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -44,6 +44,7 @@ #include "intprops.h" #include "virnetserverservice.h" #include "virnetserver.h" +#include "virfile.h" #include "remote_protocol.h" #include "qemu_protocol.h" @@ -3214,6 +3215,48 @@ cleanup: } +static int +remoteDispatchDomainOpenGraphics(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr msg, + virNetMessageErrorPtr rerr, + remote_domain_open_graphics_args *args) +{ + virDomainPtr dom = NULL; + int rv = -1; + int fd = -1; + struct daemonClientPrivate *priv = + virNetServerClientGetPrivateData(client); + + if (!priv->conn) { + virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + if (!(dom = get_nonnull_domain(priv->conn, args->dom))) + goto cleanup; + + if ((fd = virNetMessageDupFD(msg, 0)) < 0) + goto cleanup; + + if (virDomainOpenGraphics(dom, + args->idx, + fd, + args->flags) < 0) + goto cleanup; + + rv = 0; + +cleanup: + VIR_FORCE_CLOSE(fd); + if (rv < 0) + virNetMessageSaveError(rerr); + if (dom) + virDomainFree(dom); + return rv; +} + + /*----- Helpers. -----*/ /* get_nonnull_domain and get_nonnull_network turn an on-wire diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 382bb421af..ea7fb24f89 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -103,10 +103,14 @@ static void remoteDriverUnlock(struct private_data *driver) virMutexUnlock(&driver->lock); } -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 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 remoteAuthenticate (virConnectPtr conn, struct private_data *priv, virConnectAuthPtr auth, const char *authtype); #if HAVE_SASL @@ -4122,6 +4126,36 @@ done: } +static int +remoteDomainOpenGraphics(virDomainPtr dom, + unsigned int idx, + int fd, + unsigned int flags) +{ + int rv = -1; + remote_domain_open_graphics_args args; + struct private_data *priv = dom->conn->privateData; + + remoteDriverLock(priv); + + make_nonnull_domain (&args.dom, 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) + goto done; + + rv = 0; + +done: + remoteDriverUnlock(priv); + + return rv; +} + + #include "remote_client_bodies.h" #include "qemu_client_bodies.h" @@ -4130,17 +4164,20 @@ done: * send that to the server and wait for reply */ static int -call (virConnectPtr conn ATTRIBUTE_UNUSED, - struct private_data *priv, - unsigned int flags, - int proc_nr, - xdrproc_t args_filter, char *args, - xdrproc_t ret_filter, char *ret) +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) { int rv; virNetClientProgramPtr prog = flags & REMOTE_CALL_QEMU ? priv->qemuProgram : priv->remoteProgram; int counter = priv->counter++; virNetClientPtr client = priv->client; + int fds[] = { fd }; + size_t nfds = fd == -1 ? 0 : 1; priv->localUses++; /* Unlock, so that if we get any async events/stream data @@ -4152,7 +4189,7 @@ call (virConnectPtr conn ATTRIBUTE_UNUSED, client, counter, proc_nr, - 0, NULL, NULL, NULL, + nfds, nfds ? fds : NULL, NULL, NULL, args_filter, args, ret_filter, ret); remoteDriverLock(priv); @@ -4161,6 +4198,19 @@ call (virConnectPtr conn ATTRIBUTE_UNUSED, return rv; } +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) +{ + return callWithFD(conn, priv, flags, -1, proc_nr, + args_filter, args, + ret_filter, ret); +} + static void remoteDomainEventDispatchFunc(virConnectPtr conn, virDomainEventPtr event, @@ -4463,6 +4513,7 @@ static virDriver remote_driver = { .qemuDomainMonitorCommand = remoteQemuDomainMonitorCommand, /* 0.8.3 */ .qemuDomainAttach = qemuDomainAttach, /* 0.9.4 */ .domainOpenConsole = remoteDomainOpenConsole, /* 0.8.6 */ + .domainOpenGraphics = remoteDomainOpenGraphics, /* 0.9.7 */ .domainInjectNMI = remoteDomainInjectNMI, /* 0.9.2 */ .domainMigrateBegin3 = remoteDomainMigrateBegin3, /* 0.9.2 */ .domainMigratePrepare3 = remoteDomainMigratePrepare3, /* 0.9.2 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 47b89579a0..a174af8a5a 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2261,6 +2261,12 @@ struct remote_domain_get_control_info_ret { /* insert@1 */ unsigned hyper stateTime; }; +struct remote_domain_open_graphics_args { + remote_nonnull_domain dom; + unsigned int idx; + unsigned int flags; +}; + /*----- Protocol. -----*/ /* Define the program number, protocol version and procedure numbers here. */ @@ -2555,7 +2561,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_RESET = 245, /* autogen autogen */ REMOTE_PROC_DOMAIN_SNAPSHOT_NUM_CHILDREN = 246, /* autogen autogen priority:high */ REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES = 247, /* autogen autogen priority:high */ - REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE = 248 /* skipgen skipgen */ + REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE = 248, /* skipgen skipgen */ + REMOTE_PROC_DOMAIN_OPEN_GRAPHICS = 249 /* skipgen skipgen */ /* * Notice how the entries are grouped in sets of 10 ? diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 569fcb329e..12cedefd6f 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -1750,6 +1750,11 @@ struct remote_domain_get_control_info_ret { u_int details; uint64_t stateTime; }; +struct remote_domain_open_graphics_args { + remote_nonnull_domain dom; + u_int idx; + u_int flags; +}; enum remote_procedure { REMOTE_PROC_OPEN = 1, REMOTE_PROC_CLOSE = 2, @@ -1999,4 +2004,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_SNAPSHOT_NUM_CHILDREN = 246, REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES = 247, REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE = 248, + REMOTE_PROC_DOMAIN_OPEN_GRAPHICS = 249, };