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,
.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 */
}
+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)
{
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,
}
+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)
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);