Re: [PATCH v4 6/7] migration/dirtyrate: Implement qemuDomainGetDirtyRateInfo

2020-11-16 Thread Hao Wang
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 
>> Reviewed-by: Chuan Zheng 
>> ---
>>   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 */
>> +    .domainGet

Re: [PATCH v4 6/7] migration/dirtyrate: Implement qemuDomainGetDirtyRateInfo

2020-11-10 Thread Michal Privoznik

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 
Reviewed-by: Chuan Zheng 
---
  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_PERIOD1  /* supported min dirtyrate calc time: 1s */

+#define MAX_DIRTYRATE_CALCULATION_PERIOD60 /* 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?


+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;
 virQEMU

[PATCH v4 6/7] migration/dirtyrate: Implement qemuDomainGetDirtyRateInfo

2020-11-07 Thread Hao Wang
Implement qemuDomainGetDirtyRateInfo:
using flags to control behaviors -- calculate and/or query dirtyrate.

Signed-off-by: Hao Wang 
Reviewed-by: Chuan Zheng 
---
 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:
  *
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_PERIOD1  /* supported min dirtyrate calc 
time: 1s */
+#define MAX_DIRTYRATE_CALCULATION_PERIOD60 /* 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;
+
+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"));
+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);
+}
+
+if (qemuDomainQueryDirtyRate(dom, vm, info) < 0) {
+virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+   _("can't query domain's dirty rate"));
+goto endjob;
+}
+}
+
+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 */
 };
 
 
-- 
2.23.0