Add a rather universal API implemented via typed params that will allow
to query the guest agent for the state and possibly other aspects of
guest vcpus.
---
include/libvirt/libvirt-domain.h | 5 ++++
src/driver-hypervisor.h | 7 +++++
src/libvirt-domain.c | 56 ++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 1 +
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 21 ++++++++++++++-
src/remote_protocol-structs | 11 ++++++++
7 files changed, 101 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index cba4fa5..5605a94 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -4097,4 +4097,9 @@ int virDomainRename(virDomainPtr dom,
const char *new_name,
unsigned int flags);
+int virDomainGetGuestVcpus(virDomainPtr domain,
+ virTypedParameterPtr *params,
+ unsigned int *nparams,
+ unsigned int flags);
+
#endif /* __VIR_LIBVIRT_DOMAIN_H__ */
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 5ab5775..93af2b6 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1239,6 +1239,12 @@ typedef int
(*virDrvConnectUnregisterCloseCallback)(virConnectPtr conn,
virConnectCloseFunc cb);
+typedef int
+(*virDrvDomainGetGuestVcpus)(virDomainPtr domain,
+ virTypedParameterPtr *params,
+ unsigned int *nparams,
+ unsigned int flags);
+
typedef struct _virHypervisorDriver virHypervisorDriver;
typedef virHypervisorDriver *virHypervisorDriverPtr;
@@ -1475,6 +1481,7 @@ struct _virHypervisorDriver {
virDrvConnectRegisterCloseCallback connectRegisterCloseCallback;
virDrvConnectUnregisterCloseCallback connectUnregisterCloseCallback;
virDrvDomainMigrateStartPostCopy domainMigrateStartPostCopy;
+ virDrvDomainGetGuestVcpus domainGetGuestVcpus;
};
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 73ae369..0971a96 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -11835,3 +11835,59 @@ virDomainInterfaceFree(virDomainInterfacePtr iface)
VIR_FREE(iface);
}
+
+
+/**
+ * virDomainGetGuestVcpus:
+ * @domain: pointer to domain object
+ * @params: Pointer that will be filled with an array of typed parameters
+ * @nparams: pointer filled with number of elements in @params
+ * @flags: currently unused, callers shall pass 0
+ *
+ * Queries the guest agent for state and information regarding vCPUs from
+ * guest's perspective. The reported data depends on the guest agent
+ * implementation.
+ *
+ * Reported fields stored in @params:
+ * 'vcpus': string containing bitmap representing vCPU ids as reported by the
+ * guest
+ * 'online': string containing bitmap representing online vCPUs as reported
+ * by the guest agent.
+ * 'offlinable': string containing bitmap representing ids of vCPUs that can be
+ * offlined
+ *
+ * This API requires the VM to run. The caller is responsible for calling
+ * virTypedParamsFree to free memory returned in @params.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int
+virDomainGetGuestVcpus(virDomainPtr domain,
+ virTypedParameterPtr *params,
+ unsigned int *nparams,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%p, flags=%x",
+ params, nparams, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ virCheckNonNullArgGoto(params, error);
+ virCheckNonNullArgGoto(nparams, error);
+
+ if (domain->conn->driver->domainGetGuestVcpus) {
+ int ret;
+ ret = domain->conn->driver->domainGetGuestVcpus(domain, params,
nparams,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(domain->conn);
+ return -1;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 06011ce..30801c5 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -736,6 +736,7 @@ LIBVIRT_2.0.0 {
global:
virConnectStoragePoolEventRegisterAny;
virConnectStoragePoolEventDeregisterAny;
+ virDomainGetGuestVcpus;
} LIBVIRT_1.3.3;
# .... define new API here using predicted next version number ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 84b6d58..6a580c6 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -7981,6 +7981,7 @@ static virHypervisorDriver hypervisor_driver = {
.connectRegisterCloseCallback = remoteConnectRegisterCloseCallback, /* 1.3.2 */
.connectUnregisterCloseCallback = remoteConnectUnregisterCloseCallback, /* 1.3.2 */
.domainMigrateStartPostCopy = remoteDomainMigrateStartPostCopy, /* 1.3.3 */
+ .domainGetGuestVcpus = remoteDomainGetGuestVcpus, /* 2.0.0 */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index cec6bd2..f72918d 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -250,6 +250,9 @@ const REMOTE_DOMAIN_INTERFACE_MAX = 2048;
/* Upper limit on number of IP addresses per interface */
const REMOTE_DOMAIN_IP_ADDR_MAX = 2048;
+/* Upper limit on number of guest vcpu information entries */
+const REMOTE_DOMAIN_GUEST_VCPU_PARAMS_MAX = 64;
+
/* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */
typedef opaque remote_uuid[VIR_UUID_BUFLEN];
@@ -3292,6 +3295,16 @@ struct remote_domain_event_callback_device_removal_failed_msg {
remote_nonnull_string devAlias;
};
+struct remote_domain_get_guest_vcpus_args {
+ remote_nonnull_domain dom;
+ unsigned int flags;
+};
+
+struct remote_domain_get_guest_vcpus_ret {
+ remote_typed_param params<REMOTE_DOMAIN_GUEST_VCPU_PARAMS_MAX>; /*
alloc@1@unsigned int@2 */
+};
+
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -5839,5 +5852,11 @@ enum remote_procedure {
* @generate: both
* @acl: none
*/
- REMOTE_PROC_STORAGE_POOL_EVENT_LIFECYCLE = 370
+ REMOTE_PROC_STORAGE_POOL_EVENT_LIFECYCLE = 370,
+
+ /**
+ * @generate: both
+ * @acl: domain:write
+ */
+ REMOTE_PROC_DOMAIN_GET_GUEST_VCPUS = 371
};
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 3934e07..4e603db 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2751,6 +2751,16 @@ struct remote_domain_event_callback_device_removal_failed_msg {
remote_nonnull_domain dom;
remote_nonnull_string devAlias;
};
+struct remote_domain_get_guest_vcpus_args {
+ remote_nonnull_domain dom;
+ u_int flags;
+};
+struct remote_domain_get_guest_vcpus_ret {
+ struct {
+ u_int params_len;
+ remote_typed_param * params_val;
+ } params;
+};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3122,4 +3132,5 @@ enum remote_procedure {
REMOTE_PROC_CONNECT_STORAGE_POOL_EVENT_REGISTER_ANY = 368,
REMOTE_PROC_CONNECT_STORAGE_POOL_EVENT_DEREGISTER_ANY = 369,
REMOTE_PROC_STORAGE_POOL_EVENT_LIFECYCLE = 370,
+ REMOTE_PROC_DOMAIN_GET_GUEST_VCPUS = 371,
};
--
2.8.3