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));