bhyve: Eliminate exit status magic numbers

bhyve's exit status codes indicate how the VM was terminated.
Unfortunately, their meaning within the source code is somewhat
unclear since they are only used as magic numbers.

Fix this by defining exit status macros and using them to replace
the magic numbers in exit(3) function calls.

Differential Revision:	https://reviews.freebsd.org/D53730
Reviewed by:	markj, corvink, emaste
Sponsored by:	The FreeBSD Foundation
Sponsored by:	Klara, Inc.
MFC after:	3 months
This commit is contained in:
Bojan Novković
2025-11-06 15:28:24 +01:00
parent bd16bac27e
commit 3c0686082d
13 changed files with 62 additions and 50 deletions
+1 -1
View File
@@ -168,7 +168,7 @@ bhyve_optparse(int argc, char **argv)
pci_print_supported_devices();
exit(0);
} else if (pci_parse_slot(optarg) != 0)
exit(4);
exit(BHYVE_EXIT_ERROR);
else
break;
case 'S':
+4 -4
View File
@@ -115,15 +115,15 @@ vmexit_suspend(struct vmctx *ctx, struct vcpu *vcpu, struct vm_run *vmrun)
switch (how) {
case VM_SUSPEND_RESET:
exit(0);
exit(BHYVE_EXIT_RESET);
case VM_SUSPEND_POWEROFF:
if (get_config_bool_default("destroy_on_poweroff", false))
vm_destroy(ctx);
exit(1);
exit(BHYVE_EXIT_POWEROFF);
case VM_SUSPEND_HALT:
exit(2);
exit(BHYVE_EXIT_HALT);
case VM_SUSPEND_DESTROY:
exit(4);
exit(BHYVE_EXIT_ERROR);
default:
fprintf(stderr, "vmexit_suspend: invalid reason %d\n", how);
exit(100);
+4 -4
View File
@@ -186,7 +186,7 @@ bhyve_optparse(int argc, char **argv)
pci_print_supported_devices();
exit(0);
} else if (pci_parse_slot(optarg) != 0)
exit(4);
exit(BHYVE_EXIT_ERROR);
else
break;
case 'S':
@@ -276,7 +276,7 @@ bhyve_init_vcpu(struct vcpu *vcpu)
err = vm_get_capability(vcpu, VM_CAP_HALT_EXIT, &tmp);
if (err < 0) {
EPRINTLN("VM exit on HLT not supported");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
vm_set_capability(vcpu, VM_CAP_HALT_EXIT, 1);
}
@@ -288,7 +288,7 @@ bhyve_init_vcpu(struct vcpu *vcpu)
err = vm_get_capability(vcpu, VM_CAP_PAUSE_EXIT, &tmp);
if (err < 0) {
EPRINTLN("SMP mux requested, no pause support");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
vm_set_capability(vcpu, VM_CAP_PAUSE_EXIT, 1);
}
@@ -300,7 +300,7 @@ bhyve_init_vcpu(struct vcpu *vcpu)
if (err) {
EPRINTLN("Unable to set x2apic state (%d)", err);
exit(4);
exit(BHYVE_EXIT_ERROR);
}
vm_set_capability(vcpu, VM_CAP_ENABLE_INVPCID, 1);
+1 -1
View File
@@ -368,7 +368,7 @@ fwctl_request(uint32_t value)
/* Verify size */
if (value < 12) {
printf("msg size error");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
rinfo.req_size = value;
rinfo.req_count = 1;
+5 -5
View File
@@ -409,17 +409,17 @@ vmexit_suspend(struct vmctx *ctx, struct vcpu *vcpu, struct vm_run *vmrun)
switch (how) {
case VM_SUSPEND_RESET:
exit(0);
exit(BHYVE_EXIT_RESET);
case VM_SUSPEND_POWEROFF:
if (get_config_bool_default("destroy_on_poweroff", false))
vm_destroy(ctx);
exit(1);
exit(BHYVE_EXIT_POWEROFF);
case VM_SUSPEND_HALT:
exit(2);
exit(BHYVE_EXIT_HALT);
case VM_SUSPEND_TRIPLEFAULT:
exit(3);
exit(BHYVE_EXIT_TRIPLEFAULT);
case VM_SUSPEND_DESTROY:
exit(4);
exit(BHYVE_EXIT_ERROR);
default:
EPRINTLN("vmexit_suspend: invalid reason %d", how);
exit(100);
+23 -23
View File
@@ -477,7 +477,7 @@ set_vcpu_affinities(void)
value = get_config_value_node(nvl, "cpus");
if (value == NULL) {
EPRINTLN("Missing CPU set for domain %d", dom);
exit(4);
exit(BHYVE_EXIT_ERROR);
}
parse_cpuset(dom, value, &cpus);
@@ -487,7 +487,7 @@ set_vcpu_affinities(void)
EPRINTLN(
"Unable to set vCPU %d affinity for domain %d: %s",
cpu, dom, strerror(errno));
exit(4);
exit(BHYVE_EXIT_ERROR);
}
}
}
@@ -504,7 +504,7 @@ set_vcpu_affinities(void)
EPRINTLN(
"Unable to set vCPU %d affinity for domain %d: %s",
cpu, 0, strerror(errno));
exit(4);
exit(BHYVE_EXIT_ERROR);
}
}
}
@@ -562,7 +562,7 @@ fbsdrun_start_thread(void *param)
vm_loop(vi->ctx, vi->vcpu);
/* We get here if the VM was destroyed asynchronously. */
exit(4);
exit(BHYVE_EXIT_ERROR);
}
void
@@ -596,7 +596,7 @@ fbsdrun_deletecpu(int vcpu)
pthread_mutex_lock(&resetcpu_mtx);
if (!CPU_ISSET(vcpu, &cpumask)) {
EPRINTLN("Attempting to delete unknown cpu %d", vcpu);
exit(4);
exit(BHYVE_EXIT_ERROR);
}
CPU_CLR(vcpu, &cpumask);
@@ -645,7 +645,7 @@ vm_loop(struct vmctx *ctx, struct vcpu *vcpu)
if (exitcode >= VM_EXITCODE_MAX ||
vmexit_handlers[exitcode] == NULL) {
warnx("vm_loop: unexpected exitcode 0x%x", exitcode);
exit(4);
exit(BHYVE_EXIT_ERROR);
}
rc = (*vmexit_handlers[exitcode])(ctx, vcpu, &vmrun);
@@ -656,7 +656,7 @@ vm_loop(struct vmctx *ctx, struct vcpu *vcpu)
case VMEXIT_ABORT:
abort();
default:
exit(4);
exit(BHYVE_EXIT_ERROR);
}
}
EPRINTLN("vm_run error %d, errno %d", error, errno);
@@ -816,7 +816,7 @@ main(int argc, char *argv[])
if (error) {
fprintf(stderr, "Failed to read checkpoint info from "
"file: '%s'.\n", restore_file);
exit(1);
exit(BHYVE_EXIT_ERROR);
}
vmname = lookup_vmname(&rstate);
if (vmname != NULL)
@@ -833,7 +833,7 @@ main(int argc, char *argv[])
if (get_config_bool_default("config.dump", false)) {
dump_config();
exit(1);
exit(BHYVE_EXIT_POWEROFF);
}
calc_topology();
@@ -855,7 +855,7 @@ main(int argc, char *argv[])
if (guest_ncpus < 1) {
fprintf(stderr, "Invalid guest vCPUs (%d)\n", guest_ncpus);
exit(1);
exit(BHYVE_EXIT_ERROR);
}
#endif
@@ -864,7 +864,7 @@ main(int argc, char *argv[])
if (guest_ncpus > max_vcpus) {
fprintf(stderr, "%d vCPUs requested but only %d available\n",
guest_ncpus, max_vcpus);
exit(4);
exit(BHYVE_EXIT_ERROR);
}
bhyve_init_vcpu(bsp);
@@ -898,17 +898,17 @@ main(int argc, char *argv[])
init_mem(guest_ncpus);
init_bootrom(ctx);
if (bhyve_init_platform(ctx, bsp) != 0)
exit(4);
exit(BHYVE_EXIT_ERROR);
if (qemu_fwcfg_init(ctx) != 0) {
fprintf(stderr, "qemu fwcfg initialization error\n");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
if (qemu_fwcfg_add_file("opt/bhyve/hw.ncpu", sizeof(guest_ncpus),
&guest_ncpus) != 0) {
fprintf(stderr, "Could not add qemu fwcfg opt/bhyve/hw.ncpu\n");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
/*
@@ -917,11 +917,11 @@ main(int argc, char *argv[])
if (init_pci(ctx) != 0) {
EPRINTLN("Device emulation initialization error: %s",
strerror(errno));
exit(4);
exit(BHYVE_EXIT_ERROR);
}
if (init_tpm(ctx) != 0) {
EPRINTLN("Failed to init TPM device");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
/*
@@ -946,37 +946,37 @@ main(int argc, char *argv[])
FPRINTLN(stdout, "Pausing pci devs...");
if (vm_pause_devices() != 0) {
EPRINTLN("Failed to pause PCI device state.");
exit(1);
exit(BHYVE_EXIT_ERROR);
}
FPRINTLN(stdout, "Restoring vm mem...");
if (restore_vm_mem(ctx, &rstate) != 0) {
EPRINTLN("Failed to restore VM memory.");
exit(1);
exit(BHYVE_EXIT_ERROR);
}
FPRINTLN(stdout, "Restoring pci devs...");
if (vm_restore_devices(&rstate) != 0) {
EPRINTLN("Failed to restore PCI device state.");
exit(1);
exit(BHYVE_EXIT_ERROR);
}
FPRINTLN(stdout, "Restoring kernel structs...");
if (vm_restore_kern_structs(ctx, &rstate) != 0) {
EPRINTLN("Failed to restore kernel structs.");
exit(1);
exit(BHYVE_EXIT_ERROR);
}
FPRINTLN(stdout, "Resuming pci devs...");
if (vm_resume_devices() != 0) {
EPRINTLN("Failed to resume PCI device state.");
exit(1);
exit(BHYVE_EXIT_ERROR);
}
}
#endif
if (bhyve_init_platform_late(ctx, bsp) != 0)
exit(4);
exit(BHYVE_EXIT_ERROR);
/*
* Change the proc title to include the VM name.
@@ -1018,5 +1018,5 @@ main(int argc, char *argv[])
*/
mevent_dispatch();
exit(4);
exit(BHYVE_EXIT_ERROR);
}
+10
View File
@@ -34,6 +34,16 @@
#define VMEXIT_CONTINUE (0)
#define VMEXIT_ABORT (-1)
/*
* Exit status codes as described in the bhyve(8) manpage.
*/
#define BHYVE_EXIT_RESET 0
#define BHYVE_EXIT_POWEROFF 1
#define BHYVE_EXIT_HALT 2
#define BHYVE_EXIT_TRIPLEFAULT 3
#define BHYVE_EXIT_ERROR 4
#define BHYVE_EXIT_SUSPEND 5
extern int guest_ncpus;
extern uint16_t cpu_cores, cpu_sockets, cpu_threads;
+1 -1
View File
@@ -1105,7 +1105,7 @@ gdb_cpu_breakpoint(struct vcpu *vcpu, struct vm_exit *vmexit)
if (!gdb_active) {
EPRINTLN("vm_loop: unexpected VMEXIT_DEBUG");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
vcpuid = vcpu_id(vcpu);
pthread_mutex_lock(&gdb_lock);
+2 -1
View File
@@ -55,6 +55,7 @@
#include <pthread.h>
#include <pthread_np.h>
#include "bhyverun.h"
#include "mevent.h"
#define MEVENT_MAX 64
@@ -517,7 +518,7 @@ mevent_dispatch(void)
ret = pipe(mevent_pipefd);
if (ret < 0) {
perror("pipe");
exit(0);
exit(BHYVE_EXIT_ERROR);
}
#ifndef WITHOUT_CAPSICUM
+5 -4
View File
@@ -45,6 +45,7 @@
#include <pthread.h>
#include <unistd.h>
#include "bhyverun.h"
#include "mevent.h"
#define TEST_PORT 4321
@@ -139,7 +140,7 @@ echoer(void *param)
mev = mevent_add(fd, EVF_READ, echoer_callback, &sync);
if (mev == NULL) {
printf("Could not allocate echoer event\n");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
while (!pthread_cond_wait(&sync.e_cond, &sync.e_mt)) {
@@ -197,7 +198,7 @@ acceptor(void *param)
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("cannot create socket");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
sin.sin_len = sizeof(sin);
@@ -207,12 +208,12 @@ acceptor(void *param)
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("cannot bind socket");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
if (listen(s, 1) < 0) {
perror("cannot listen socket");
exit(4);
exit(BHYVE_EXIT_ERROR);
}
(void) mevent_add(s, EVF_READ, acceptor_callback, NULL);
+1 -1
View File
@@ -159,7 +159,7 @@ bhyve_optparse(int argc, char **argv)
pci_print_supported_devices();
exit(0);
} else if (pci_parse_slot(optarg) != 0)
exit(4);
exit(BHYVE_EXIT_ERROR);
else
break;
case 'S':
+4 -4
View File
@@ -114,15 +114,15 @@ vmexit_suspend(struct vmctx *ctx, struct vcpu *vcpu, struct vm_run *vmrun)
switch (how) {
case VM_SUSPEND_RESET:
exit(0);
exit(BHYVE_EXIT_RESET);
case VM_SUSPEND_POWEROFF:
if (get_config_bool_default("destroy_on_poweroff", false))
vm_destroy(ctx);
exit(1);
exit(BHYVE_EXIT_POWEROFF);
case VM_SUSPEND_HALT:
exit(2);
exit(BHYVE_EXIT_HALT);
case VM_SUSPEND_DESTROY:
exit(4);
exit(BHYVE_EXIT_ERROR);
default:
fprintf(stderr, "vmexit_suspend: invalid reason %d\n", how);
exit(100);
+1 -1
View File
@@ -1308,7 +1308,7 @@ vm_checkpoint(struct vmctx *ctx, int fddir, const char *checkpoint_file,
if (stop_vm) {
vm_destroy(ctx);
exit(5);
exit(BHYVE_EXIT_SUSPEND);
}
done: