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 | 16 ++++++++++++
src/driver.h | 7 +++++
src/libvirt.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 5 ++++
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 9 ++++++-
src/remote_protocol-structs | 6 +++++
7 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index c6739d7..cc7ebb9 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -4548,6 +4548,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;
diff --git a/src/driver.h b/src/driver.h
index 64d652f..01c95cf 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -717,6 +717,12 @@ typedef int
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,
int fd,
@@ -1078,6 +1084,7 @@ struct _virDriver {
virDrvDomainQemuAttach qemuDomainAttach;
virDrvDomainQemuAgentCommand qemuDomainArbitraryAgentCommand;
virDrvDomainOpenConsole domainOpenConsole;
+ virDrvDomainOpenChannel domainOpenChannel;
virDrvDomainOpenGraphics domainOpenGraphics;
virDrvDomainInjectNMI domainInjectNMI;
virDrvDomainMigrateBegin3 domainMigrateBegin3;
diff --git a/src/libvirt.c b/src/libvirt.c
index 4215971..b656173 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -19118,6 +19118,67 @@ error:
}
/**
+ * 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
* @disk: path to the block device, or device shorthand
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index e3d63d3..2107519 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -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 ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 5cc7e32..da1f755 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -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 */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index bdad9f0..9035776 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -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 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index e7d05b8..91414d4 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -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,
};
--
1.7.11.7