enum qemuDomainJob {
QEMU_JOB_NONE = 0, /* Always set to 0 for easy if (jobActive) conditions */
QEMU_JOB_UNSPECIFIED,
- QEMU_JOB_MIGRATION,
+ QEMU_JOB_MIGRATION_OUT,
+ QEMU_JOB_MIGRATION_IN,
};
enum qemuDomainJobSignals {
priv = vm->privateData;
- if (priv->jobActive == QEMU_JOB_MIGRATION) {
+ if (priv->jobActive == QEMU_JOB_MIGRATION_OUT) {
if (vm->state != VIR_DOMAIN_PAUSED) {
VIR_DEBUG("Requesting domain pause on %s",
vm->def->name);
char *unixfile = NULL;
unsigned long long qemuCmdFlags;
struct qemuStreamMigFile *qemust = NULL;
+ qemuDomainObjPrivatePtr priv = NULL;
+ struct timeval now;
+
+ if (gettimeofday(&now, NULL) < 0) {
+ virReportSystemError(errno, "%s",
+ _("cannot get time of day"));
+ return -1;
+ }
qemuDriverLock(driver);
if (!dom_xml) {
goto cleanup;
}
def = NULL;
+ priv = vm->privateData;
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
goto cleanup;
+ priv->jobActive = QEMU_JOB_MIGRATION_OUT;
/* Domain starts inactive, even if the domain XML had an id field. */
vm->def->id = -1;
qemuDomainObjEndJob(vm) == 0)
vm = NULL;
+ /* We set a fake job active which is held across
+ * API calls until the finish() call. This prevents
+ * any other APIs being invoked while incoming
+ * migration is taking place
+ */
+ if (vm &&
+ virDomainObjIsActive(vm)) {
+ priv->jobActive = QEMU_JOB_MIGRATION_IN;
+ priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED;
+ priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000);
+ }
+
cleanup:
virDomainDefFree(def);
if (unixfile)
virDomainEventPtr event = NULL;
int ret = -1;
int internalret;
+ qemuDomainObjPrivatePtr priv = NULL;
+ struct timeval now;
+
+ if (gettimeofday(&now, NULL) < 0) {
+ virReportSystemError(errno, "%s",
+ _("cannot get time of day"));
+ return -1;
+ }
virCheckFlags(VIR_MIGRATE_LIVE |
VIR_MIGRATE_PEER2PEER |
goto cleanup;
}
def = NULL;
+ priv = vm->privateData;
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
goto cleanup;
+ priv->jobActive = QEMU_JOB_MIGRATION_OUT;
/* Domain starts inactive, even if the domain XML had an id field. */
vm->def->id = -1;
qemuDomainObjEndJob(vm) == 0)
vm = NULL;
+ /* We set a fake job active which is held across
+ * API calls until the finish() call. This prevents
+ * any other APIs being invoked while incoming
+ * migration is taking place
+ */
+ if (vm &&
+ virDomainObjIsActive(vm)) {
+ priv->jobActive = QEMU_JOB_MIGRATION_IN;
+ priv->jobInfo.type = VIR_DOMAIN_JOB_UNBOUNDED;
+ priv->jobStart = (now.tv_sec * 1000ull) + (now.tv_usec / 1000);
+ }
+
cleanup:
VIR_FREE(hostname);
virDomainDefFree(def);
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
goto cleanup;
- priv->jobActive = QEMU_JOB_MIGRATION;
+ priv->jobActive = QEMU_JOB_MIGRATION_OUT;
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
virDomainEventPtr event = NULL;
virErrorPtr orig_err;
int newVM = 1;
+ qemuDomainObjPrivatePtr priv = NULL;
virCheckFlags(VIR_MIGRATE_LIVE |
VIR_MIGRATE_PEER2PEER |
goto cleanup;
}
+ priv = vm->privateData;
+ if (priv->jobActive != QEMU_JOB_MIGRATION_IN) {
+ qemuReportError(VIR_ERR_NO_DOMAIN,
+ _("domain '%s' is not processing incoming migration"), dname);
+ goto cleanup;
+ }
+ priv->jobActive = QEMU_JOB_NONE;
+ memset(&priv->jobInfo, 0, sizeof(priv->jobInfo));
+
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
goto cleanup;
event = NULL;
}
- qemuDomainObjPrivatePtr priv = vm->privateData;
dom = virGetDomain (dconn, vm->def->name, vm->def->uuid);
if (!(flags & VIR_MIGRATE_PAUSED)) {
if (virDomainObjIsActive(vm)) {
if (priv->jobActive) {
+ struct timeval now;
+
memcpy(info, &priv->jobInfo, sizeof(*info));
+
+ /* Refresh elapsed time again just to ensure it
+ * is fully updated. This is primarily for benefit
+ * of incoming migration which we don't currently
+ * monitor actively in the background thread
+ */
+ if (gettimeofday(&now, NULL) < 0) {
+ virReportSystemError(errno, "%s",
+ _("cannot get time of day"));
+ goto cleanup;
+ }
+ info->timeElapsed =
+ ((now.tv_sec * 1000ull) + (now.tv_usec / 1000)) -
+ priv->jobStart;
} else {
memset(info, 0, sizeof(*info));
info->type = VIR_DOMAIN_JOB_NONE;
priv = vm->privateData;
- if (priv->jobActive != QEMU_JOB_MIGRATION) {
+ if (priv->jobActive != QEMU_JOB_MIGRATION_OUT) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not being migrated"));
goto cleanup;