mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
api: Add API to tunnel a guest channel via stream
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.
This commit is contained in:
parent
54df702ed0
commit
d52add46ed
@ -4547,6 +4547,22 @@ int virDomainOpenConsole(virDomainPtr dom,
|
|||||||
virStreamPtr st,
|
virStreamPtr st,
|
||||||
unsigned int flags);
|
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 {
|
typedef enum {
|
||||||
VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH = (1 << 0),
|
VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH = (1 << 0),
|
||||||
} virDomainOpenGraphicsFlags;
|
} virDomainOpenGraphicsFlags;
|
||||||
|
@ -716,6 +716,12 @@ typedef int
|
|||||||
const char *dev_name,
|
const char *dev_name,
|
||||||
virStreamPtr st,
|
virStreamPtr st,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
typedef int
|
||||||
|
(*virDrvDomainOpenChannel)(virDomainPtr dom,
|
||||||
|
const char *name,
|
||||||
|
virStreamPtr st,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
typedef int
|
typedef int
|
||||||
(*virDrvDomainOpenGraphics)(virDomainPtr dom,
|
(*virDrvDomainOpenGraphics)(virDomainPtr dom,
|
||||||
unsigned int idx,
|
unsigned int idx,
|
||||||
@ -1078,6 +1084,7 @@ struct _virDriver {
|
|||||||
virDrvDomainQemuAttach qemuDomainAttach;
|
virDrvDomainQemuAttach qemuDomainAttach;
|
||||||
virDrvDomainQemuAgentCommand qemuDomainArbitraryAgentCommand;
|
virDrvDomainQemuAgentCommand qemuDomainArbitraryAgentCommand;
|
||||||
virDrvDomainOpenConsole domainOpenConsole;
|
virDrvDomainOpenConsole domainOpenConsole;
|
||||||
|
virDrvDomainOpenChannel domainOpenChannel;
|
||||||
virDrvDomainOpenGraphics domainOpenGraphics;
|
virDrvDomainOpenGraphics domainOpenGraphics;
|
||||||
virDrvDomainInjectNMI domainInjectNMI;
|
virDrvDomainInjectNMI domainInjectNMI;
|
||||||
virDrvDomainMigrateBegin3 domainMigrateBegin3;
|
virDrvDomainMigrateBegin3 domainMigrateBegin3;
|
||||||
|
@ -19117,6 +19117,67 @@ error:
|
|||||||
return -1;
|
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:
|
* virDomainBlockJobAbort:
|
||||||
* @dom: pointer to domain object
|
* @dom: pointer to domain object
|
||||||
|
@ -580,4 +580,9 @@ LIBVIRT_1.0.1 {
|
|||||||
virDomainSendProcessSignal;
|
virDomainSendProcessSignal;
|
||||||
} LIBVIRT_1.0.0;
|
} LIBVIRT_1.0.0;
|
||||||
|
|
||||||
|
LIBVIRT_1.0.2 {
|
||||||
|
global:
|
||||||
|
virDomainOpenChannel;
|
||||||
|
} LIBVIRT_1.0.1;
|
||||||
|
|
||||||
# .... define new API here using predicted next version number ....
|
# .... define new API here using predicted next version number ....
|
||||||
|
@ -6121,6 +6121,7 @@ static virDriver remote_driver = {
|
|||||||
.qemuDomainAttach = qemuDomainAttach, /* 0.9.4 */
|
.qemuDomainAttach = qemuDomainAttach, /* 0.9.4 */
|
||||||
.qemuDomainArbitraryAgentCommand = qemuDomainAgentCommand, /* 0.10.0 */
|
.qemuDomainArbitraryAgentCommand = qemuDomainAgentCommand, /* 0.10.0 */
|
||||||
.domainOpenConsole = remoteDomainOpenConsole, /* 0.8.6 */
|
.domainOpenConsole = remoteDomainOpenConsole, /* 0.8.6 */
|
||||||
|
.domainOpenChannel = remoteDomainOpenChannel, /* 1.0.2 */
|
||||||
.domainOpenGraphics = remoteDomainOpenGraphics, /* 0.9.7 */
|
.domainOpenGraphics = remoteDomainOpenGraphics, /* 0.9.7 */
|
||||||
.domainInjectNMI = remoteDomainInjectNMI, /* 0.9.2 */
|
.domainInjectNMI = remoteDomainInjectNMI, /* 0.9.2 */
|
||||||
.domainMigrateBegin3 = remoteDomainMigrateBegin3, /* 0.9.2 */
|
.domainMigrateBegin3 = remoteDomainMigrateBegin3, /* 0.9.2 */
|
||||||
|
@ -2439,6 +2439,12 @@ struct remote_domain_open_console_args {
|
|||||||
unsigned int flags;
|
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 {
|
struct remote_storage_vol_upload_args {
|
||||||
remote_nonnull_storage_vol vol;
|
remote_nonnull_storage_vol vol;
|
||||||
unsigned hyper offset;
|
unsigned hyper offset;
|
||||||
@ -3042,7 +3048,8 @@ enum remote_procedure {
|
|||||||
REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK = 292, /* autogen autogen */
|
REMOTE_PROC_DOMAIN_EVENT_PMSUSPEND_DISK = 292, /* autogen autogen */
|
||||||
REMOTE_PROC_NODE_GET_CPU_MAP = 293, /* skipgen skipgen */
|
REMOTE_PROC_NODE_GET_CPU_MAP = 293, /* skipgen skipgen */
|
||||||
REMOTE_PROC_DOMAIN_FSTRIM = 294, /* autogen autogen */
|
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 ?
|
* Notice how the entries are grouped in sets of 10 ?
|
||||||
|
@ -1873,6 +1873,11 @@ struct remote_domain_open_console_args {
|
|||||||
remote_string dev_name;
|
remote_string dev_name;
|
||||||
u_int flags;
|
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 {
|
struct remote_storage_vol_upload_args {
|
||||||
remote_nonnull_storage_vol vol;
|
remote_nonnull_storage_vol vol;
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
@ -2447,4 +2452,5 @@ enum remote_procedure {
|
|||||||
REMOTE_PROC_NODE_GET_CPU_MAP = 293,
|
REMOTE_PROC_NODE_GET_CPU_MAP = 293,
|
||||||
REMOTE_PROC_DOMAIN_FSTRIM = 294,
|
REMOTE_PROC_DOMAIN_FSTRIM = 294,
|
||||||
REMOTE_PROC_DOMAIN_SEND_PROCESS_SIGNAL = 295,
|
REMOTE_PROC_DOMAIN_SEND_PROCESS_SIGNAL = 295,
|
||||||
|
REMOTE_PROC_DOMAIN_OPEN_CHANNEL = 296,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user