diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index cc3fe13f0b..09c89c5be0 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -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; diff --git a/src/driver.h b/src/driver.h index 64d652f829..01c95cfb2b 100644 --- a/src/driver.h +++ b/src/driver.h @@ -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; diff --git a/src/libvirt.c b/src/libvirt.c index bf674d1b4b..6d1da124c1 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -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 diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index e3d63d3b04..21075198cd 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 ae861cca40..c078cb54e6 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 bdad9f0bb0..90357765d9 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 e7d05b8e4d..91414d4b93 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, };