[libvirt] [PATCH 1/2] lib: Introduce API for retrieving bulk domain stats

Li Wei lw at cn.fujitsu.com
Tue Aug 26 08:15:30 UTC 2014



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
> 
> 




More information about the libvir-list mailing list