]> xenbits.xensource.com Git - libvirt.git/commitdiff
Introduce the virDomainOpenGraphics API
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 21 Oct 2011 08:00:37 +0000 (09:00 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 28 Oct 2011 09:23:51 +0000 (10:23 +0100)
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
src/driver.h
src/libvirt.c
src/libvirt_internal.h
src/libvirt_public.syms

index 7102bce54e1e8182b96b5597e0d76f8a84f73263..917c64de102bba8ae4e37196f2e225fd637999ff 100644 (file)
@@ -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);
 
 
index b899d0ea1f8c4fb2963f11393821728dd861da6b..4c14aaa8e9511684dd6e8912503a2b3f55eaa17d 100644 (file)
@@ -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;
index a6bcee69b42614bff65923e2c43aad8d33223981..e9d1a299f2bad0fea109b20c19cffdbc792b594d 100644 (file)
@@ -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;
+}
index 6e44341289c55e7a9e58a8e87743188bb37358c6..0117c5b1ca15f953685a2ae41732cad123725bbd 100644 (file)
@@ -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
 };
 
 
index 9762fc47b2027b2bb7b315b07076e38e792005bb..bcefb100f655f0bbf4b524151b1b044dbc30bc55 100644 (file)
@@ -491,6 +491,7 @@ LIBVIRT_0.9.5 {
 
 LIBVIRT_0.9.7 {
     global:
+        virDomainOpenGraphics;
         virDomainReset;
         virDomainSnapshotGetParent;
         virDomainSnapshotListChildrenNames;