git: 1f3aeb3ea5a5 - main - bhyve: monitor: detect monitor exit

Roman Bogorodskiy <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a806095.32d50.53c35a21__1456.59202696464$1786798245$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by novel:

URL: https://cgit.FreeBSD.org/src/commit/?id=1f3aeb3ea5a52e16e87439160dc19c53526600c3

commit 1f3aeb3ea5a52e16e87439160dc19c53526600c3
Author:     Roman Bogorodskiy <[email protected]>
AuthorDate: 2026-08-11 16:20:31 +0000
Commit:     Roman Bogorodskiy <[email protected]>
CommitDate: 2026-08-15 08:58:02 +0000

    bhyve: monitor: detect monitor exit
    
    Currently, sending SIGTERM to the bhyve process triggers ACPI poweroff
    for a VM. However, when running bhyve in monitor mode (-M), there are
    two processes: the monitor process and the actual VM process. Sending
    SIGTERM to the VM process works as before -- it powers off the VM.
    But sending SIGTERM to the monitor process just kills the monitor
    process, leaving the stale VM process running.
    
    Fix that by creating a pipe between these two processes. The child
    process uses the pipe to detect when the monitor goes away, and exits
    automatically.
    
    MFC after:              2 weeks
    Reviewed by:            markj
    Sponsored by:           The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D58788
---
 usr.sbin/bhyve/bhyverun.c | 41 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 37 insertions(+), 4 deletions(-)

diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c
index c089d1fbc8fa..339cf5071906 100644
--- a/usr.sbin/bhyve/bhyverun.c
+++ b/usr.sbin/bhyve/bhyverun.c
@@ -54,9 +54,7 @@
 #include <string.h>
 #include <err.h>
 #include <errno.h>
-#ifdef BHYVE_SNAPSHOT
 #include <fcntl.h>
-#endif
 #include <libgen.h>
 #include <libutil.h>
 #include <unistd.h>
@@ -127,6 +125,29 @@ static struct vcpu_info {
 
 static cpuset_t **vcpumap;
 
+static void
+monitor_pipe_handler(int fd __unused, enum ev_type type __unused,
+    void *param __unused)
+{
+
+	exit(BHYVE_EXIT_ERROR);
+}
+
+static void
+monitor_pipe_init(int fd)
+{
+#ifndef WITHOUT_CAPSICUM
+	cap_rights_t rights;
+
+	cap_rights_init(&rights, CAP_EVENT);
+	if (caph_rights_limit(fd, &rights) == -1)
+		err(BHYVE_EXIT_ERROR, "Unable to apply rights to monitor pipe");
+#endif
+
+	if (mevent_add(fd, EVF_READ, monitor_pipe_handler, NULL) == NULL)
+		errx(BHYVE_EXIT_ERROR, "Unable to register parent exit event");
+}
+
 /*
  * XXX This parser is known to have the following issues:
  * 1.  It accepts null key=value tokens ",," as setting "cpus" to an
@@ -922,17 +943,29 @@ main(int argc, char *argv[])
 	init_bootrom(ctx);
 
 	if (get_config_bool_default("monitor", false)) {
+		int monitor_pipe[2];
+		pid_t child;
+
 		while (1) {
-			pid_t child = fork();
+			if (pipe2(monitor_pipe, O_CLOEXEC) == -1)
+				err(BHYVE_EXIT_ERROR, "pipe2");
+
+			child = fork();
 			if (child == -1) {
 				EPRINTLN("Monitor mode fork failed: %s",
 				    strerror(errno));
 				exit(BHYVE_EXIT_ERROR);
 			}
-			if (child == 0)
+			if (child == 0) {
+				close(monitor_pipe[1]);
+				monitor_pipe_init(monitor_pipe[0]);
 				break;
+			}
+
+			close(monitor_pipe[0]);
 			while ((error = waitpid(child, &status, 0)) == -1 && errno == EINTR)
 			    ;
+			close(monitor_pipe[1]);
 			if (error == -1) {
 				EPRINTLN("Monitor mode wait failed: %s",
 				    strerror(errno));
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.