From 408aae3849418c391db0fabadd7ae92951db0183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Mon, 25 Aug 2014 18:55:20 +0200 Subject: [PATCH] Add RPC implementation for virDomainOpenGraphicsFd --- daemon/remote.c | 44 ++++++++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 43 +++++++++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 15 +++++++++++- src/remote_protocol-structs | 6 +++++ src/rpc/virnetmessage.c | 26 +++++++++++++++++++++ src/rpc/virnetmessage.h | 3 +++ 6 files changed, 136 insertions(+), 1 deletion(-) diff --git a/daemon/remote.c b/daemon/remote.c index ea16789679..27d1aa8037 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -4398,6 +4398,50 @@ remoteDispatchDomainOpenGraphics(virNetServerPtr server ATTRIBUTE_UNUSED, return rv; } +static int +remoteDispatchDomainOpenGraphicsFd(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr msg, + virNetMessageErrorPtr rerr, + remote_domain_open_graphics_fd_args *args) +{ + virDomainPtr dom = NULL; + int rv = -1; + int fd = -1; + struct daemonClientPrivate *priv = + virNetServerClientGetPrivateData(client); + + 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; + + if (virDomainOpenGraphicsFD(dom, + args->idx, + &fd, + args->flags) < 0) + goto cleanup; + + if (virNetMessageAddFD(msg, fd) < 0) + goto cleanup; + + /* return 1 here to let virNetServerProgramDispatchCall know + * we are passing a FD */ + rv = 1; + + cleanup: + VIR_FORCE_CLOSE(fd); + if (rv < 0) { + virNetMessageSaveError(rerr); + } + + if (dom) + virDomainFree(dom); + return rv; +} static int remoteDispatchDomainGetInterfaceParameters(virNetServerPtr server ATTRIBUTE_UNUSED, virNetServerClientPtr client ATTRIBUTE_UNUSED, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 9a1d78fc4f..e01216a861 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -6445,6 +6445,48 @@ remoteDomainOpenGraphics(virDomainPtr dom, } +static int +remoteDomainOpenGraphicsFD(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; + int *fdout = NULL; + size_t fdoutlen = 0; + + remoteDriverLock(priv); + + make_nonnull_domain(&args.dom, dom); + args.idx = idx; + args.flags = flags; + + if (callFull(dom->conn, priv, 0, + NULL, 0, + &fdout, &fdoutlen, + REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD, + (xdrproc_t) xdr_remote_domain_open_graphics_fd_args, (char *) &args, + (xdrproc_t) xdr_void, NULL) == -1) + goto done; + + if (fdoutlen != 1) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("no file descriptor received")); + goto done; + } + *fd = fdout[0]; + + rv = 0; + + done: + remoteDriverUnlock(priv); + + return rv; +} + + static int remoteConnectSetKeepAlive(virConnectPtr conn, int interval, unsigned int count) { @@ -7963,6 +8005,7 @@ static virDriver remote_driver = { .domainOpenConsole = remoteDomainOpenConsole, /* 0.8.6 */ .domainOpenChannel = remoteDomainOpenChannel, /* 1.0.2 */ .domainOpenGraphics = remoteDomainOpenGraphics, /* 0.9.7 */ + .domainOpenGraphicsFD = remoteDomainOpenGraphicsFD, /* 1.2.8 */ .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 5c316fb576..6dc2d29250 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2733,6 +2733,12 @@ struct remote_domain_open_graphics_args { unsigned int flags; }; +struct remote_domain_open_graphics_fd_args { + remote_nonnull_domain dom; + unsigned int idx; + unsigned int flags; +}; + struct remote_node_suspend_for_duration_args { unsigned int target; unsigned hyper duration; @@ -5420,5 +5426,12 @@ enum remote_procedure { * @generate: both * @acl: connect:write */ - REMOTE_PROC_CONNECT_GET_DOMAIN_CAPABILITIES = 342 + REMOTE_PROC_CONNECT_GET_DOMAIN_CAPABILITIES = 342, + + /** + * @generate: none + * @acl: domain:open_graphics + */ + REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD = 343 + }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 9bf09b8417..38bf0b8582 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2153,6 +2153,11 @@ struct remote_domain_open_graphics_args { u_int idx; u_int flags; }; +struct remote_domain_open_graphics_fd_args { + remote_nonnull_domain dom; + u_int idx; + u_int flags; +}; struct remote_node_suspend_for_duration_args { u_int target; uint64_t duration; @@ -2862,4 +2867,5 @@ enum remote_procedure { REMOTE_PROC_NODE_GET_FREE_PAGES = 340, REMOTE_PROC_NETWORK_GET_DHCP_LEASES = 341, REMOTE_PROC_CONNECT_GET_DOMAIN_CAPABILITIES = 342, + REMOTE_PROC_DOMAIN_OPEN_GRAPHICS_FD = 343, }; diff --git a/src/rpc/virnetmessage.c b/src/rpc/virnetmessage.c index 19b2d6ce21..5c57128c13 100644 --- a/src/rpc/virnetmessage.c +++ b/src/rpc/virnetmessage.c @@ -564,3 +564,29 @@ int virNetMessageDupFD(virNetMessagePtr msg, } return fd; } + +int virNetMessageAddFD(virNetMessagePtr msg, + int fd) +{ + int newfd = -1; + + if ((newfd = dup(fd)) < 0) { + virReportSystemError(errno, + _("Unable to duplicate FD %d"), + fd); + goto error; + } + + if (virSetInherit(newfd, false) < 0) { + virReportSystemError(errno, + _("Cannot set close-on-exec %d"), + newfd); + goto error; + } + if (VIR_APPEND_ELEMENT(msg->fds, msg->nfds, newfd) < 0) + goto error; + return 0; + error: + VIR_FORCE_CLOSE(newfd); + return -1; +} diff --git a/src/rpc/virnetmessage.h b/src/rpc/virnetmessage.h index c94dddc259..89a2ebf716 100644 --- a/src/rpc/virnetmessage.h +++ b/src/rpc/virnetmessage.h @@ -96,4 +96,7 @@ void virNetMessageSaveError(virNetMessageErrorPtr rerr) int virNetMessageDupFD(virNetMessagePtr msg, size_t slot); +int virNetMessageAddFD(virNetMessagePtr msg, + int fd); + #endif /* __VIR_NET_MESSAGE_H__ */ -- GitLab