git: 1f3aeb3ea5a5 - main - bhyve: monitor: detect monitor exit
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 15 Aug 2026 12:50:29 UTC
The branch main has been updated by novel:
URL: https://cgit.FreeBSD.org/src/commit/?id=1f3aeb3ea5a52e16e87439160dc19c53526600c3
commit 1f3aeb3ea5a52e16e87439160dc19c53526600c3
Author: Roman Bogorodskiy <novel@FreeBSD.org>
AuthorDate: 2026-08-11 16:20:31 +0000
Commit: Roman Bogorodskiy <novel@FreeBSD.org>
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));