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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list