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 > > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list