Skip to content

Commit 04938c6

Browse files
committed
init: reboot after reporting the workload exit code
KRUN_EXIT_CODE_IOCTL is used only as a transfer workload exit code Guest, no generic VMM shutdown mechanism is provided. In the past init logged the workload exit code and simply returned. On platforms where there is no shutdown/reset path to wake VMM later, the guest Can continue running after the workload exits. Keep ioctl for exit code transmission once reported by init Workload exit code requesting kernel-mediated reboot/reset for VMM Still exit via existing platform closure path. On x86 guests, it is important to use the reboot/reset path as powering off may cause Fallback to a stopped state, which does not trigger libkrun's VM exit path. Add end-to-end tests to verify that the runner exits with the workload Exit code. Signed-off-by: Zewei Yang <yangzewei@loongson.cn>
1 parent 788cf91 commit 04938c6

1 file changed

Lines changed: 16 additions & 2 deletions

File tree

init/init.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <net/if.h>
1515
#include <sys/ioctl.h>
1616
#include <sys/mount.h>
17+
#include <sys/reboot.h>
1718
#include <sys/resource.h>
1819
#include <sys/socket.h>
1920
#include <sys/stat.h>
@@ -1003,6 +1004,20 @@ void set_exit_code(int code)
10031004
close(fd);
10041005
}
10051006

1007+
static void shutdown_vm(void)
1008+
{
1009+
sync();
1010+
1011+
/*
1012+
* Use a kernel-mediated reboot here rather than RB_POWER_OFF.
1013+
* On x86 guests, RB_POWER_OFF may fall back to halt, which does not
1014+
* trigger libkrun's VM exit path, while reboot/reset does.
1015+
*/
1016+
if (reboot(RB_AUTOBOOT) < 0) {
1017+
printf("Error: reboot() failed: %s\n", strerror(errno));
1018+
}
1019+
}
1020+
10061021
int try_mount(const char *source, const char *target, const char *fstype,
10071022
unsigned long mountflags, const void *data)
10081023
{
@@ -1241,13 +1256,12 @@ int main(int argc, char **argv)
12411256
// Not the first child, ignore it.
12421257
};
12431258

1244-
// The workload's entrypoint has exited, record its exit code and exit
1245-
// ourselves.
12461259
if (WIFEXITED(status)) {
12471260
set_exit_code(WEXITSTATUS(status));
12481261
} else if (WIFSIGNALED(status)) {
12491262
set_exit_code(WTERMSIG(status) + 128);
12501263
}
1264+
shutdown_vm();
12511265
}
12521266

12531267
return 0;

0 commit comments

Comments
 (0)