diff options
author | Raphael Ning <raphning@amazon.com> | 2022-03-23 14:44:18 +0000 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2022-03-23 15:58:27 +0100 |
commit | 501646beec2b1c4a2ff4f2909c5ddb5cea8c7f8e (patch) | |
tree | ba5bf8bd4a43a65cbc95c688af9cd89dff6558ce /kexec/kexec.c | |
parent | 1d7a308bf7349fcf1627e950159029dfccf85891 (diff) | |
download | kexec-tools-501646beec2b1c4a2ff4f2909c5ddb5cea8c7f8e.tar.gz |
kexec-xen: Allow xen_kexec_exec() to return in case of Live Update
Currently, my_exec() does not expect the Xen KEXEC_CMD_kexec hypercall
to return on success, because it assumes that the hypercall always
triggers an immediate reboot. However, for Live Update, the hypercall
merely schedules the kexec operation and returns; the actual reboot
happens asynchronously. [1]
Therefore, rework the Xen code path of my_exec() such that it does not
treat a successfully processed Live Update request as an error. Also,
rephrase the comment above the function to remove ambiguity.
[1] https://lists.xen.org/archives/html/xen-devel/2021-05/msg00286.html
Signed-off-by: Raphael Ning <raphning@amazon.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'kexec/kexec.c')
-rw-r--r-- | kexec/kexec.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/kexec/kexec.c b/kexec/kexec.c index 865de61..829a6ea 100644 --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -902,13 +902,28 @@ static int my_shutdown(void) } /* - * Exec the new kernel (reboot) + * Exec the new kernel. If successful, this triggers an immediate reboot + * and does not return, but Xen Live Update is an exception (more on this + * below). */ static int my_exec(void) { - if (xen_present()) - xen_kexec_exec(kexec_flags); - else + if (xen_present()) { + int ret; + + /* + * There are two cases in which the Xen hypercall may return: + * 1) An error occurred, e.g. the kexec image was not loaded. + * The exact error is indicated by errno. + * 2) Live Update was successfully scheduled. Note that unlike + * a normal kexec, Live Update happens asynchronously, i.e. + * the hypercall merely schedules the kexec operation and + * returns immediately. + */ + ret = xen_kexec_exec(kexec_flags); + if ((kexec_flags & KEXEC_LIVE_UPDATE) && !ret) + return 0; + } else reboot(LINUX_REBOOT_CMD_KEXEC); /* I have failed if I make it here */ fprintf(stderr, "kexec failed: %s\n", |