mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 19:41:16 +00:00
lib: Introduce API for retrieving bulk domain stats
The motivation for this API is that management layers that use libvirt usually poll for statistics using various split up APIs we currently provide. To get all the necessary stuff, the app needs to issue a lot of calls and aggregate the results. The APIs I'm introducing here: 1) Returns data in a format that we can expand in the future and is (pseudo) hierarchical. The data is returned as typed parameters where the fields are constructed as dot-separated strings containing names and other stuff in a list of typed params. 2) Stats for multiple (all) domains can be queried at once and are returned in one call. This will decrease the overhead necessary to issue multiple calls per domain multiplied by the count of domains. 3) Selectable (bit mask) fields in the returned format. This will allow to retrieve only specific stats according to the app's need. The stats groups will be enabled using a bit field @stats passed as the function argument. A few sample stats groups that this API will support: VIR_DOMAIN_STATS_STATE VIR_DOMAIN_STATS_CPU VIR_DOMAIN_STATS_BLOCK VIR_DOMAIN_STATS_INTERFACE (Note that this is only an example, the initial implementation supports only VIR_DOMAIN_STATS_STATE while others will be added later.) the returned typed params will use the following scheme state.state = VIR_DOMAIN_RUNNING state.reason = VIR_DOMAIN_RUNNING_BOOTED (the actual values according to the enum) cpu.count = 8 cpu.0.state = running cpu.0.time = 1234
This commit is contained in:
parent
27a20b6c1a
commit
76a5bc4eef
@ -2501,6 +2501,30 @@ int virDomainDetachDeviceFlags(virDomainPtr domain,
|
|||||||
int virDomainUpdateDeviceFlags(virDomainPtr domain,
|
int virDomainUpdateDeviceFlags(virDomainPtr domain,
|
||||||
const char *xml, unsigned int flags);
|
const char *xml, unsigned int flags);
|
||||||
|
|
||||||
|
typedef struct _virDomainStatsRecord virDomainStatsRecord;
|
||||||
|
typedef virDomainStatsRecord *virDomainStatsRecordPtr;
|
||||||
|
struct _virDomainStatsRecord {
|
||||||
|
virDomainPtr dom;
|
||||||
|
virTypedParameterPtr params;
|
||||||
|
int nparams;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIR_DOMAIN_STATS_STATE = (1 << 0), /* return domain state */
|
||||||
|
} virDomainStatsTypes;
|
||||||
|
|
||||||
|
int virConnectGetAllDomainStats(virConnectPtr conn,
|
||||||
|
unsigned int stats,
|
||||||
|
virDomainStatsRecordPtr **retStats,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
|
int virDomainListGetStats(virDomainPtr *doms,
|
||||||
|
unsigned int stats,
|
||||||
|
virDomainStatsRecordPtr **retStats,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
|
void virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BlockJob API
|
* BlockJob API
|
||||||
*/
|
*/
|
||||||
|
@ -1197,6 +1197,14 @@ typedef int
|
|||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(*virDrvConnectGetAllDomainStats)(virConnectPtr conn,
|
||||||
|
virDomainPtr *doms,
|
||||||
|
unsigned int ndoms,
|
||||||
|
unsigned int stats,
|
||||||
|
virDomainStatsRecordPtr **retStats,
|
||||||
|
unsigned int flags);
|
||||||
|
|
||||||
typedef struct _virDriver virDriver;
|
typedef struct _virDriver virDriver;
|
||||||
typedef virDriver *virDriverPtr;
|
typedef virDriver *virDriverPtr;
|
||||||
|
|
||||||
@ -1418,6 +1426,7 @@ struct _virDriver {
|
|||||||
virDrvDomainSetTime domainSetTime;
|
virDrvDomainSetTime domainSetTime;
|
||||||
virDrvNodeGetFreePages nodeGetFreePages;
|
virDrvNodeGetFreePages nodeGetFreePages;
|
||||||
virDrvConnectGetDomainCapabilities connectGetDomainCapabilities;
|
virDrvConnectGetDomainCapabilities connectGetDomainCapabilities;
|
||||||
|
virDrvConnectGetAllDomainStats connectGetAllDomainStats;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
186
src/libvirt.c
186
src/libvirt.c
@ -21399,3 +21399,189 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
|
|||||||
virDispatchError(conn);
|
virDispatchError(conn);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectGetAllDomainStats:
|
||||||
|
* @conn: pointer to the hypervisor connection
|
||||||
|
* @stats: stats to return, binary-OR of virDomainStatsTypes
|
||||||
|
* @retStats: Pointer that will be filled with the array of returned stats.
|
||||||
|
* @flags: extra flags; not used yet, so callers should always pass 0
|
||||||
|
*
|
||||||
|
* Query statistics for all domains on a given connection.
|
||||||
|
*
|
||||||
|
* Report statistics of various parameters for a running VM according to @stats
|
||||||
|
* field. The statistics are returned as an array of structures for each queried
|
||||||
|
* domain. The structure contains an array of typed parameters containing the
|
||||||
|
* individual statistics. The typed parameter name for each statistic field
|
||||||
|
* consists of a dot-separated string containing name of the requested group
|
||||||
|
* followed by a group specific description of the statistic value.
|
||||||
|
*
|
||||||
|
* The statistic groups are enabled using the @stats parameter which is a
|
||||||
|
* binary-OR of enum virDomainStatsTypes. The following groups are available
|
||||||
|
* (although not necessarily implemented for each hypervisor):
|
||||||
|
*
|
||||||
|
* VIR_DOMAIN_STATS_STATE: Return domain state and reason for entering that
|
||||||
|
* state. The typed parameter keys are in this format:
|
||||||
|
* "state.state" - state of the VM, returned as int from virDomainState enum
|
||||||
|
* "state.reason" - reason for entering given state, returned as int from
|
||||||
|
* virDomain*Reason enum corresponding to given state.
|
||||||
|
*
|
||||||
|
* Using 0 for @stats returns all stats groups supported by the given
|
||||||
|
* hypervisor.
|
||||||
|
*
|
||||||
|
* Returns the count of returned statistics structures on success, -1 on error.
|
||||||
|
* The requested data are returned in the @retStats parameter. The returned
|
||||||
|
* array should be freed by the caller. See virDomainStatsRecordListFree.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virConnectGetAllDomainStats(virConnectPtr conn,
|
||||||
|
unsigned int stats,
|
||||||
|
virDomainStatsRecordPtr **retStats,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
VIR_DEBUG("conn=%p, stats=0x%x, retStats=%p, flags=0x%x",
|
||||||
|
conn, stats, retStats, flags);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckConnectReturn(conn, -1);
|
||||||
|
virCheckNonNullArgGoto(retStats, cleanup);
|
||||||
|
|
||||||
|
if (!conn->driver->connectGetAllDomainStats) {
|
||||||
|
virReportUnsupportedError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = conn->driver->connectGetAllDomainStats(conn, NULL, 0, stats,
|
||||||
|
retStats, flags);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (ret < 0)
|
||||||
|
virDispatchError(conn);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainListGetStats:
|
||||||
|
* @doms: NULL terminated array of domains
|
||||||
|
* @stats: stats to return, binary-OR of virDomainStatsTypes
|
||||||
|
* @retStats: Pointer that will be filled with the array of returned stats.
|
||||||
|
* @flags: extra flags; not used yet, so callers should always pass 0
|
||||||
|
*
|
||||||
|
* Query statistics for domains provided by @doms. Note that all domains in
|
||||||
|
* @doms must share the same connection.
|
||||||
|
*
|
||||||
|
* Report statistics of various parameters for a running VM according to @stats
|
||||||
|
* field. The statistics are returned as an array of structures for each queried
|
||||||
|
* domain. The structure contains an array of typed parameters containing the
|
||||||
|
* individual statistics. The typed parameter name for each statistic field
|
||||||
|
* consists of a dot-separated string containing name of the requested group
|
||||||
|
* followed by a group specific description of the statistic value.
|
||||||
|
*
|
||||||
|
* The statistic groups are enabled using the @stats parameter which is a
|
||||||
|
* binary-OR of enum virDomainStatsTypes. The following groups are available
|
||||||
|
* (although not necessarily implemented for each hypervisor):
|
||||||
|
*
|
||||||
|
* VIR_DOMAIN_STATS_STATE: Return domain state and reason for entering that
|
||||||
|
* state. The typed parameter keys are in this format:
|
||||||
|
* "state.state" - state of the VM, returned as int from virDomainState enum
|
||||||
|
* "state.reason" - reason for entering given state, returned as int from
|
||||||
|
* virDomain*Reason enum corresponding to given state.
|
||||||
|
*
|
||||||
|
* Using 0 for @stats returns all stats groups supported by the given
|
||||||
|
* hypervisor.
|
||||||
|
*
|
||||||
|
* Returns the count of returned statistics structures on success, -1 on error.
|
||||||
|
* The requested data are returned in the @retStats parameter. The returned
|
||||||
|
* array should be freed by the caller. See virDomainStatsRecordListFree.
|
||||||
|
* Note that the count of returned stats may be less than the domain count
|
||||||
|
* provided via @doms.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virDomainListGetStats(virDomainPtr *doms,
|
||||||
|
unsigned int stats,
|
||||||
|
virDomainStatsRecordPtr **retStats,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
virConnectPtr conn = NULL;
|
||||||
|
virDomainPtr *nextdom = doms;
|
||||||
|
unsigned int ndoms = 0;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
VIR_DEBUG("doms=%p, stats=0x%x, retStats=%p, flags=0x%x",
|
||||||
|
doms, stats, retStats, flags);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckNonNullArgGoto(doms, cleanup);
|
||||||
|
virCheckNonNullArgGoto(retStats, cleanup);
|
||||||
|
|
||||||
|
if (!*doms) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG,
|
||||||
|
_("doms array in %s must contain at least one domain"),
|
||||||
|
__FUNCTION__);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = doms[0]->conn;
|
||||||
|
virCheckConnectReturn(conn, -1);
|
||||||
|
|
||||||
|
if (!conn->driver->connectGetAllDomainStats) {
|
||||||
|
virReportUnsupportedError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*nextdom) {
|
||||||
|
virDomainPtr dom = *nextdom;
|
||||||
|
|
||||||
|
virCheckDomainGoto(dom, cleanup);
|
||||||
|
|
||||||
|
if (dom->conn != conn) {
|
||||||
|
virReportError(VIR_ERR_INVALID_ARG,
|
||||||
|
_("domains in 'doms' array must belong to a "
|
||||||
|
"single connection in %s"), __FUNCTION__);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ndoms++;
|
||||||
|
nextdom++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = conn->driver->connectGetAllDomainStats(conn, doms, ndoms,
|
||||||
|
stats, retStats, flags);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (ret < 0)
|
||||||
|
virDispatchError(conn);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virDomainStatsRecordListFree:
|
||||||
|
* @stats: NULL terminated array of virDomainStatsRecords to free
|
||||||
|
*
|
||||||
|
* Convenience function to free a list of domain stats returned by
|
||||||
|
* virDomainListGetStats and virConnectGetAllDomainStats.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
virDomainStatsRecordListFree(virDomainStatsRecordPtr *stats)
|
||||||
|
{
|
||||||
|
virDomainStatsRecordPtr *next;
|
||||||
|
|
||||||
|
if (!stats)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (next = stats; *next; next++) {
|
||||||
|
virTypedParamsFree((*next)->params, (*next)->nparams);
|
||||||
|
virDomainFree((*next)->dom);
|
||||||
|
VIR_FREE(*next);
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_FREE(stats);
|
||||||
|
}
|
||||||
|
@ -671,8 +671,11 @@ LIBVIRT_1.2.7 {
|
|||||||
} LIBVIRT_1.2.6;
|
} LIBVIRT_1.2.6;
|
||||||
|
|
||||||
LIBVIRT_1.2.8 {
|
LIBVIRT_1.2.8 {
|
||||||
global:
|
global:
|
||||||
virDomainOpenGraphicsFD;
|
virConnectGetAllDomainStats;
|
||||||
|
virDomainListGetStats;
|
||||||
|
virDomainOpenGraphicsFD;
|
||||||
|
virDomainStatsRecordListFree;
|
||||||
} LIBVIRT_1.2.7;
|
} LIBVIRT_1.2.7;
|
||||||
|
|
||||||
# .... define new API here using predicted next version number ....
|
# .... define new API here using predicted next version number ....
|
||||||
|
Loading…
Reference in New Issue
Block a user