]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
api: Add API to tunnel a guest channel via stream
authorJohn Eckersberg <jeckersb@redhat.com>
Thu, 13 Dec 2012 16:24:16 +0000 (11:24 -0500)
committerEric Blake <eblake@redhat.com>
Sat, 5 Jan 2013 00:10:55 +0000 (17:10 -0700)
This patch adds a new API, virDomainOpenChannel, that uses streams to
connect to a virtio channel on a guest.  This creates a secure
communication channel between a guest and a libvirt client.

This behaves the same as virDomainOpenConsole, except on channels
instead of console/serial/parallel devices.

include/libvirt/libvirt.h.in
src/driver.h
src/libvirt.c
src/libvirt_public.syms
src/remote/remote_driver.c
src/remote/remote_protocol.x
src/remote_protocol-structs

index cc3fe13f0b8196ba8ad2dd95b67714ce740df10e..09c89c5be0c103a4d6b92b8a774c53f91db36d8a 100644 (file)
@@ -4547,6 +4547,22 @@ int virDomainOpenConsole(virDomainPtr dom,
                          virStreamPtr st,
                          unsigned int flags);
 
+/**
+ * virDomainChannelFlags
+ *
+ * Since 1.0.2
+ */
+typedef enum {
+    VIR_DOMAIN_CHANNEL_FORCE = (1 << 0), /* abort a (possibly) active channel
+                                            connection to force a new
+                                            connection */
+} virDomainChannelFlags;
+
+int virDomainOpenChannel(virDomainPtr dom,
+                         const char *name,
+                         virStreamPtr st,
+                         unsigned int flags);
+
 typedef enum {
     VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH = (1 << 0),
 } virDomainOpenGraphicsFlags;
index 64d652f82929a2666a7919a92b57d6cbce2cbbf4..01c95cfb2b2c67b740fe4e8d903726752e9749f7 100644 (file)
@@ -716,6 +716,12 @@ typedef int
                                const char *dev_name,
                                virStreamPtr st,
                                unsigned int flags);
