[PATCH v4 6/7] migration/dirtyrate: Implement qemuDomainGetDirtyRateInfo
Hao Wang
wanghao232 at huawei.com
Mon Nov 16 12:20:33 UTC 2020
Thanks for the reviews.
On 2020/11/11 4:11, Michal Privoznik wrote:
> On 11/7/20 10:41 AM, Hao Wang wrote:
>> Implement qemuDomainGetDirtyRateInfo:
>> using flags to control behaviors -- calculate and/or query dirtyrate.
>>
>> Signed-off-by: Hao Wang <wanghao232 at huawei.com>
>> Reviewed-by: Chuan Zheng <zhengchuan at huawei.com>
>> ---
>> include/libvirt/libvirt-domain.h | 11 ++++++
>> src/qemu/qemu_driver.c | 68 ++++++++++++++++++++++++++++++++
>> 2 files changed, 79 insertions(+)
>>
>> diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
>> index 51d8685086..fc45f42dcf 100644
>> --- a/include/libvirt/libvirt-domain.h
>> +++ b/include/libvirt/libvirt-domain.h
>> @@ -5096,6 +5096,17 @@ int virDomainBackupBegin(virDomainPtr domain,
>> char *virDomainBackupGetXMLDesc(virDomainPtr domain,
>> unsigned int flags);
>> +/**
>> + * virDomainDirtyRateFlags:
>> + *
>> + * Details on the flags used by getdirtyrate api.
>> + */
>> +
>> +typedef enum {
>> + VIR_DOMAIN_DIRTYRATE_CALC = 1 << 0, /* calculate domain's dirtyrate */
>> + VIR_DOMAIN_DIRTYRATE_QUERY = 1 << 1, /* query domain's dirtyrate */
>> +} virDomainDirtyRateFlags;
>> +
>> /**
>> * virDomainDirtyRateStatus:
>> *
>
> Again, doesn't belong here.
>
>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>> index cb56fbbfcf..93d5a23630 100644
>> --- a/src/qemu/qemu_driver.c
>> +++ b/src/qemu/qemu_driver.c
>> @@ -20121,6 +20121,73 @@ qemuDomainAgentSetResponseTimeout(virDomainPtr dom,
>> }
>> +#define MIN_DIRTYRATE_CALCULATION_PERIOD 1 /* supported min dirtyrate calc time: 1s */
>> +#define MAX_DIRTYRATE_CALCULATION_PERIOD 60 /* supported max dirtyrate calc time: 60s */
>> +
>> +static int
>> +qemuDomainGetDirtyRateInfo(virDomainPtr dom,
>> + virDomainDirtyRateInfoPtr info,
>> + long long sec,
>> + unsigned int flags)
>> +{
>> + virDomainObjPtr vm = NULL;
>> + virQEMUDriverPtr driver = dom->conn->privateData;
>> + int ret = -1;
>> +
>> + if (!(vm = qemuDomainObjFromDomain(dom)))
>> + return ret;
>> +
>> + if (virDomainGetDirtyRateInfoEnsureACL(dom->conn, vm->def) < 0)
>> + goto cleanup;
>> +
>> + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
>> + goto cleanup;
>> +
>> + if (!qemuMigrationSrcIsAllowed(driver, vm, false, 0))
>> + goto endjob;
>> +
>
> Why is this check needed? I don't understand it, can you please explain?
It's indeed not necessary. I'll remove it.
>
>> + if (flags & VIR_DOMAIN_DIRTYRATE_CALC) {
>> + if (sec < MIN_DIRTYRATE_CALCULATION_PERIOD || sec > MAX_DIRTYRATE_CALCULATION_PERIOD) {
>> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>> + _("seconds=%lld is invalid, please choose value within [1, 60]."),
>> + sec);
>> + goto endjob;
>> + }
>> +
>> + if (qemuDomainCalculateDirtyRate(dom, vm, sec) < 0) {
>> + virReportError(VIR_ERR_OPERATION_FAILED, "%s",
>> + _("can't calculate domain's dirty rate"));
>
> This overwrites a more accurate error reported by qemuDomainCalculateDirtyRate().
>
>> + goto endjob;
>> + }
>> + }
>> +
>> + if (flags & VIR_DOMAIN_DIRTYRATE_QUERY) {
>> + if (flags & VIR_DOMAIN_DIRTYRATE_CALC) {
>> + struct timespec ts = { .tv_sec = sec, .tv_nsec = 50 * 1000 * 1000ull };
>> +
>> + virObjectUnlock(vm);
>> + nanosleep(&ts, NULL);
>> + virObjectLock(vm);
>
> At first I was afraid, I was petrified that this waits for 50 seconds, until I realized it's nanosleep(). Perhaps g_usleep(50*1000); would look better?
>
>> + }
>> +
>> + if (qemuDomainQueryDirtyRate(dom, vm, info) < 0) {
>> + virReportError(VIR_ERR_OPERATION_FAILED, "%s",
>> + _("can't query domain's dirty rate"));
>
> Again, error overwrite.
>
>> + goto endjob;
>> + }
>> + }
>
> So if no flag is specified then nothing happens? I know you handle that in virsh, but I think that logic should live here. And perhaps the public API description should document that no flags is equal to specifying both flags together.
>
>> +
>> + ret = 0;
>> +
>> + endjob:
>> + qemuDomainObjEndJob(driver, vm);
>> +
>> + cleanup:
>> + virDomainObjEndAPI(&vm);
>> + return ret;
>> +}
>> +
>> +
>> static virHypervisorDriver qemuHypervisorDriver = {
>> .name = QEMU_DRIVER_NAME,
>> .connectURIProbe = qemuConnectURIProbe,
>> @@ -20360,6 +20427,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
>> .domainAgentSetResponseTimeout = qemuDomainAgentSetResponseTimeout, /* 5.10.0 */
>> .domainBackupBegin = qemuDomainBackupBegin, /* 6.0.0 */
>> .domainBackupGetXMLDesc = qemuDomainBackupGetXMLDesc, /* 6.0.0 */
>> + .domainGetDirtyRateInfo = qemuDomainGetDirtyRateInfo, /* 6.9.0 */
>
> 6.10.0 :-(
>
>> };
>>
>
> I think the following should be squashed in:
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 4cbbe8dd84..4058fb487c 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -20130,12 +20130,12 @@ qemuDomainGetDirtyRateInfo(virDomainPtr dom,
> long long sec,
> unsigned int flags)
> {
> - virDomainObjPtr vm = NULL;
> virQEMUDriverPtr driver = dom->conn->privateData;
> + virDomainObjPtr vm = NULL;
> int ret = -1;
>
> if (!(vm = qemuDomainObjFromDomain(dom)))
> - return ret;
> + return -1;
>
> if (virDomainGetDirtyRateInfoEnsureACL(dom->conn, vm->def) < 0)
> goto cleanup;
> @@ -20147,18 +20147,18 @@ qemuDomainGetDirtyRateInfo(virDomainPtr dom,
> goto endjob;
>
> if (flags & VIR_DOMAIN_DIRTYRATE_CALC) {
> - if (sec < MIN_DIRTYRATE_CALCULATION_PERIOD || sec > MAX_DIRTYRATE_CALCULATION_PERIOD) {
> + if (sec < MIN_DIRTYRATE_CALCULATION_PERIOD ||
> + sec > MAX_DIRTYRATE_CALCULATION_PERIOD) {
> virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> - _("seconds=%lld is invalid, please choose value within [1, 60]."),
> - sec);
> + _("seconds=%lld is invalid, please choose value within [%d, %d]."),
> + sec,
> + MIN_DIRTYRATE_CALCULATION_PERIOD,
> + MAX_DIRTYRATE_CALCULATION_PERIOD);
> goto endjob;
> }
>
> - if (qemuDomainCalculateDirtyRate(dom, vm, sec) < 0) {
> - virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> - _("can't calculate domain's dirty rate"));
> + if (qemuDomainCalculateDirtyRate(driver, vm, sec) < 0)
> goto endjob;
> - }
> }
>
> if (flags & VIR_DOMAIN_DIRTYRATE_QUERY) {
> @@ -20170,11 +20170,8 @@ qemuDomainGetDirtyRateInfo(virDomainPtr dom,
> virObjectLock(vm);
> }
>
> - if (qemuDomainQueryDirtyRate(dom, vm, info) < 0) {
> - virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> - _("can't query domain's dirty rate"));
> + if (qemuDomainQueryDirtyRate(driver, vm, info) < 0)
> goto endjob;
> - }
> }
>
> ret = 0;
> @@ -20427,7 +20424,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
> .domainAgentSetResponseTimeout = qemuDomainAgentSetResponseTimeout, /* 5.10.0 */
> .domainBackupBegin = qemuDomainBackupBegin, /* 6.0.0 */
> .domainBackupGetXMLDesc = qemuDomainBackupGetXMLDesc, /* 6.0.0 */
> - .domainGetDirtyRateInfo = qemuDomainGetDirtyRateInfo, /* 6.9.0 */
> + .domainGetDirtyRateInfo = qemuDomainGetDirtyRateInfo, /* 6.10.0 */
> };
>
>
> Michal
>
> .
More information about the libvir-list
mailing list