[libvirt] qemu: lifecycle: reboot + shutdown, unexpected vm status.
Michal Privoznik
mprivozn at redhat.com
Thu Apr 16 11:09:28 UTC 2015
On 16.04.2015 08:02, zhang bo wrote:
> 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*. (Do you think so?)
>
>
> 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 needs to check 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)
>
>
> My 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.
> --------------------------------------------------------------------------------
> 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. */
Yes, the analysis is correct and the patch looks right. Can you please
post it among with commit message so that I can push it?
Michal
More information about the libvir-list
mailing list