From 492afb8202e6b0b2407beb1b41b60d6cd2c5800c Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Mon, 18 Feb 2013 21:54:58 +0100 Subject: [PATCH] qemu: Implement virDomainMigrate*CompressionCache --- src/qemu/qemu_driver.c | 107 +++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.c | 43 ++++++++++++++ src/qemu/qemu_monitor.h | 5 ++ src/qemu/qemu_monitor_json.c | 63 +++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 5 ++ 5 files changed, 223 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2bf9b6aa5f..435c37c8fe 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10432,6 +10432,111 @@ cleanup: return ret; } +static int +qemuDomainMigrateGetCompressionCache(virDomainPtr dom, + unsigned long long *cacheSize, + unsigned int flags) +{ + virQEMUDriverPtr driver = dom->conn->privateData; + virDomainObjPtr vm; + qemuDomainObjPrivatePtr priv; + int ret = -1; + + virCheckFlags(0, -1); + + if (!(vm = qemuDomObjFromDomain(dom))) + goto cleanup; + + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0) + goto cleanup; + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); + goto endjob; + } + + priv = vm->privateData; + + qemuDomainObjEnterMonitor(driver, vm); + + ret = qemuMonitorGetMigrationCapability( + priv->mon, + QEMU_MONITOR_MIGRATION_CAPS_XBZRLE); + if (ret == 0) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("Compressed migration is not supported by " + "QEMU binary")); + ret = -1; + } else if (ret > 0) { + ret = qemuMonitorGetMigrationCacheSize(priv->mon, cacheSize); + } + + qemuDomainObjExitMonitor(driver, vm); + +endjob: + if (qemuDomainObjEndJob(driver, vm) == 0) + vm = NULL; + +cleanup: + if (vm) + virObjectUnlock(vm); + return ret; +} + +static int +qemuDomainMigrateSetCompressionCache(virDomainPtr dom, + unsigned long long cacheSize, + unsigned int flags) +{ + virQEMUDriverPtr driver = dom->conn->privateData; + virDomainObjPtr vm; + qemuDomainObjPrivatePtr priv; + int ret = -1; + + virCheckFlags(0, -1); + + if (!(vm = qemuDomObjFromDomain(dom))) + goto cleanup; + + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) < 0) + goto cleanup; + + if (!virDomainObjIsActive(vm)) { + virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); + goto endjob; + } + + priv = vm->privateData; + + qemuDomainObjEnterMonitor(driver, vm); + + ret = qemuMonitorGetMigrationCapability( + priv->mon, + QEMU_MONITOR_MIGRATION_CAPS_XBZRLE); + if (ret == 0) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("Compressed migration is not supported by " + "QEMU binary")); + ret = -1; + } else if (ret > 0) { + VIR_DEBUG("Setting compression cache to %llu B", cacheSize); + ret = qemuMonitorSetMigrationCacheSize(priv->mon, cacheSize); + } + + qemuDomainObjExitMonitor(driver, vm); + +endjob: + if (qemuDomainObjEndJob(driver, vm) == 0) + vm = NULL; + +cleanup: + if (vm) + virObjectUnlock(vm); + return ret; +} + static int qemuDomainMigrateSetMaxSpeed(virDomainPtr dom, unsigned long bandwidth, @@ -14993,6 +15098,8 @@ static virDriver qemuDriver = { .domainGetJobStats = qemuDomainGetJobStats, /* 1.0.3 */ .domainAbortJob = qemuDomainAbortJob, /* 0.7.7 */ .domainMigrateSetMaxDowntime = qemuDomainMigrateSetMaxDowntime, /* 0.8.0 */ + .domainMigrateGetCompressionCache = qemuDomainMigrateGetCompressionCache, /* 1.0.3 */ + .domainMigrateSetCompressionCache = qemuDomainMigrateSetCompressionCache, /* 1.0.3 */ .domainMigrateSetMaxSpeed = qemuDomainMigrateSetMaxSpeed, /* 0.9.0 */ .domainMigrateGetMaxSpeed = qemuDomainMigrateGetMaxSpeed, /* 0.9.5 */ .domainEventRegisterAny = qemuDomainEventRegisterAny, /* 0.8.0 */ diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 4c1793109c..7f4a7a017a 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1804,6 +1804,49 @@ int qemuMonitorSetMigrationDowntime(qemuMonitorPtr mon, } +int +qemuMonitorGetMigrationCacheSize(qemuMonitorPtr mon, + unsigned long long *cacheSize) +{ + VIR_DEBUG("mon=%p cacheSize=%p", mon, cacheSize); + + if (!mon) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); + return -1; + } + + if (!mon->json) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("JSON monitor is required")); + return -1; + } + + return qemuMonitorJSONGetMigrationCacheSize(mon, cacheSize); +} + +int +qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon, + unsigned long long cacheSize) +{ + VIR_DEBUG("mon=%p cacheSize=%llu", mon, cacheSize); + + if (!mon) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); + return -1; + } + + if (!mon->json) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("JSON monitor is required")); + return -1; + } + + return qemuMonitorJSONSetMigrationCacheSize(mon, cacheSize); +} + + int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon, qemuMonitorMigrationStatusPtr status) { diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 40e635df64..ffb17c207a 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -326,6 +326,11 @@ int qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon, int qemuMonitorSetMigrationDowntime(qemuMonitorPtr mon, unsigned long long downtime); +int qemuMonitorGetMigrationCacheSize(qemuMonitorPtr mon, + unsigned long long *cacheSize); +int qemuMonitorSetMigrationCacheSize(qemuMonitorPtr mon, + unsigned long long cacheSize); + 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 bac712a6e8..f712321223 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -2256,6 +2256,69 @@ int qemuMonitorJSONSetMigrationDowntime(qemuMonitorPtr mon, } +int +qemuMonitorJSONGetMigrationCacheSize(qemuMonitorPtr mon, + unsigned long long *cacheSize) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + + *cacheSize = 0; + + cmd = qemuMonitorJSONMakeCommand("query-migrate-cache-size", NULL); + if (!cmd) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + if (ret < 0) + goto cleanup; + + ret = virJSONValueObjectGetNumberUlong(reply, "return", cacheSize); + if (ret < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("query-migrate-cache-size reply was missing " + "'return' data")); + goto cleanup; + } + + ret = 0; +cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + + +int +qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon, + unsigned long long cacheSize) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + + cmd = qemuMonitorJSONMakeCommand("migrate-set-cache-size", + "U:value", cacheSize, + NULL); + 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, qemuMonitorMigrationStatusPtr status) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 66635fde02..cfe9c1926e 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -120,6 +120,11 @@ int qemuMonitorJSONSetMigrationSpeed(qemuMonitorPtr mon, int qemuMonitorJSONSetMigrationDowntime(qemuMonitorPtr mon, unsigned long long downtime); +int qemuMonitorJSONGetMigrationCacheSize(qemuMonitorPtr mon, + unsigned long long *cacheSize); +int qemuMonitorJSONSetMigrationCacheSize(qemuMonitorPtr mon, + unsigned long long cacheSize); + int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon, qemuMonitorMigrationStatusPtr status); -- GitLab