+typedef int
+    (*virDrvDomainOpenChannel)(virDomainPtr dom,
+                               const char *name,
+                               virStreamPtr st,
+                               unsigned int flags);
+
 typedef int
     (*virDrvDomainOpenGraphics)(virDomainPtr dom,
                                 unsigned int idx,
@@ -1078,6 +1084,7 @@ struct _virDriver {
     virDrvDomainQemuAttach              qemuDomainAttach;
     virDrvDomainQemuAgentCommand        qemuDomainArbitraryAgentCommand;
     virDrvDomainOpenConsole             domainOpenConsole;
+    virDrvDomainOpenChannel             domainOpenChannel;
     virDrvDomainOpenGraphics            domainOpenGraphics;
     virDrvDomainInjectNMI               domainInjectNMI;
     virDrvDomainMigrateBegin3           domainMigrateBegin3;
index bf674d1b4b388ba7ee2dff85f62c4d3c71cc6f62..6d1da124c15d431bac8dc1698acc00f3ea01adb4 100644 (file)
@@ -19117,6 +19117,67 @@ error:
     return -1;
 }
 
+/**
+ * virDomainOpenChannel:
+ * @dom: a domain object
+ * @name: the channel name, or NULL
+ * @st: a stream to associate with the channel
+ * @flags: bitwise-OR of virDomainChannelFlags
+ *
+ * This opens the host interface associated with a channel device on a
+ * guest, if the host interface is supported.  If @name is given, it
+ * can match either the device alias (e.g. "channel0"), or the virtio
+ * target name (e.g. "org.qemu.guest_agent.0").  If @name is omitted,
+ * then the first channel is opened. The channel is associated with
+ * the passed in @st stream, which should have been opened in
+ * non-blocking mode for bi-directional I/O.
+ *
+ * By default, when @flags is 0, the open will fail if libvirt detects
+ * that the channel is already in use by another client; passing
+ * VIR_DOMAIN_CHANNEL_FORCE will cause libvirt to forcefully remove the
+ * other client prior to opening this channel.
+ *
+ * Returns 0 if the channel was opened, -1 on error
+ */
+int virDomainOpenChannel(virDomainPtr dom,
+                         const char *name,
+                         virStreamPtr st,
+                         unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(dom, "name=%s, st=%p, flags=%x",
+                     NULLSTR(name), st, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_DOMAIN(dom)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+
+    conn = dom->conn;
+    if (conn->flags & VIR_CONNECT_RO) {
+        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+
+    if (conn->driver->domainOpenChannel) {
+        int ret;
+        ret = conn->driver->domainOpenChannel(dom, name, st, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(conn);
+    return -1;
+}
+
 /**
  * virDomainBlockJobAbort:
  * @dom: pointer to domain object
index e3d63d3b04f04ecd45a93d63d1d9068ce73533d6..21075198cde0ca673b640b9fddd4d1b172ed36bf 100644 (file)
@@ -580,4 +580,9 @@ LIBVIRT_1.0.1 {
         virDomainSendProcessSignal;
 } LIBVIRT_1.0.0;
 
+LIBVIRT_1.0.2 {
+    global:
+        virDomainOpenChannel;
+} LIBVIRT_1.0.1;
+
 # .... define new API here using predicted next version number ....
index ae861cca40cd5a341d4acc851561db54fd80d8c1..c078cb54e6e083644d703a38e0dc9c21269a71ab 100644 (file)
@@ -6121,6 +6121,7 @@ static virDriver remote_driver = {
     .qemuDomainAttach = qemuDomainAttach, /* 0.9.4 */
     .qemuDomainArbitraryAgentCommand = qemuDomainAgentCommand, /* 0.10.0 */
     .domainOpenConsole = remoteDomainOpenConsole, /* 0.8.6 */
+    .domainOpenChannel = remoteDomainOpenChannel, /* 1.0.2 */
     .domainOpenGraphics = remoteDomainOpenGraphics, /* 0.9.7 */
     .domainInjectNMI = remoteDomainInjectNMI, /* 0.9.2 */
     .domainMigrateBegin3 = remoteDomainMigrateBegin3, /* 0.9.2 */
index bdad9f0bb0e1287edbbbdfbb972c3d3543f95000..90357765d93b9d34f761af092668135a004f6578 100644 (file)
@@ -2439,6 +2439,12 @@ struct remote_domain_open_console_args {
     unsigned int flags;
 };
 
+struct remote_domain_open_channel_args {
+    remote_nonnull_domain dom;
+    remote_string name;
+    unsigned int flags;
+};
+
 struct remote_storage_vol_upload_args {
     remote_nonnull_storage_vol vol;
     unsigned hyper offset;
@@ -3042,7 +3048,8 @@ enum remote_procedure {
     REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK = 292, /* autogen autogen */
     REMOTE_PROC_NODE_GET_CPU_MAP = 293, /* skipgen skipgen */
     REMOTE_PROC_DOMAIN_FSTRIM = 294, /* autogen autogen */
-    REMOTE_PROC_DOMAIN_SEND_PROCESS_SIGNAL = 295 /* autogen autogen */
+    REMOTE_PROC_DOMAIN_SEND_PROCESS_SIGNAL = 295, /* autogen autogen */
+    REMOTE_PROC_DOMAIN_OPEN_CHANNEL = 296 /* autogen autogen | readstream@2 */
 
     /*
      * Notice how the entries are grouped in sets of 10 ?
index e7d05b8e4d740596ffa23dd03fc87baf8ac75efe..91414d4b93eda029ad1576cd6da0ba043352be25 100644 (file)
@@ -1873,6 +1873,11 @@ struct remote_domain_open_console_args {
         remote_string              dev_name;
         u_int                      flags;
 };
+struct remote_domain_open_channel_args {
+        remote_nonnull_domain      dom;
+        remote_string              name;
+        u_int                      flags;
+};
 struct remote_storage_vol_upload_args {
         remote_nonnull_storage_vol vol;
         uint64_t                   offset;
@@ -2447,4 +2452,5 @@ enum remote_procedure {
         REMOTE_PROC_NODE_GET_CPU_MAP = 293,
         REMOTE_PROC_DOMAIN_FSTRIM = 294,
         REMOTE_PROC_DOMAIN_SEND_PROCESS_SIGNAL = 295,
+        REMOTE_PROC_DOMAIN_OPEN_CHANNEL = 296,
 };