mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Implement virDomainMigrateSetMaxDowntime in qemu driver
This commit is contained in:
parent
0ab6423579
commit
7f4f1dd416
@ -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 {
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
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,
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
|
|
||||||
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
|
|||||||
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:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 = {
|
|||||||
qemuCPUBaseline, /* cpuBaseline */
|
qemuCPUBaseline, /* cpuBaseline */
|
||||||
qemuDomainGetJobInfo, /* domainGetJobInfo */
|
qemuDomainGetJobInfo, /* domainGetJobInfo */
|
||||||
qemuDomainAbortJob, /* domainAbortJob */
|
qemuDomainAbortJob, /* domainAbortJob */
|
||||||
NULL, /* domainMigrateSetMaxDowntime */
|
qemuDomainMigrateSetMaxDowntime, /* domainMigrateSetMaxDowntime */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
|||||||
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:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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,
|
|||||||
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user