From ed88223012a5221a4fbf2676cdb2854971706a52 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 26 2018 15:29:54 +0000 Subject: import libvirt-4.5.0-10.el7_6.3 --- diff --git a/SOURCES/libvirt-qemu-Avoid-duplicate-resume-events-and-state-changes.patch b/SOURCES/libvirt-qemu-Avoid-duplicate-resume-events-and-state-changes.patch new file mode 100644 index 0000000..473caeb --- /dev/null +++ b/SOURCES/libvirt-qemu-Avoid-duplicate-resume-events-and-state-changes.patch @@ -0,0 +1,243 @@ +From f01aeffaa7dbb4e9efe61f9826deed14c4cb3b41 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Wed, 12 Sep 2018 14:34:33 +0200 +Subject: [PATCH] qemu: Avoid duplicate resume events and state changes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The only place where VIR_DOMAIN_EVENT_RESUMED should be generated is the +RESUME event handler to make sure we don't generate duplicate events or +state changes. In the worse case the duplicity can revert or cover +changes done by other event handlers. + +For example, after QEMU sent RESUME, BLOCK_IO_ERROR, and STOP events +we could happily mark the domain as running and report +VIR_DOMAIN_EVENT_RESUMED to registered clients. + +https://bugzilla.redhat.com/show_bug.cgi?id=1612943 + +Signed-off-by: Jiri Denemark +Reviewed-by: John Ferlan +(cherry picked from commit e6d77a75c4bf0c017d62b717b75e4bb6aa7a456b) + +https://bugzilla.redhat.com/show_bug.cgi?id=1634758 +https://bugzilla.redhat.com/show_bug.cgi?id=1634759 + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_driver.c | 13 ----------- + src/qemu/qemu_migration.c | 49 ++++++++++++++++----------------------- + src/qemu/qemu_process.c | 10 ++++---- + 3 files changed, 24 insertions(+), 48 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index 26aa557d9f..295613ba3c 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -1863,7 +1863,6 @@ static int qemuDomainResume(virDomainPtr dom) + virQEMUDriverPtr driver = dom->conn->privateData; + virDomainObjPtr vm; + int ret = -1; +- virObjectEventPtr event = NULL; + int state; + int reason; + virQEMUDriverConfigPtr cfg = NULL; +@@ -1902,9 +1901,6 @@ static int qemuDomainResume(virDomainPtr dom) + "%s", _("resume operation failed")); + goto endjob; + } +- event = virDomainEventLifecycleNewFromObj(vm, +- VIR_DOMAIN_EVENT_RESUMED, +- VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); + } + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) + goto endjob; +@@ -1915,7 +1911,6 @@ static int qemuDomainResume(virDomainPtr dom) + + cleanup: + virDomainObjEndAPI(&vm); +- virObjectEventStateQueue(driver->domainEventState, event); + virObjectUnref(cfg); + return ret; + } +@@ -16031,7 +16026,6 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, + virDomainDefPtr config = NULL; + virQEMUDriverConfigPtr cfg = NULL; + virCapsPtr caps = NULL; +- bool was_running = false; + bool was_stopped = false; + qemuDomainSaveCookiePtr cookie; + virCPUDefPtr origCPU = NULL; +@@ -16222,7 +16216,6 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, + priv = vm->privateData; + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { + /* Transitions 5, 6 */ +- was_running = true; + if (qemuProcessStopCPUs(driver, vm, + VIR_DOMAIN_PAUSED_FROM_SNAPSHOT, + QEMU_ASYNC_JOB_START) < 0) +@@ -16319,12 +16312,6 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, + event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_STARTED, + detail); +- } else if (!was_running) { +- /* Transition 8 */ +- detail = VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT; +- event = virDomainEventLifecycleNewFromObj(vm, +- VIR_DOMAIN_EVENT_RESUMED, +- detail); + } + } + break; +diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c +index 825a9d399b..67940330aa 100644 +--- a/src/qemu/qemu_migration.c ++++ b/src/qemu/qemu_migration.c +@@ -2982,14 +2982,10 @@ qemuMigrationSrcConfirmPhase(virQEMUDriverPtr driver, + virFreeError(orig_err); + + if (virDomainObjGetState(vm, &reason) == VIR_DOMAIN_PAUSED && +- reason == VIR_DOMAIN_PAUSED_POSTCOPY) { ++ reason == VIR_DOMAIN_PAUSED_POSTCOPY) + qemuMigrationAnyPostcopyFailed(driver, vm); +- } else if (qemuMigrationSrcRestoreDomainState(driver, vm)) { +- event = virDomainEventLifecycleNewFromObj(vm, +- VIR_DOMAIN_EVENT_RESUMED, +- VIR_DOMAIN_EVENT_RESUMED_MIGRATED); +- virObjectEventStateQueue(driver->domainEventState, event); +- } ++ else ++ qemuMigrationSrcRestoreDomainState(driver, vm); + + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + priv->job.migParams, priv->job.apiFlags); +@@ -4624,11 +4620,7 @@ qemuMigrationSrcPerformJob(virQEMUDriverPtr driver, + qemuMigrationParamsReset(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, + priv->job.migParams, priv->job.apiFlags); + +- if (qemuMigrationSrcRestoreDomainState(driver, vm)) { +- event = virDomainEventLifecycleNewFromObj(vm, +- VIR_DOMAIN_EVENT_RESUMED, +- VIR_DOMAIN_EVENT_RESUMED_MIGRATED); +- } ++ qemuMigrationSrcRestoreDomainState(driver, vm); + + qemuMigrationJobFinish(driver, vm); + if (!virDomainObjIsActive(vm) && ret == 0) { +@@ -4672,7 +4664,6 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, + unsigned long resource) + { + qemuDomainObjPrivatePtr priv = vm->privateData; +- virObjectEventPtr event = NULL; + int ret = -1; + + /* If we didn't start the job in the begin phase, start it now. */ +@@ -4694,11 +4685,7 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, + nmigrate_disks, migrate_disks, migParams); + + if (ret < 0) { +- if (qemuMigrationSrcRestoreDomainState(driver, vm)) { +- event = virDomainEventLifecycleNewFromObj(vm, +- VIR_DOMAIN_EVENT_RESUMED, +- VIR_DOMAIN_EVENT_RESUMED_MIGRATED); +- } ++ qemuMigrationSrcRestoreDomainState(driver, vm); + goto endjob; + } + +@@ -4722,7 +4709,6 @@ qemuMigrationSrcPerformPhase(virQEMUDriverPtr driver, + + cleanup: + virDomainObjEndAPI(&vm); +- virObjectEventStateQueue(driver->domainEventState, event); + return ret; + } + +@@ -5074,13 +5060,8 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver, + goto endjob; + } + +- if (inPostCopy) { ++ if (inPostCopy) + doKill = false; +- event = virDomainEventLifecycleNewFromObj(vm, +- VIR_DOMAIN_EVENT_RESUMED, +- VIR_DOMAIN_EVENT_RESUMED_POSTCOPY); +- virObjectEventStateQueue(driver->domainEventState, event); +- } + } + + if (mig->jobInfo) { +@@ -5111,10 +5092,20 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver, + + dom = virGetDomain(dconn, vm->def->name, vm->def->uuid, vm->def->id); + +- event = virDomainEventLifecycleNewFromObj(vm, +- VIR_DOMAIN_EVENT_RESUMED, +- VIR_DOMAIN_EVENT_RESUMED_MIGRATED); +- virObjectEventStateQueue(driver->domainEventState, event); ++ if (inPostCopy) { ++ /* The only RESUME event during post-copy migration is triggered by ++ * QEMU when the running domain moves from the source to the ++ * destination host, but then the migration keeps running until all ++ * modified memory is transferred from the source host. This will ++ * result in VIR_DOMAIN_EVENT_RESUMED with RESUMED_POSTCOPY detail. ++ * However, our API documentation says we need to fire another RESUMED ++ * event at the very end of migration with RESUMED_MIGRATED detail. ++ */ ++ event = virDomainEventLifecycleNewFromObj(vm, ++ VIR_DOMAIN_EVENT_RESUMED, ++ VIR_DOMAIN_EVENT_RESUMED_MIGRATED); ++ virObjectEventStateQueue(driver->domainEventState, event); ++ } + + if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER); +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 37568165b7..2d51c0fa25 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -436,7 +436,6 @@ qemuProcessFakeReboot(void *opaque) + virDomainObjPtr vm = opaque; + qemuDomainObjPrivatePtr priv = vm->privateData; + virQEMUDriverPtr driver = priv->driver; +- virObjectEventPtr event = NULL; + virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + virDomainRunningReason reason = VIR_DOMAIN_RUNNING_BOOTED; + int ret = -1, rc; +@@ -473,9 +472,6 @@ qemuProcessFakeReboot(void *opaque) + goto endjob; + } + priv->gotShutdown = false; +- event = virDomainEventLifecycleNewFromObj(vm, +- VIR_DOMAIN_EVENT_RESUMED, +- VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); + + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) { + VIR_WARN("Unable to save status on vm %s after state change", +@@ -491,7 +487,6 @@ qemuProcessFakeReboot(void *opaque) + if (ret == -1) + ignore_value(qemuProcessKill(vm, VIR_QEMU_PROCESS_KILL_FORCE)); + virDomainObjEndAPI(&vm); +- virObjectEventStateQueue(driver->domainEventState, event); + virObjectUnref(cfg); + } + +@@ -3073,7 +3068,10 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm, + if (ret < 0) + goto release; + +- virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason); ++ /* The RESUME event handler will change the domain state with the reason ++ * saved in priv->runningReason and it will also emit corresponding domain ++ * lifecycle event. ++ */ + + cleanup: + virObjectUnref(cfg); +-- +2.19.1 + diff --git a/SOURCES/libvirt-qemu-Don-t-ignore-resume-events.patch b/SOURCES/libvirt-qemu-Don-t-ignore-resume-events.patch new file mode 100644 index 0000000..a44eb50 --- /dev/null +++ b/SOURCES/libvirt-qemu-Don-t-ignore-resume-events.patch @@ -0,0 +1,68 @@ +From 7359db070b7a1379ea33e2754a00e56ca5e6b29f Mon Sep 17 00:00:00 2001 +Message-Id: <7359db070b7a1379ea33e2754a00e56ca5e6b29f@dist-git> +From: Jiri Denemark +Date: Wed, 7 Nov 2018 14:34:52 +0100 +Subject: [PATCH] qemu: Don't ignore resume events + +Since commit v4.7.0-302-ge6d77a75c4 processing RESUME event is mandatory +for updating domain state. But the event handler explicitly ignored this +event in some cases. Thus the state would be wrong after a fake reboot +or when a domain was rebooted after it crashed. + +BTW, the code to ignore RESUME event after SHUTDOWN didn't make sense +even before making RESUME event mandatory. Most likely it was there as a +result of careless copy&paste from qemuProcessHandleStop. + +The corresponding debug message was clarified since the original state +does not have to be "paused" only and while we have a "resumed" event, +the state is called "running". + +https://bugzilla.redhat.com/show_bug.cgi?id=1612943 + +Signed-off-by: Jiri Denemark +(cherry picked from commit e47949357ba268e7e8c3adea7c262b84fa002302) + +https://bugzilla.redhat.com/show_bug.cgi?id=1634759 +https://bugzilla.redhat.com/show_bug.cgi?id=1634758 +https://bugzilla.redhat.com/show_bug.cgi?id=1643338 + +Signed-off-by: Jiri Denemark +Reviewed-by: Erik Skultety +--- + src/qemu/qemu_process.c | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 2d51c0fa25..9b5cb93325 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -699,15 +699,10 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + priv->runningReason = VIR_DOMAIN_RUNNING_UNKNOWN; + } + +- if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { +- if (priv->gotShutdown) { +- VIR_DEBUG("Ignoring RESUME event after SHUTDOWN"); +- goto unlock; +- } +- ++ if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_RUNNING) { + eventDetail = qemuDomainRunningReasonToResumeEvent(reason); +- VIR_DEBUG("Transitioned guest %s out of paused into resumed state, " +- "reason '%s', event detail %d", ++ VIR_DEBUG("Transitioned guest %s into running state, reason '%s', " ++ "event detail %d", + vm->def->name, virDomainRunningReasonTypeToString(reason), + eventDetail); + +@@ -722,7 +717,6 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + } + } + +- unlock: + virObjectUnlock(vm); + virObjectEventStateQueue(driver->domainEventState, event); + virObjectUnref(cfg); +-- +2.19.1 + diff --git a/SOURCES/libvirt-qemu-Map-running-reason-to-resume-event-detail.patch b/SOURCES/libvirt-qemu-Map-running-reason-to-resume-event-detail.patch new file mode 100644 index 0000000..817b06b --- /dev/null +++ b/SOURCES/libvirt-qemu-Map-running-reason-to-resume-event-detail.patch @@ -0,0 +1,121 @@ +From 919834294448ac9d1569a1f2620ea01d79a86e96 Mon Sep 17 00:00:00 2001 +Message-Id: <919834294448ac9d1569a1f2620ea01d79a86e96@dist-git> +From: Jiri Denemark +Date: Tue, 11 Sep 2018 15:13:08 +0200 +Subject: [PATCH] qemu: Map running reason to resume event detail +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Thanks to the previous commit the RESUME event handler knows what reason +should be used when changing the domain state to VIR_DOMAIN_RUNNING, but +the emitted VIR_DOMAIN_EVENT_RESUMED event still uses a generic +VIR_DOMAIN_EVENT_RESUMED_UNPAUSED detail. Luckily, the event detail can +be easily deduced from the running reason, which saves us from having to +pass one more value to the handler. + +Signed-off-by: Jiri Denemark +Reviewed-by: John Ferlan +(cherry picked from commit 8ae9b49f5a4a02f57a1dfa20d4fe04c3d40a4665) + +https://bugzilla.redhat.com/show_bug.cgi?id=1634758 +https://bugzilla.redhat.com/show_bug.cgi?id=1634759 + +Conflicts: + src/qemu/qemu_domain.c + src/qemu/qemu_domain.h + - nodenames code is not backported + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_domain.c | 29 +++++++++++++++++++++++++++++ + src/qemu/qemu_domain.h | 3 +++ + src/qemu/qemu_process.c | 11 +++++++---- + 3 files changed, 39 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 17be6e5537..d80f9b393e 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -13149,3 +13149,32 @@ qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivatePtr priv) + + return ret; + } ++ ++ ++virDomainEventResumedDetailType ++qemuDomainRunningReasonToResumeEvent(virDomainRunningReason reason) ++{ ++ switch (reason) { ++ case VIR_DOMAIN_RUNNING_RESTORED: ++ case VIR_DOMAIN_RUNNING_FROM_SNAPSHOT: ++ return VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT; ++ ++ case VIR_DOMAIN_RUNNING_MIGRATED: ++ case VIR_DOMAIN_RUNNING_MIGRATION_CANCELED: ++ return VIR_DOMAIN_EVENT_RESUMED_MIGRATED; ++ ++ case VIR_DOMAIN_RUNNING_POSTCOPY: ++ return VIR_DOMAIN_EVENT_RESUMED_POSTCOPY; ++ ++ case VIR_DOMAIN_RUNNING_UNKNOWN: ++ case VIR_DOMAIN_RUNNING_SAVE_CANCELED: ++ case VIR_DOMAIN_RUNNING_BOOTED: ++ case VIR_DOMAIN_RUNNING_UNPAUSED: ++ case VIR_DOMAIN_RUNNING_WAKEUP: ++ case VIR_DOMAIN_RUNNING_CRASHED: ++ case VIR_DOMAIN_RUNNING_LAST: ++ break; ++ } ++ ++ return VIR_DOMAIN_EVENT_RESUMED_UNPAUSED; ++} +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index 6a96f27a5f..cc406e3ca0 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -1066,4 +1066,7 @@ qemuDomainDiskCachemodeFlags(int cachemode, + + char * qemuDomainGetManagedPRSocketPath(qemuDomainObjPrivatePtr priv); + ++virDomainEventResumedDetailType ++qemuDomainRunningReasonToResumeEvent(virDomainRunningReason reason); ++ + #endif /* __QEMU_DOMAIN_H__ */ +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 7325bc4c90..37568165b7 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -694,6 +694,7 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + qemuDomainObjPrivatePtr priv; + virDomainRunningReason reason = VIR_DOMAIN_RUNNING_UNPAUSED; ++ virDomainEventResumedDetailType eventDetail; + + virObjectLock(vm); + +@@ -709,14 +710,16 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + goto unlock; + } + ++ eventDetail = qemuDomainRunningReasonToResumeEvent(reason); + VIR_DEBUG("Transitioned guest %s out of paused into resumed state, " +- "reason '%s'", +- vm->def->name, virDomainRunningReasonTypeToString(reason)); ++ "reason '%s', event detail %d", ++ vm->def->name, virDomainRunningReasonTypeToString(reason), ++ eventDetail); + + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason); + event = virDomainEventLifecycleNewFromObj(vm, +- VIR_DOMAIN_EVENT_RESUMED, +- VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); ++ VIR_DOMAIN_EVENT_RESUMED, ++ eventDetail); + + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, driver->caps) < 0) { + VIR_WARN("Unable to save status on vm %s after state change", +-- +2.19.1 + diff --git a/SOURCES/libvirt-qemu-Pass-running-reason-to-RESUME-event-handler.patch b/SOURCES/libvirt-qemu-Pass-running-reason-to-RESUME-event-handler.patch new file mode 100644 index 0000000..6e404ce --- /dev/null +++ b/SOURCES/libvirt-qemu-Pass-running-reason-to-RESUME-event-handler.patch @@ -0,0 +1,123 @@ +From 725d1095dfd473b2a0da59594276413ea6a7fa8b Mon Sep 17 00:00:00 2001 +Message-Id: <725d1095dfd473b2a0da59594276413ea6a7fa8b@dist-git> +From: Jiri Denemark +Date: Mon, 10 Sep 2018 19:41:53 +0200 +Subject: [PATCH] qemu: Pass running reason to RESUME event handler +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Whenever we get the RESUME event from QEMU, we change the state of the +affected domain to VIR_DOMAIN_RUNNING with VIR_DOMAIN_RUNNING_UNPAUSED +reason. This is fine if the domain is resumed unexpectedly, but when we +sent "cont" to QEMU we usually have a better reason for the state +change. The better reason is used in qemuProcessStartCPUs which also +sets the domain state to running if qemuMonitorStartCPUs reports +success. Thus we may end up with two state updates in a row, but the +final reason is correct. + +This patch is a preparation for dropping the state change done in +qemuMonitorStartCPUs for which we need to pass the actual running reason +to the RESUME event handler and use it there instead of +VIR_DOMAIN_RUNNING_UNPAUSED. + +Signed-off-by: Jiri Denemark +Reviewed-by: John Ferlan +(cherry picked from commit 5dab984ed0cd0332e59d719420ab2f9d009b952f) + +https://bugzilla.redhat.com/show_bug.cgi?id=1634758 +https://bugzilla.redhat.com/show_bug.cgi?id=1634759 + +Conflicts: + src/qemu/qemu_domain.h + - nodenames code is not backported + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_domain.h | 4 ++++ + src/qemu/qemu_process.c | 23 +++++++++++++++++------ + 2 files changed, 21 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index e748d78adb..6a96f27a5f 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -363,6 +363,10 @@ struct _qemuDomainObjPrivate { + + /* true if qemu-pr-helper process is running for the domain */ + bool prDaemonRunning; ++ ++ /* qemuProcessStartCPUs stores the reason for starting vCPUs here for the ++ * RESUME event handler to use it */ ++ virDomainRunningReason runningReason; + }; + + # define QEMU_DOMAIN_PRIVATE(vm) \ +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index 26979faa72..7325bc4c90 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -692,21 +692,28 @@ qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + virQEMUDriverPtr driver = opaque; + virObjectEventPtr event = NULL; + virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); ++ qemuDomainObjPrivatePtr priv; ++ virDomainRunningReason reason = VIR_DOMAIN_RUNNING_UNPAUSED; + + virObjectLock(vm); +- if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { +- qemuDomainObjPrivatePtr priv = vm->privateData; + ++ priv = vm->privateData; ++ if (priv->runningReason != VIR_DOMAIN_RUNNING_UNKNOWN) { ++ reason = priv->runningReason; ++ priv->runningReason = VIR_DOMAIN_RUNNING_UNKNOWN; ++ } ++ ++ if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { + if (priv->gotShutdown) { + VIR_DEBUG("Ignoring RESUME event after SHUTDOWN"); + goto unlock; + } + +- VIR_DEBUG("Transitioned guest %s out of paused into resumed state", +- vm->def->name); ++ VIR_DEBUG("Transitioned guest %s out of paused into resumed state, " ++ "reason '%s'", ++ vm->def->name, virDomainRunningReasonTypeToString(reason)); + +- virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, +- VIR_DOMAIN_RUNNING_UNPAUSED); ++ virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason); + event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_RESUMED, + VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); +@@ -3051,6 +3058,8 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm, + } + VIR_FREE(priv->lockState); + ++ priv->runningReason = reason; ++ + if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) + goto release; + +@@ -3068,6 +3077,7 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm, + return ret; + + release: ++ priv->runningReason = VIR_DOMAIN_RUNNING_UNKNOWN; + if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0) + VIR_WARN("Unable to release lease on %s", vm->def->name); + VIR_DEBUG("Preserving lock state '%s'", NULLSTR(priv->lockState)); +@@ -5928,6 +5938,7 @@ qemuProcessPrepareDomain(virQEMUDriverPtr driver, + priv->monError = false; + priv->monStart = 0; + priv->gotShutdown = false; ++ priv->runningReason = VIR_DOMAIN_RUNNING_UNKNOWN; + + VIR_DEBUG("Updating guest CPU definition"); + if (qemuProcessUpdateGuestCPU(vm->def, priv->qemuCaps, caps, flags) < 0) +-- +2.19.1 + diff --git a/SOURCES/libvirt-qemu-Properly-report-VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT.patch b/SOURCES/libvirt-qemu-Properly-report-VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT.patch new file mode 100644 index 0000000..2cfbf59 --- /dev/null +++ b/SOURCES/libvirt-qemu-Properly-report-VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT.patch @@ -0,0 +1,42 @@ +From fcfb306555cbae44542d3819e93a24f68b7e431a Mon Sep 17 00:00:00 2001 +Message-Id: +From: Jiri Denemark +Date: Mon, 10 Sep 2018 15:10:54 +0200 +Subject: [PATCH] qemu: Properly report VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT was defined but not used anywhere +in our event generation code. This fixes qemuDomainRevertToSnapshot to +properly report why the domain was resumed. + +Signed-off-by: Jiri Denemark +Reviewed-by: John Ferlan +(cherry picked from commit 55af06187c48a01192764d8638b85739b0178fe0) + +https://bugzilla.redhat.com/show_bug.cgi?id=1634758 +https://bugzilla.redhat.com/show_bug.cgi?id=1634759 + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_driver.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index c7689cc239..26aa557d9f 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -16321,7 +16321,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, + detail); + } else if (!was_running) { + /* Transition 8 */ +- detail = VIR_DOMAIN_EVENT_RESUMED; ++ detail = VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT; + event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_RESUMED, + detail); +-- +2.19.1 + diff --git a/SOURCES/libvirt-qemu-Report-more-appropriate-running-reasons.patch b/SOURCES/libvirt-qemu-Report-more-appropriate-running-reasons.patch new file mode 100644 index 0000000..1095745 --- /dev/null +++ b/SOURCES/libvirt-qemu-Report-more-appropriate-running-reasons.patch @@ -0,0 +1,61 @@ +From 338a37710209d5fc35e326925318f087d572ba25 Mon Sep 17 00:00:00 2001 +Message-Id: <338a37710209d5fc35e326925318f087d572ba25@dist-git> +From: Jiri Denemark +Date: Tue, 11 Sep 2018 19:26:07 +0200 +Subject: [PATCH] qemu: Report more appropriate running reasons +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch replaces some rather generic VIR_DOMAIN_RUNNING_UNPAUSED +reasons when changing domain state to running with more specific ones. +All of them are done when libvirtd reconnects to an existing domain +after being restarted and sees an unfinished migration or save. + +Signed-off-by: Jiri Denemark +Reviewed-by: John Ferlan +(cherry picked from commit 54b5b0ac3945ad5417b67bec8443cf6e7b3d482b) + +https://bugzilla.redhat.com/show_bug.cgi?id=1634758 +https://bugzilla.redhat.com/show_bug.cgi?id=1634759 + +Signed-off-by: Jiri Denemark +Reviewed-by: Ján Tomko +--- + src/qemu/qemu_process.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index a4b1f97df5..26979faa72 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -3247,7 +3247,7 @@ qemuProcessRecoverMigrationIn(virQEMUDriverPtr driver, + VIR_DEBUG("Incoming migration finished, resuming domain %s", + vm->def->name); + if (qemuProcessStartCPUs(driver, vm, +- VIR_DOMAIN_RUNNING_UNPAUSED, ++ VIR_DOMAIN_RUNNING_MIGRATED, + QEMU_ASYNC_JOB_NONE) < 0) { + VIR_WARN("Could not resume domain %s", vm->def->name); + } +@@ -3354,7 +3354,7 @@ qemuProcessRecoverMigrationOut(virQEMUDriverPtr driver, + (reason == VIR_DOMAIN_PAUSED_MIGRATION || + reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { + if (qemuProcessStartCPUs(driver, vm, +- VIR_DOMAIN_RUNNING_UNPAUSED, ++ VIR_DOMAIN_RUNNING_MIGRATION_CANCELED, + QEMU_ASYNC_JOB_NONE) < 0) { + VIR_WARN("Could not resume domain %s", vm->def->name); + } +@@ -3412,7 +3412,7 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver, + reason == VIR_DOMAIN_PAUSED_MIGRATION)) || + reason == VIR_DOMAIN_PAUSED_UNKNOWN)) { + if (qemuProcessStartCPUs(driver, vm, +- VIR_DOMAIN_RUNNING_UNPAUSED, ++ VIR_DOMAIN_RUNNING_SAVE_CANCELED, + QEMU_ASYNC_JOB_NONE) < 0) { + VIR_WARN("Could not resume domain '%s' after migration to file", + vm->def->name); +-- +2.19.1 + diff --git a/SOURCES/libvirt-virfile-Take-symlink-into-account-in-virFileIsSharedFixFUSE.patch b/SOURCES/libvirt-virfile-Take-symlink-into-account-in-virFileIsSharedFixFUSE.patch new file mode 100644 index 0000000..5f1d252 --- /dev/null +++ b/SOURCES/libvirt-virfile-Take-symlink-into-account-in-virFileIsSharedFixFUSE.patch @@ -0,0 +1,186 @@ +From 703d3a465850b768e627705a587cfd8095fe0be7 Mon Sep 17 00:00:00 2001 +Message-Id: <703d3a465850b768e627705a587cfd8095fe0be7@dist-git> +From: Michal Privoznik +Date: Tue, 23 Oct 2018 11:40:58 +0100 +Subject: [PATCH] virfile: Take symlink into account in virFileIsSharedFixFUSE + +RHEL-7.7: https://bugzilla.redhat.com/show_bug.cgi?id=1640465 +RHEL-7.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=1641798 + +Weirdly enough, there can be symlinks in the path we are trying +to fix. If it is the case our clever algorithm that finds matches +against mount table won't work. Canonicalize path at the +beginning then. + +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +(cherry picked from commit c0790e3a09f57da0bd25c7eac4a35ed6e7e9e858) +Signed-off-by: Michal Privoznik +Reviewed-by: Erik Skultety +--- + cfg.mk | 2 +- + src/util/virfile.c | 15 +++++++++++++-- + tests/virfilemock.c | 33 ++++++++++++++++++++++++++++++++- + tests/virfiletest.c | 1 + + 4 files changed, 47 insertions(+), 4 deletions(-) + +diff --git a/cfg.mk b/cfg.mk +index 6bebd0ad9f..e3e94bf6f0 100644 +--- a/cfg.mk ++++ b/cfg.mk +@@ -1216,7 +1216,7 @@ exclude_file_name_regexp--sc_prohibit_select = \ + ^cfg\.mk$$ + + exclude_file_name_regexp--sc_prohibit_canonicalize_file_name = \ +- ^cfg\.mk$$ ++ ^(cfg\.mk|tests/virfilemock\.c)$$ + + exclude_file_name_regexp--sc_prohibit_raw_allocation = \ + ^(docs/hacking\.html\.in|src/util/viralloc\.[ch]|examples/.*|tests/(securityselinuxhelper|(vircgroup|nss)mock|commandhelper)\.c|tools/wireshark/src/packet-libvirt\.c)$$ +diff --git a/src/util/virfile.c b/src/util/virfile.c +index e1dee7633a..716b55d770 100644 +--- a/src/util/virfile.c ++++ b/src/util/virfile.c +@@ -3549,9 +3549,19 @@ virFileIsSharedFixFUSE(const char *path, + char mntbuf[1024]; + char *mntDir = NULL; + char *mntType = NULL; ++ char *canonPath = NULL; + size_t maxMatching = 0; + int ret = -1; + ++ if (!(canonPath = virFileCanonicalizePath(path))) { ++ virReportSystemError(errno, ++ _("unable to canonicalize %s"), ++ path); ++ return -1; ++ } ++ ++ VIR_DEBUG("Path canonicalization: %s->%s", path, canonPath); ++ + if (!(f = setmntent(PROC_MOUNTS, "r"))) { + virReportSystemError(errno, + _("Unable to open %s"), +@@ -3563,7 +3573,7 @@ virFileIsSharedFixFUSE(const char *path, + const char *p; + size_t len = strlen(mb.mnt_dir); + +- if (!(p = STRSKIP(path, mb.mnt_dir))) ++ if (!(p = STRSKIP(canonPath, mb.mnt_dir))) + continue; + + if (*(p - 1) != '/' && *p != '/' && *p != '\0') +@@ -3581,12 +3591,13 @@ virFileIsSharedFixFUSE(const char *path, + + if (STREQ_NULLABLE(mntType, "fuse.glusterfs")) { + VIR_DEBUG("Found gluster FUSE mountpoint=%s for path=%s. " +- "Fixing shared FS type", mntDir, path); ++ "Fixing shared FS type", mntDir, canonPath); + *f_type = GFS2_MAGIC; + } + + ret = 0; + cleanup: ++ VIR_FREE(canonPath); + VIR_FREE(mntType); + VIR_FREE(mntDir); + endmntent(f); +diff --git a/tests/virfilemock.c b/tests/virfilemock.c +index 822c757380..ae5c8d025a 100644 +--- a/tests/virfilemock.c ++++ b/tests/virfilemock.c +@@ -28,11 +28,14 @@ + #endif + + #include "virmock.h" ++#include "virstring.h" ++#include "viralloc.h" + + #define VIR_FROM_THIS VIR_FROM_NONE + + static FILE *(*real_setmntent)(const char *filename, const char *type); + static int (*real_statfs)(const char *path, struct statfs *buf); ++static char *(*real_canonicalize_file_name)(const char *path); + + + static void +@@ -43,6 +46,7 @@ init_syms(void) + + VIR_MOCK_REAL_INIT(setmntent); + VIR_MOCK_REAL_INIT(statfs); ++ VIR_MOCK_REAL_INIT(canonicalize_file_name); + } + + +@@ -94,6 +98,7 @@ statfs_mock(const char *mtab, + FILE *f; + struct mntent mb; + char mntbuf[1024]; ++ char *canonPath = NULL; + int ret = -1; + + if (!(f = real_setmntent(mtab, "r"))) { +@@ -101,10 +106,16 @@ statfs_mock(const char *mtab, + return -1; + } + ++ /* We don't need to do this in callers because real statfs(2) ++ * does that for us. However, in mocked implementation we ++ * need to do this. */ ++ if (!(canonPath = canonicalize_file_name(path))) ++ return -1; ++ + while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) { + int ftype; + +- if (STRNEQ(mb.mnt_dir, path)) ++ if (STRNEQ(mb.mnt_dir, canonPath)) + continue; + + if (STREQ(mb.mnt_type, "nfs") || +@@ -136,6 +147,7 @@ statfs_mock(const char *mtab, + } + + endmntent(f); ++ VIR_FREE(canonPath); + return ret; + } + +@@ -152,3 +164,22 @@ statfs(const char *path, struct statfs *buf) + + return real_statfs(path, buf); + } ++ ++ ++char * ++canonicalize_file_name(const char *path) ++{ ++ if (getenv("LIBVIRT_MTAB")) { ++ const char *p; ++ char *ret; ++ ++ if ((p = STRSKIP(path, "/some/symlink"))) ++ ignore_value(virAsprintfQuiet(&ret, "/gluster%s", p)); ++ else ++ ignore_value(VIR_STRDUP_QUIET(ret, path)); ++ ++ return ret; ++ } ++ ++ return real_canonicalize_file_name(path); ++} +diff --git a/tests/virfiletest.c b/tests/virfiletest.c +index be4dbf8910..a246d601ba 100644 +--- a/tests/virfiletest.c ++++ b/tests/virfiletest.c +@@ -457,6 +457,7 @@ mymain(void) + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/nfs/blah", false); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/file", true); + DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/gluster/sshfs/file", false); ++ DO_TEST_FILE_IS_SHARED_FS_TYPE("mounts3.txt", "/some/symlink/file", true); + + return ret != 0 ? EXIT_FAILURE : EXIT_SUCCESS; + } +-- +2.19.1 + diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index a8843b7..926c37d 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -253,7 +253,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 4.5.0 -Release: 10%{?dist}.2%{?extra_release} +Release: 10%{?dist}.3%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -374,6 +374,13 @@ Patch108: libvirt-virfiletest-Fix-test-name-prefix-for-virFileInData-test.patch Patch109: libvirt-virfiletst-Test-virFileIsSharedFS.patch Patch110: libvirt-virFileIsSharedFSType-Detect-direct-mount-points.patch Patch111: libvirt-virfile-Rework-virFileIsSharedFixFUSE.patch +Patch112: libvirt-virfile-Take-symlink-into-account-in-virFileIsSharedFixFUSE.patch +Patch113: libvirt-qemu-Properly-report-VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT.patch +Patch114: libvirt-qemu-Report-more-appropriate-running-reasons.patch +Patch115: libvirt-qemu-Pass-running-reason-to-RESUME-event-handler.patch +Patch116: libvirt-qemu-Map-running-reason-to-resume-event-detail.patch +Patch117: libvirt-qemu-Avoid-duplicate-resume-events-and-state-changes.patch +Patch118: libvirt-qemu-Don-t-ignore-resume-events.patch Requires: libvirt-daemon = %{version}-%{release} Requires: libvirt-daemon-config-network = %{version}-%{release} @@ -2273,6 +2280,15 @@ exit 0 %changelog +* Thu Nov 8 2018 Jiri Denemark - 4.5.0-10.el7_6.3 +- virfile: Take symlink into account in virFileIsSharedFixFUSE (rhbz#1641798) +- qemu: Properly report VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT (rhbz#1634759) +- qemu: Report more appropriate running reasons (rhbz#1634759) +- qemu: Pass running reason to RESUME event handler (rhbz#1634759) +- qemu: Map running reason to resume event detail (rhbz#1634759) +- qemu: Avoid duplicate resume events and state changes (rhbz#1634759) +- qemu: Don't ignore resume events (rhbz#1634759) + * Wed Oct 10 2018 Jiri Denemark - 4.5.0-10.el7_6.2 - virfile: fix cast-align error (rhbz#1635705) - virfiletest: Fix test name prefix for virFileInData test (rhbz#1635705)