mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 12:35:17 +00:00
Implement virDomainMigrateSetMaxDowntime in qemu driver
This commit is contained in:
parent
0ab6423579
commit
7f4f1dd416
@ -99,6 +99,11 @@ enum qemuDomainJob {
|
||||
enum qemuDomainJobSignals {
|
||||
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_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;
|
||||
@ -107,6 +112,7 @@ struct _qemuDomainObjPrivate {
|
||||
virCond jobCond; /* Use in conjunction with main virDomainObjPtr lock */
|
||||
enum qemuDomainJob jobActive; /* Currently running job */
|
||||
unsigned int jobSignals; /* Signals for running job */
|
||||
struct qemuDomainJobSignalsData jobSignalsData; /* Signal specific data */
|
||||
virDomainJobInfo jobInfo;
|
||||
unsigned long long jobStart;
|
||||
|
||||
@ -352,6 +358,7 @@ static int qemuDomainObjBeginJob(virDomainObjPtr obj)
|
||||
}
|
||||
priv->jobActive = QEMU_JOB_UNSPECIFIED;
|
||||
priv->jobSignals = 0;
|
||||
memset(&priv->jobSignalsData, 0, sizeof(priv->jobSignalsData));
|
||||
priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000);
|
||||
memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
|
||||
|
||||
@ -399,6 +406,7 @@ static int qemuDomainObjBeginJobWithDriver(struct qemud_driver *driver,
|
||||
}
|
||||
priv->jobActive = QEMU_JOB_UNSPECIFIED;
|
||||
priv->jobSignals = 0;
|
||||
memset(&priv->jobSignalsData, 0, sizeof(priv->jobSignalsData));
|
||||
priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000);
|
||||
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->jobSignals = 0;
|
||||
memset(&priv->jobSignalsData, 0, sizeof(priv->jobSignalsData));
|
||||
priv->jobStart = 0;
|
||||
memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
|
||||
virCondSignal(&priv->jobCond);
|
||||
@ -4064,6 +4073,17 @@ qemuDomainWaitForMigrationComplete(struct qemud_driver *driver, virDomainObjPtr
|
||||
VIR_DEBUG0("Pausing domain for non-live migration");
|
||||
if (qemuDomainMigrateOffline(driver, vm) < 0)
|
||||
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);
|
||||
@ -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 = {
|
||||
VIR_DRV_QEMU,
|
||||
"QEMU",
|
||||
@ -9601,7 +9675,7 @@ static virDriver qemuDriver = {
|
||||
qemuCPUBaseline, /* cpuBaseline */
|
||||
qemuDomainGetJobInfo, /* domainGetJobInfo */
|
||||
qemuDomainAbortJob, /* domainAbortJob */
|
||||
NULL, /* domainMigrateSetMaxDowntime */
|
||||
qemuDomainMigrateSetMaxDowntime, /* domainMigrateSetMaxDowntime */
|
||||
};
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
|
||||
int *status,
|
||||
|
@ -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,
|
||||
|
@ -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_TRANSFER_PREFIX "transferred ram: "
|
||||
#define MIGRATION_REMAINING_PREFIX "remaining ram: "
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user