Page MenuHomeFreeBSD

D58788.id183888.diff
No OneTemporary

D58788.id183888.diff

diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c
--- a/usr.sbin/bhyve/bhyverun.c
+++ b/usr.sbin/bhyve/bhyverun.c
@@ -59,6 +59,7 @@
#endif
#include <libgen.h>
#include <libutil.h>
+#include <signal.h>
#include <unistd.h>
#include <assert.h>
#include <pthread.h>
@@ -127,6 +128,11 @@
static cpuset_t **vcpumap;
+static void
+monitor_signal_handler(int signo __unused)
+{
+}
+
/*
* XXX This parser is known to have the following issues:
* 1. It accepts null key=value tokens ",," as setting "cpus" to an
@@ -826,7 +832,10 @@
int
main(int argc, char *argv[])
{
- int error, status;
+ struct sigaction action, old_sigchld;
+ sigset_t mask, old_mask;
+ pid_t child;
+ int error, signo, status;
int max_vcpus, memflags;
struct vcpu *bsp;
struct vmctx *ctx;
@@ -912,29 +921,71 @@
init_bootrom(ctx);
if (get_config_bool_default("monitor", false)) {
+ bool sigterm_received = false;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGCHLD);
+ sigaddset(&mask, SIGTERM);
+ if (sigprocmask(SIG_BLOCK, &mask, &old_mask) == -1)
+ err(BHYVE_EXIT_ERROR, "sigprocmask(SIG_BLOCK)");
+
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = monitor_signal_handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = SA_NOCLDSTOP;
+ if (sigaction(SIGCHLD, &action, &old_sigchld) == -1)
+ err(BHYVE_EXIT_ERROR, "sigaction(SIGCHLD)");
+
while (1) {
- pid_t child = fork();
+ child = fork();
if (child == -1) {
EPRINTLN("Monitor mode fork failed: %s",
strerror(errno));
exit(BHYVE_EXIT_ERROR);
}
- if (child == 0)
+ if (child == 0) {
+ if (sigaction(SIGCHLD, &old_sigchld, NULL) == -1)
+ err(BHYVE_EXIT_ERROR, "sigaction(SIGCHLD)");
+ if (sigprocmask(SIG_SETMASK, &old_mask, NULL) == -1)
+ err(BHYVE_EXIT_ERROR,
+ "sigprocmask(SIG_SETMASK)");
break;
- while ((error = waitpid(child, &status, 0)) == -1 && errno == EINTR)
- ;
- if (error == -1) {
- EPRINTLN("Monitor mode wait failed: %s",
- strerror(errno));
- exit(BHYVE_EXIT_ERROR);
}
+
+ for (;;) {
+ do {
+ signo = sigwaitinfo(&mask, NULL);
+ } while (signo == -1 && errno == EINTR);
+ if (signo == -1)
+ err(BHYVE_EXIT_ERROR, "sigwaitinfo");
+ if (signo == SIGTERM) {
+ sigterm_received = true;
+ if (kill(child, SIGTERM) == -1 &&
+ errno != ESRCH)
+ warn("Unable to forward SIGTERM to child");
+ continue;
+ }
+
+ do {
+ error = waitpid(child, &status, WNOHANG);
+ } while (error == -1 && errno == EINTR);
+ if (error == -1) {
+ EPRINTLN("Monitor mode wait failed: %s",
+ strerror(errno));
+ exit(BHYVE_EXIT_ERROR);
+ }
+ if (error == child)
+ break;
+ }
+
if (WIFSIGNALED(status)) {
EPRINTLN("Child process was killed by signal %d",
WTERMSIG(status));
exit(BHYVE_EXIT_ERROR);
} else {
status = WEXITSTATUS(status);
- if (status != BHYVE_EXIT_RESET)
+ if (status != BHYVE_EXIT_RESET ||
+ sigterm_received)
exit(status);
}
if (vm_reinit(ctx) != 0) {

File Metadata

Mime Type
text/plain
Expires
Mon, Aug 17, 9:34 PM (1 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36569055
Default Alt Text
D58788.id183888.diff (3 KB)

Event Timeline