Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_driver.c | 48 +++++++++++++++++++++++++++++++++++++++++-
src/qemu/qemu_monitor.c | 15 +++++++++++++
src/qemu/qemu_monitor.h | 3 ++
src/qemu/qemu_monitor_json.c | 29 +++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 3 ++
src/qemu/qemu_monitor_text.c | 27 +++++++++++++++++++++++
src/qemu/qemu_monitor_text.h | 3 ++
7 files changed, 127 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8527c96..80973ea 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9499,6 +9499,52 @@ cleanup:
}
+static int
+qemuDomainMigrateSetDowntime(virDomainPtr dom,
+ unsigned long long downtime)
+{
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm;
+ qemuDomainObjPrivatePtr priv;
+ int ret = -1;
+
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemuReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"),
uuidstr);
+ goto cleanup;
+ }
+
+ if (qemuDomainObjBeginJob(vm) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
+ priv = vm->privateData;
+ qemuDomainObjEnterMonitor(vm);
+ ret = qemuMonitorSetMigrationDowntime(priv->mon, downtime);
+ qemuDomainObjExitMonitor(vm);
+
+endjob:
+ if (qemuDomainObjEndJob(vm) == 0)
+ vm = NULL;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ return ret;
+}
+
+
static virDriver qemuDriver = {
VIR_DRV_QEMU,
"QEMU",
@@ -9580,7 +9626,7 @@ static virDriver qemuDriver = {
qemuCPUBaseline, /* cpuBaseline */
qemuDomainGetJobInfo, /* domainGetJobInfo */
qemuDomainAbortJob, /* domainAbortJob */
- NULL, /* domainMigrateSetDowntime */
+ qemuDomainMigrateSetDowntime, /* domainMigrateSetDowntime */
};
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index acc841b..6b68db8 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1016,6 +1016,21 @@ int qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon,
return ret;
}
+
+int qemuMonitorSetMigrationDowntime(qemuMonitorPtr mon,
+ unsigned long long downtime)
+{
+ int ret;
+ DEBUG("mon=%p, fd=%d downtime=%llu", mon, mon->fd, downtime);
+
+ if (mon->json)
+ ret = qemuMonitorJSONSetMigrationDowntime(mon, downtime);
+ else
+ ret = qemuMonitorTextSetMigrationDowntime(mon, downtime);
+ return ret;
+}
+
+
int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
int *status,
unsigned long long *transferred,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index cfb76b6..2557fb9 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -176,6 +176,9 @@ int qemuMonitorSavePhysicalMemory(qemuMonitorPtr mon,
int qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon,
unsigned long bandwidth);
+int qemuMonitorSetMigrationDowntime(qemuMonitorPtr mon,
+ unsigned long long downtime);
+
enum {
QEMU_MONITOR_MIGRATION_STATUS_INACTIVE,
QEMU_MONITOR_MIGRATION_STATUS_ACTIVE,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 7a263cb..b259452 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1088,6 +1088,35 @@ int qemuMonitorJSONSetMigrationSpeed(qemuMonitorPtr mon,
}
+int qemuMonitorJSONSetMigrationDowntime(qemuMonitorPtr mon,
+ unsigned long long downtime)
+{
+ int ret;
+ char *downtimestr;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+ if (virAsprintf(&downtimestr, "%llun", downtime) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+ cmd = qemuMonitorJSONMakeCommand("migrate_set_downtime",
+ "s:value", downtimestr,
+ NULL);
+ VIR_FREE(downtimestr);
+ if (!cmd)
+ return -1;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0)
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
+
static int
qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
int *status,
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 2906fee..fc05153 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -81,6 +81,9 @@ int qemuMonitorJSONSavePhysicalMemory(qemuMonitorPtr mon,
int qemuMonitorJSONSetMigrationSpeed(qemuMonitorPtr mon,
unsigned long bandwidth);
+int qemuMonitorJSONSetMigrationDowntime(qemuMonitorPtr mon,
+ unsigned long long downtime);
+
int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
int *status,
unsigned long long *transferred,
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index b7c41a1..99f1180 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -999,6 +999,33 @@ cleanup:
}
+int qemuMonitorTextSetMigrationDowntime(qemuMonitorPtr mon,
+ unsigned long long downtime)
+{
+ char *cmd = NULL;
+ char *info = NULL;
+ int ret = -1;
+
+ if (virAsprintf(&cmd, "migrate_set_downtime %llu", downtime) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (qemuMonitorCommand(mon, cmd, &info) < 0) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ "%s", _("could not set maximum migration
downtime"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(info);
+ VIR_FREE(cmd);
+ return ret;
+}
+
+
#define MIGRATION_PREFIX "Migration status: "
#define MIGRATION_TRANSFER_PREFIX "transferred ram: "
#define MIGRATION_REMAINING_PREFIX "remaining ram: "
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 3215cae..4e1939c 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -83,6 +83,9 @@ int qemuMonitorTextSavePhysicalMemory(qemuMonitorPtr mon,
int qemuMonitorTextSetMigrationSpeed(qemuMonitorPtr mon,
unsigned long bandwidth);
+int qemuMonitorTextSetMigrationDowntime(qemuMonitorPtr mon,
+ unsigned long long downtime);
+
int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
int *status,
unsigned long long *transferred,
--
1.7.0.2