git: 24cd5c26fe3e - main - bhyveload: support guest rebooting from the loader

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Fri, 05 Jan 2024 06:22:05 UTC
The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=24cd5c26fe3ef7181e85467d9d55afbd76af5a2c

commit 24cd5c26fe3ef7181e85467d9d55afbd76af5a2c
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2024-01-05 06:21:15 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2024-01-05 06:21:15 +0000

    bhyveload: support guest rebooting from the loader
    
    userboot has a EXIT_REBOOT code that it uses when the 'reboot' loader
    command is executed.  Use that and longjmp back to reinit the VM
    entirely with a reboot request.  This fixes the 'reboot' option in the
    loader menu to actually reboot rather than shutdown the VM.
    
    The JMP_* constants are introduced to keep track of why we're doing a
    longjmp, though they aren't currently used.  We'll notably still do a
    complete reload of the interpreter to give the rebooted VM that new
    loader smell.  It just seemed forward thinking to just keep track of the
    different setjmp points.
    
    While we're here, we don't actually need to keep the fd we passed to
    fdlopen(3), so let's avoid leaking it.
    
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D43300
---
 usr.sbin/bhyveload/bhyveload.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/usr.sbin/bhyveload/bhyveload.c b/usr.sbin/bhyveload/bhyveload.c
index f75ef27dd958..37338e77d621 100644
--- a/usr.sbin/bhyveload/bhyveload.c
+++ b/usr.sbin/bhyveload/bhyveload.c
@@ -89,6 +89,16 @@
 
 #define	NDISKS	32
 
+/*
+ * Reason for our loader reload and reentry, though these aren't really used
+ * at the moment.
+ */
+enum {
+	/* 0 cannot be allocated; setjmp(3) return. */
+	JMP_SWAPLOADER = 0x01,
+	JMP_REBOOT,
+};
+
 static struct termios term, oldterm;
 static int disk_fd[NDISKS];
 static int ndisks;
@@ -543,6 +553,8 @@ cb_exit(void *arg __unused, int v)
 {
 
 	tcsetattr(consout_fd, TCSAFLUSH, &oldterm);
+	if (v == USERBOOT_EXIT_REBOOT)
+		longjmp(jb, JMP_REBOOT);
 	exit(v);
 }
 
@@ -628,7 +640,7 @@ cb_swap_interpreter(void *arg __unused, const char *interp_req)
 
 	if (asprintf(&loader, "userboot_%s.so", interp_req) == -1)
 		err(EX_OSERR, "malloc");
-	longjmp(jb, 1);
+	longjmp(jb, JMP_SWAPLOADER);
 }
 
 static struct loader_callbacks cb = {
@@ -769,6 +781,8 @@ loader_open(int bootfd)
 	loader_hdl = fdlopen(fd, RTLD_LOCAL);
 	if (!loader_hdl)
 		errx(EX_OSERR, "dlopen: %s", dlerror());
+	if (fd != explicit_loader_fd)
+		close(fd);
 }
 
 int