On 08/26/2014 03:46 PM, Peter Krempa wrote:
On 08/26/14 05:21, Li Wei wrote:
>
>
> On 08/26/2014 01:05 AM, Peter Krempa wrote:
>> 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 agregate 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 allow to 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 apps 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
>>
>> the returned typed params will use the following scheme
>>
>> state.state = running
>> state.reason = started
>> cpu.count = 8
>> cpu.0.state = running
>> cpu.0.time = 1234
>> ---
>> include/libvirt/libvirt.h.in | 26 +++++++
>> src/driver.h | 9 +++
>> src/libvirt.c | 179 +++++++++++++++++++++++++++++++++++++++++++
>> src/libvirt_public.syms | 7 ++
>> 4 files changed, 221 insertions(+)
>>
>> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
>> index 47ea695..962f740 100644
>> --- a/include/libvirt/libvirt.h.in
>> +++ b/include/libvirt/libvirt.h.in
>> @@ -2501,6 +2501,32 @@ int virDomainDetachDeviceFlags(virDomainPtr domain,
>> int virDomainUpdateDeviceFlags(virDomainPtr domain,
>> const char *xml, unsigned int flags);
>>
>> +typedef struct _virDomainStatsRecord virDomainStatsRecord;
>> +typedef virDomainStatsRecord *virDomainStatsRecordPtr;
>> +struct _virDomainStatsRecord {
>> + virDomainPtr dom;
>> + unsigned int nparams;
>> + virTypedParameterPtr params;
>> +};
>> +
>> +typedef enum {
>> + VIR_DOMAIN_STATS_ALL = (1 << 0), /* return all stats fields
>> + implemented in the daemon */
>> + VIR_DOMAIN_STATS_STATE = (1 << 1), /* 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
>> */
>> diff --git a/src/driver.h b/src/driver.h
>> index ba7c1fc..d5596ab 100644
>> --- a/src/driver.h
>> +++ b/src/driver.h
>> @@ -1191,6 +1191,14 @@ typedef int
>> unsigned int flags);
>>
>>
>> +typedef int
>> +(*virDrvDomainListGetStats)(virConnectPtr conn,
>> + virDomainPtr *doms,
>> + unsigned int ndoms,
>> + unsigned int stats,
>> + virDomainStatsRecordPtr **retStats,
>> + unsigned int flags);
>> +
>> typedef struct _virDriver virDriver;
>> typedef virDriver *virDriverPtr;
>>
>> @@ -1411,6 +1419,7 @@ struct _virDriver {
>> virDrvDomainSetTime domainSetTime;
>> virDrvNodeGetFreePages nodeGetFreePages;
>> virDrvConnectGetDomainCapabilities connectGetDomainCapabilities;
>> + virDrvDomainListGetStats domainListGetStats;
>> };
>>
>>
>> diff --git a/src/libvirt.c b/src/libvirt.c
>> index 8349261..bbbc023 100644
>> --- a/src/libvirt.c
>> +++ b/src/libvirt.c
>> @@ -21341,3 +21341,182 @@ virConnectGetDomainCapabilities(virConnectPtr conn,
>> virDispatchError(conn);
>> 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 storage driver):
>> + *
>> + * VIR_DOMAIN_STATS_ALL: Return all statistics supported by the hypervisor
>> + * driver. This allows to query everything the driver supports without getting
>> + * an error.
>> + *
>> + * VIR_DOMAIN_STATS_STATE: Return domain state and reason for entering that
>> + * state. The typed parameter keys are in format:
>> + * "state.state" - state of the VM, returned as int from
virDomainState enum
>> + * "state.reason" - reason for entering given state, returned as in
from
>> + * virDomain*Reason enmum corresponding to given state.
>> + *
>> + * Returns the count of returned statistics strucutres 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);
>> +
>> + if (!conn->driver->domainListGetStats) {
>> + virReportUnsupportedError();
>> + goto cleanup;
>> + }
>> +
>> + ret = conn->driver->domainListGetStats(conn, NULL, 0, stats,
>
> You mean we pass a NULL as doms to retrieve stats for all domains of this conn?
> how about generate the domain list here to avoid implement it
> in every individual drivers(although this need (de)serialize domains via rpc)?
>
You'd need to transport the domain list over the RPC two more times if
the client would retrieve it. It's more optimal to do it in the driver
itself as it stores the domain list already.
Oh, I missed the transport of domain list when client retrieving it,
thanks for your explanation.
Thanks
Peter