Steps:
1 virsh reboot guest1 --mode=acpi
2 virsh shutdown guest1 --mode=agent
Expected result:
As the SHUTDOWN job is after REBOOT, we expected the guest to be *shutoff*.
Exacted result:
After the 2 steps above, the guest got *rebooted*.
The reason to this problem:
1 in qemuDomainReboot(mode acpi), it sets priv->fakeReboot to 1.
2 after shutdown/reboot, qemu monitor IO trigged
qemuProcessHandleShutdown(), which finds that priv->fakeReboot is 1, and reboot
the guest.
Root Cause of the problem:
After further look into the problem, We found that the design of
acpi/agent shutdown/reboot seems a little chaotic.
-----------------------------------
sheet1 who sets fakeReboot
-----------------------------------
shutdown reboot
acpi Y(0) Y(1)
agent N N
It's apparently, *acpi-mode* jobs set fakeReboot.
-----------------------------------
sheet2 who needs to check fakeReboot(qemuProcessHandleShutdown())
-----------------------------------
shutdown reboot
acpi Y Y
agent *Y* *N*
Things become a little odd here. only agent-mode reboot doesn't check
fakeReboot.
We can tell from the above 2 sheets, that they're not consistent.
*Agent-mode shutdown checks fakeReboot(trigger by SHUTDOWN monitorIO
event), while it didn't set it before.*
The chaos is not caused by libvirtd, it's a systematic problem, including
guest os and qemu. (guest os writes ACPI, triggers qemu, qemu then triggers
libvirtd)
Solution:
A simple solution is to make the 1st sheet consistent to the 2nd sheet,
which is:
-----------------------------------
sheet3 who should set fakeReboot:
-----------------------------------
shutdown reboot
acpi Y(0) Y(1)
agent *Y(0)* N
-----------------------------------
we let agent-mode shutdown set fakeReboot to 0.
Signed-off-by: Zhang Bo <[email protected]>
Signed-off-by: Wang Yufei <[email protected]>
---
src/qemu/qemu_driver.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7eb5a7d..c751dcf 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1959,6 +1959,8 @@ static int qemuDomainShutdownFlags(virDomainPtr dom,
unsigned int flags)
goto endjob;
}
+ qemuDomainSetFakeReboot(driver, vm, isReboot);
+
if (useAgent) {
qemuDomainObjEnterAgent(vm);
ret = qemuAgentShutdown(priv->agent, agentFlag);
@@ -1970,7 +1972,6 @@ static int qemuDomainShutdownFlags(virDomainPtr dom,
unsigned int flags)
*/
if (!useAgent ||
(ret < 0 && (acpiRequested || !flags))) {
- qemuDomainSetFakeReboot(driver, vm, isReboot);
/* Even if agent failed, we have to check if guest went away
* by itself while our locks were down. */
--
1.7.12.4
--
libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list