Introduce DomainGetDirtyRateInfo API to get domain's memory dirty rate info which may be expected by user in order to decide whether it's proper to be migrated out or not. Using flags to control the action of the API: If the VIR_DOMAIN_DIRTYRATE_CALC flag is set, this will calculate domain's memory dirty rate within specific time. If the VIR_DOMAIN_DIRTYRATE_QUERY flag is set, this will query the dirty rate info calculated last time. The VIR_DOMAIN_DIRTYRATE_DEFAULT flag is equal to both VIR_DOMAIN_DIRTYRATE_CALC and VIR_DOMAIN_DIRTYRATE_QUERY. Signed-off-by: Hao Wang <wanghao232@xxxxxxxxxx> Signed-off-by: Zhou Yimin <zhouyimin@xxxxxxxxxx> Reviewed-by: Chuan Zheng <zhengchuan@xxxxxxxxxx> --- include/libvirt/libvirt-domain.h | 59 ++++++++++++++++++++++++++++++++ src/driver-hypervisor.h | 7 ++++ src/libvirt-domain.c | 56 ++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 21 +++++++++++- 6 files changed, 148 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index de2456812c..77b46c2018 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -5119,4 +5119,63 @@ int virDomainAuthorizedSSHKeysSet(virDomainPtr domain, unsigned int nkeys, unsigned int flags); +/** + * virDomainDirtyRateStatus: + * + * Details on the cause of a dirty rate calculation status. + */ +typedef enum { + VIR_DOMAIN_DIRTYRATE_UNSTARTED = 0, /* the dirtyrate calculation has + not been started */ + VIR_DOMAIN_DIRTYRATE_MEASURING = 1, /* the dirtyrate calculation is + measuring */ + VIR_DOMAIN_DIRTYRATE_MEASURED = 2, /* the dirtyrate calculation is + completed */ + +# ifdef VIR_ENUM_SENTINELS + VIR_DOMAIN_DIRTYRATE_LAST +# endif +} virDomainDirtyRateStatus; + +/** + * virDomainDirtyRateInfo: + * + * a virDomainDirtyRateInfo is a structure filled by virDomainGetDirtyRate() + * and extracting dirty rate infomation for a given active Domain. + */ + +typedef struct _virDomainDirtyRateInfo virDomainDirtyRateInfo; +struct _virDomainDirtyRateInfo { + int status; /* the status of dirtyrate calculation, one of + virDomainDirtyRateStatus */ + long long dirtyRate; /* the dirtyrate in MB/s */ + long long startTime; /* the start time of dirtyrate calculation */ + int calcTime; /* the period of dirtyrate calculation */ +}; + +/** + * virDomainDirtyRateInfoPtr: + * + * a virDomainDirtyRateInfoPtr is a pointer to a virDomainDirtyRateInfo structure. + */ + +typedef virDomainDirtyRateInfo *virDomainDirtyRateInfoPtr; + +/** + * virDomainDirtyRateFlags: + * + * Details on the flags used by getdirtyrate api. + */ +typedef enum { + VIR_DOMAIN_DIRTYRATE_DEFAULT = 0, /* default domdirtyrate behavior: + calculate and query */ + VIR_DOMAIN_DIRTYRATE_CALC = 1 << 0, /* calculate domain's dirtyrate */ + VIR_DOMAIN_DIRTYRATE_QUERY = 1 << 1, /* query domain's dirtyrate */ +} virDomainDirtyRateFlags; + +int virDomainGetDirtyRateInfo(virDomainPtr domain, + virDomainDirtyRateInfoPtr info, + int sec, + unsigned int flags); + #endif /* LIBVIRT_DOMAIN_H */ diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 9e8fe89921..5ad681997b 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1400,6 +1400,12 @@ typedef int unsigned int nkeys, unsigned int flags); +typedef int +(*virDrvDomainGetDirtyRateInfo)(virDomainPtr domain, + virDomainDirtyRateInfoPtr info, + int sec, + unsigned int flags); + typedef struct _virHypervisorDriver virHypervisorDriver; typedef virHypervisorDriver *virHypervisorDriverPtr; @@ -1665,4 +1671,5 @@ struct _virHypervisorDriver { virDrvDomainBackupGetXMLDesc domainBackupGetXMLDesc; virDrvDomainAuthorizedSSHKeysGet domainAuthorizedSSHKeysGet; virDrvDomainAuthorizedSSHKeysSet domainAuthorizedSSHKeysSet; + virDrvDomainGetDirtyRateInfo domainGetDirtyRateInfo; }; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index c9f8ffdb56..777028c499 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -13102,3 +13102,59 @@ virDomainAuthorizedSSHKeysSet(virDomainPtr domain, virDispatchError(conn); return -1; } + + +/** + * virDomainGetDirtyRateInfo: + * @domain: a domain object + * @info: pointer to current domain's memory dirty rate info + * @sec: show dirty rate within specified seconds + * @flags: extra flags; binary-OR of virDomainGetDirtyRateInfoFlags + * + * Get the current domain's memory dirty rate info. + * + * If the VIR_DOMAIN_DIRTYRATE_CALC flag is set, this will calculate + * domain's memory dirty rate within specific time (sec). + * + * If the VIR_DOMAIN_DIRTYRATE_QUERY flag is set, this will query the + * dirty rate info calculated last time and stored in 'info'. + * + * The VIR_DOMAIN_DIRTYRATE_DEFAULT flag is equal to both + * VIR_DOMAIN_DIRTYRATE_CALC and VIR_DOMAIN_DIRTYRATE_QUERY. + * + * Returns 0 in case of success, -1 otherwise. + */ +int +virDomainGetDirtyRateInfo(virDomainPtr domain, + virDomainDirtyRateInfoPtr info, + int sec, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "info=%p, sec=%d, flags=0x%x", + info, sec, flags); + + virResetLastError(); + + virCheckDomainReturn(domain, -1); + conn = domain->conn; + + virCheckNonNullArgGoto(info, error); + memset(info, 0, sizeof(*info)); + + virCheckReadOnlyGoto(conn->flags, error); + + if (conn->driver->domainGetDirtyRateInfo) { + int ret; + ret = conn->driver->domainGetDirtyRateInfo(domain, info, sec, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + error: + virDispatchError(conn); + return -1; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index cf31f937d5..155b75713b 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -879,4 +879,9 @@ LIBVIRT_6.10.0 { virDomainAuthorizedSSHKeysSet; } LIBVIRT_6.0.0; +LIBVIRT_7.1.0 { + global: + virDomainGetDirtyRateInfo; +} LIBVIRT_6.10.0; + # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 1b784e61c7..4460d2c7ce 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8531,6 +8531,7 @@ static virHypervisorDriver hypervisor_driver = { .domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 6.0.0 */ .domainAuthorizedSSHKeysGet = remoteDomainAuthorizedSSHKeysGet, /* 6.10.0 */ .domainAuthorizedSSHKeysSet = remoteDomainAuthorizedSSHKeysSet, /* 6.10.0 */ + .domainGetDirtyRateInfo = remoteDomainGetDirtyRateInfo, /* 7.1.0 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 2df38cef77..965d05f68f 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3799,6 +3799,19 @@ struct remote_domain_authorized_ssh_keys_set_args { unsigned int flags; }; +struct remote_domain_get_dirty_rate_info_args { + remote_nonnull_domain dom; + int sec; + unsigned int flags; +}; + +struct remote_domain_get_dirty_rate_info_ret { /* insert@1 */ + int status; + hyper dirtyRate; + hyper startTime; + int calcTime; +}; + /*----- Protocol. -----*/ /* Define the program number, protocol version and procedure numbers here. */ @@ -6714,5 +6727,11 @@ enum remote_procedure { * @generate: none * @acl: domain:write */ - REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425 + REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425, + + /** + * @generate: both + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_GET_DIRTY_RATE_INFO = 426 }; -- 2.23.0