提交 7f4f1dd4 编写于 作者: J Jiri Denemark

Implement virDomainMigrateSetMaxDowntime in qemu driver

上级 0ab64235
...@@ -99,6 +99,11 @@ enum qemuDomainJob { ...@@ -99,6 +99,11 @@ enum qemuDomainJob {
enum qemuDomainJobSignals { enum qemuDomainJobSignals {
QEMU_JOB_SIGNAL_CANCEL = 1 << 0, /* Request job cancellation */ QEMU_JOB_SIGNAL_CANCEL = 1 << 0, /* Request job cancellation */
QEMU_JOB_SIGNAL_SUSPEND = 1 << 1, /* Request VM suspend to finish live migration offline */ QEMU_JOB_SIGNAL_SUSPEND = 1 << 1, /* Request VM suspend to finish live migration offline */
QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME = 1 << 2, /* Request migration downtime change */
};
struct qemuDomainJobSignalsData {
unsigned long long migrateDowntime; /* Data for QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME */
}; };
typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate; typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
...@@ -107,6 +112,7 @@ struct _qemuDomainObjPrivate { ...@@ -107,6 +112,7 @@ struct _qemuDomainObjPrivate {
virCond jobCond; /* Use in conjunction with main virDomainObjPtr lock */ virCond jobCond; /* Use in conjunction with main virDomainObjPtr lock */
enum qemuDomainJob jobActive; /* Currently running job */ enum qemuDomainJob jobActive; /* Currently running job */
unsigned int jobSignals; /* Signals for running job */ unsigned int jobSignals; /* Signals for running job */
struct qemuDomainJobSignalsData jobSignalsData; /* Signal specific data */
virDomainJobInfo jobInfo; virDomainJobInfo jobInfo;
unsigned long long jobStart; unsigned long long jobStart;
...@@ -352,6 +358,7 @@ static int qemuDomainObjBeginJob(virDomainObjPtr obj) ...@@ -352,6 +358,7 @@ static int qemuDomainObjBeginJob(virDomainObjPtr obj)
} }
priv->jobActive = QEMU_JOB_UNSPECIFIED; priv->jobActive = QEMU_JOB_UNSPECIFIED;
priv->jobSignals = 0; priv->jobSignals = 0;
memset(&priv->jobSignalsData, 0, sizeof(priv->jobSignalsData));
priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000); priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000);
memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
...@@ -399,6 +406,7 @@ static int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver, ...@@ -399,6 +406,7 @@ static int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver,
} }
priv->jobActive = QEMU_JOB_UNSPECIFIED; priv->jobActive = QEMU_JOB_UNSPECIFIED;
priv->jobSignals = 0; priv->jobSignals = 0;
memset(&priv->jobSignalsData, 0, sizeof(priv->jobSignalsData));
priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000); priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000);
memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
...@@ -424,6 +432,7 @@ static int ATTRIBUTE_RETURN_CHECK qemuDomainObjEndJob(virDomainObjPtr obj) ...@@ -424,6 +432,7 @@ static int ATTRIBUTE_RETURN_CHECK qemuDomainObjEndJob(virDomainObjPtr obj)
priv->jobActive = QEMU_JOB_NONE; priv->jobActive = QEMU_JOB_NONE;
priv->jobSignals = 0; priv->jobSignals = 0;
memset(&priv->jobSignalsData, 0, sizeof(priv->jobSignalsData));
priv->jobStart = 0; priv->jobStart = 0;
memset(&priv->jobInfo, 0, sizeof(priv->jobInfo)); memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
virCondSignal(&priv->jobCond); virCondSignal(&priv->jobCond);
...@@ -4064,6 +4073,17 @@ qemuDomainWaitForMigrationComplete(struct qemud_driver *driver, virDomainObjPtr ...@@ -4064,6 +4073,17 @@ qemuDomainWaitForMigrationComplete(struct qemud_driver *driver, virDomainObjPtr
VIR_DEBUG0("Pausing domain for non-live migration"); VIR_DEBUG0("Pausing domain for non-live migration");
if (qemuDomainMigrateOffline(driver, vm) < 0) if (qemuDomainMigrateOffline(driver, vm) < 0)
VIR_WARN0("Unable to pause domain"); VIR_WARN0("Unable to pause domain");
} else if (priv->jobSignals & QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME) {
unsigned long long ms = priv->jobSignalsData.migrateDowntime;
priv->jobSignals ^= QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME;
priv->jobSignalsData.migrateDowntime = 0;
VIR_DEBUG("Setting migration downtime to %llums", ms);
qemuDomainObjEnterMonitorWithDriver(driver, vm);
rc = qemuMonitorSetMigrationDowntime(priv->mon, ms);
qemuDomainObjExitMonitorWithDriver(driver, vm);
if (rc < 0)
VIR_WARN0("Unable to set migration downtime");
} }
qemuDomainObjEnterMonitorWithDriver(driver, vm); qemuDomainObjEnterMonitorWithDriver(driver, vm);
...@@ -9520,6 +9540,60 @@ cleanup: ...@@ -9520,6 +9540,60 @@ cleanup:
} }
static int
qemuDomainMigrateSetMaxDowntime(virDomainPtr dom,
unsigned long long downtime,
unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
qemuDomainObjPrivatePtr priv;
int ret = -1;
if (flags != 0) {
qemuReportError(VIR_ERR_INVALID_ARG,
_("unsupported flags (0x%x) passed to '%s'"), flags, __FUNCTION__);
return -1;
}
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
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 (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
goto cleanup;
}
priv = vm->privateData;
if (priv->jobActive != QEMU_JOB_MIGRATION) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not being migrated"));
goto cleanup;
}
VIR_DEBUG("Requesting migration downtime change to %llums", downtime);
priv->jobSignals |= QEMU_JOB_SIGNAL_MIGRATE_DOWNTIME;
priv->jobSignalsData.migrateDowntime = downtime;
ret = 0;
cleanup:
if (vm)
virDomainObjUnlock(vm);
qemuDriverUnlock(driver);
return ret;
}
static virDriver qemuDriver = { static virDriver qemuDriver = {
VIR_DRV_QEMU, VIR_DRV_QEMU,
"QEMU", "QEMU",
...@@ -9601,7 +9675,7 @@ static virDriver qemuDriver = { ...@@ -9601,7 +9675,7 @@ static virDriver qemuDriver = {
qemuCPUBaseline, /* cpuBaseline */ qemuCPUBaseline, /* cpuBaseline */
qemuDomainGetJobInfo, /* domainGetJobInfo */ qemuDomainGetJobInfo, /* domainGetJobInfo */
qemuDomainAbortJob, /* domainAbortJob */ qemuDomainAbortJob, /* domainAbortJob */
NULL, /* domainMigrateSetMaxDowntime */ qemuDomainMigrateSetMaxDowntime, /* domainMigrateSetMaxDowntime */
}; };
......
...@@ -1016,6 +1016,21 @@ int qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon, ...@@ -1016,6 +1016,21 @@ int qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon,
return ret; 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 qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
int *status, int *status,
unsigned long long *transferred, unsigned long long *transferred,
......
...@@ -176,6 +176,9 @@ int qemuMonitorSavePhysicalMemory(qemuMonitorPtr mon, ...@@ -176,6 +176,9 @@ int qemuMonitorSavePhysicalMemory(qemuMonitorPtr mon,
int qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon, int qemuMonitorSetMigrationSpeed(qemuMonitorPtr mon,
unsigned long bandwidth); unsigned long bandwidth);
int qemuMonitorSetMigrationDowntime(qemuMonitorPtr mon,
unsigned long long downtime);
enum { enum {
QEMU_MONITOR_MIGRATION_STATUS_INACTIVE, QEMU_MONITOR_MIGRATION_STATUS_INACTIVE,
QEMU_MONITOR_MIGRATION_STATUS_ACTIVE, QEMU_MONITOR_MIGRATION_STATUS_ACTIVE,
......
...@@ -1088,6 +1088,35 @@ int qemuMonitorJSONSetMigrationSpeed(qemuMonitorPtr mon, ...@@ -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, "%llums", 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 static int
qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply, qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
int *status, int *status,
......
...@@ -81,6 +81,9 @@ int qemuMonitorJSONSavePhysicalMemory(qemuMonitorPtr mon, ...@@ -81,6 +81,9 @@ int qemuMonitorJSONSavePhysicalMemory(qemuMonitorPtr mon,
int qemuMonitorJSONSetMigrationSpeed(qemuMonitorPtr mon, int qemuMonitorJSONSetMigrationSpeed(qemuMonitorPtr mon,
unsigned long bandwidth); unsigned long bandwidth);
int qemuMonitorJSONSetMigrationDowntime(qemuMonitorPtr mon,
unsigned long long downtime);
int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon, int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
int *status, int *status,
unsigned long long *transferred, unsigned long long *transferred,
......
...@@ -999,6 +999,33 @@ cleanup: ...@@ -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 %llums", 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_PREFIX "Migration status: "
#define MIGRATION_TRANSFER_PREFIX "transferred ram: " #define MIGRATION_TRANSFER_PREFIX "transferred ram: "
#define MIGRATION_REMAINING_PREFIX "remaining ram: " #define MIGRATION_REMAINING_PREFIX "remaining ram: "
......
...@@ -83,6 +83,9 @@ int qemuMonitorTextSavePhysicalMemory(qemuMonitorPtr mon, ...@@ -83,6 +83,9 @@ int qemuMonitorTextSavePhysicalMemory(qemuMonitorPtr mon,
int qemuMonitorTextSetMigrationSpeed(qemuMonitorPtr mon, int qemuMonitorTextSetMigrationSpeed(qemuMonitorPtr mon,
unsigned long bandwidth); unsigned long bandwidth);
int qemuMonitorTextSetMigrationDowntime(qemuMonitorPtr mon,
unsigned long long downtime);
int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon, int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
int *status, int *status,
unsigned long long *transferred, unsigned long long *transferred,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册