From: "Daniel P. Berrange" <berrange(a)redhat.com>
The virDomainOpenGraphics API allows a libvirt client to pass in
a file descriptor for an open socket pair, and get it connected
to the graphics display of the guest. This is limited to working
with local libvirt hypervisors connected over a UNIX domain
socket, since it will use UNIX FD passing
* include/libvirt/libvirt.h.in: Define virDomainOpenGraphics
* src/driver.h: Define driver for virDomainOpenGraphics
* src/libvirt_public.syms, src/libvirt.c: Entry point for
virDomainOpenGraphics
* src/libvirt_internal.h: VIR_DRV_FEATURE_FD_PASSING
---
include/libvirt/libvirt.h.in | 9 ++++
src/driver.h | 6 +++
src/libvirt.c | 85 ++++++++++++++++++++++++++++++++++++++++++
src/libvirt_internal.h | 5 ++
src/libvirt_public.syms | 1 +
5 files changed, 106 insertions(+), 0 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 7102bce..917c64d 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -3140,6 +3140,15 @@ int virDomainOpenConsole(virDomainPtr dom,
virStreamPtr st,
unsigned int flags);
+typedef enum {
+ VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH = (1 << 0),
+} virDomainOpenGraphicsFlags;
+
+int virDomainOpenGraphics(virDomainPtr dom,
+ unsigned int idx,
+ int fd,
+ unsigned int flags);
+
int virDomainInjectNMI(virDomainPtr domain, unsigned int flags);
diff --git a/src/driver.h b/src/driver.h
index b899d0e..4c14aaa 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -632,6 +632,11 @@ typedef int
const char *dev_name,
virStreamPtr st,
unsigned int flags);
+typedef int
+ (*virDrvDomainOpenGraphics)(virDomainPtr dom,
+ unsigned int idx,
+ int fd,
+ unsigned int flags);
typedef int
(*virDrvDomainInjectNMI)(virDomainPtr dom, unsigned int flags);
@@ -881,6 +886,7 @@ struct _virDriver {
virDrvDomainQemuMonitorCommand qemuDomainMonitorCommand;
virDrvDomainQemuAttach qemuDomainAttach;
virDrvDomainOpenConsole domainOpenConsole;
+ virDrvDomainOpenGraphics domainOpenGraphics;
virDrvDomainInjectNMI domainInjectNMI;
virDrvDomainMigrateBegin3 domainMigrateBegin3;
virDrvDomainMigratePrepare3 domainMigratePrepare3;
diff --git a/src/libvirt.c b/src/libvirt.c
index a6bcee6..e9d1a29 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -16964,3 +16964,88 @@ error:
virDispatchError(dom->conn);
return -1;
}
+
+
+/**
+ * virDomainOpenGraphics:
+ * @dom: pointer to domain object
+ * @idx: index of graphics config to open
+ * @fd: file descriptor to attach graphics to
+ * @flags: flags to control open operation
+ *
+ * This will attempt to connect the file descriptor @fd, to
+ * the graphics backend of @dom. If @dom has multiple graphics
+ * backends configured, then @idx will determine which one is
+ * opened, starting from @idx 0.
+ *
+ * To disable any authentication, pass the VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH
+ * constant for @flags.
+ *
+ * The caller should use an anonymous socketpair to open
+ * @fd before invocation.
+ *
+ * This method can only be used when connected to a local
+ * libvirt hypervisor, over a UNIX domain socket. Attempts
+ * to use this method over a TCP connection will always fail
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int virDomainOpenGraphics(virDomainPtr dom,
+ unsigned int idx,
+ int fd,
+ unsigned int flags)
+{
+ struct stat sb;
+ VIR_DOMAIN_DEBUG(dom, "idx=%u, fd=%d, flags=%x",
+ idx, fd, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_DOMAIN(dom)) {
+ virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ if (fd < 0) {
+ virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if (fstat(fd, &sb) < 0) {
+ virReportSystemError(errno,
+ _("Unable to access file descriptor %d"), fd);
+ goto error;
+ }
+
+ if (!S_ISSOCK(sb.st_mode)) {
+ virLibDomainError(VIR_ERR_INVALID_ARG,
+ _("File descriptor %d must be a socket"), fd);
+ goto error;
+ }
+
+ if (dom->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (!VIR_DRV_SUPPORTS_FEATURE(dom->conn->driver, dom->conn,
+ VIR_DRV_FEATURE_FD_PASSING)) {
+ virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ goto error;
+ }
+
+ if (dom->conn->driver->domainOpenGraphics) {
+ int ret;
+ ret = dom->conn->driver->domainOpenGraphics(dom, idx, fd, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(dom->conn);
+ return -1;
+}
diff --git a/src/libvirt_internal.h b/src/libvirt_internal.h
index 6e44341..0117c5b 100644
--- a/src/libvirt_internal.h
+++ b/src/libvirt_internal.h
@@ -79,6 +79,11 @@ enum {
* to domain configuration, i.e., starting from Begin3 and not Perform3.
*/
VIR_DRV_FEATURE_MIGRATE_CHANGE_PROTECTION = 7,
+
+ /*
+ * Support for file descriptor passing
+ */
+ VIR_DRV_FEATURE_FD_PASSING = 8
};
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 9762fc4..caa21a2 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -495,6 +495,7 @@ LIBVIRT_0.9.7 {
virDomainSnapshotGetParent;
virDomainSnapshotListChildrenNames;
virDomainSnapshotNumChildren;
+ virDomainOpenGraphics;
} LIBVIRT_0.9.5;
# .... define new API here using predicted next version number ....
--
1.7.6.4