summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Voutila <dv@cvs.openbsd.org>2023-01-22 22:18:41 +0000
committerDave Voutila <dv@cvs.openbsd.org>2023-01-22 22:18:41 +0000
commit39a1f356e875f8fc826664a85bb51619f70a0a9d (patch)
tree4069c02f2f91064d6b1378c53a0717aa145a9054
parent1cacd5bf8159cefeace97012cd3084c4e9308aa9 (diff)
vmd(8): don't remove known vm's from the config on error.
Multiple error paths, specifically the one related to if a guest cannot allocate memory at start, resulted in a known vm (via vm.conf(5)) being removed from the vm list. Adjust the error paths to check if the failing vm is defined in the config before tearing it down. Tested with help from beck@ and Mischa Peters. ok beck@
-rw-r--r--usr.sbin/vmd/vmd.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index 0557a3101c9..8d8d2558c5c 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.c,v 1.136 2023/01/14 20:55:55 dv Exp $ */
+/* $OpenBSD: vmd.c,v 1.137 2023/01/22 22:18:40 dv Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -67,6 +67,8 @@ int vm_checkinsflag(struct vmop_create_params *, unsigned int, uid_t);
int vm_claimid(const char *, int, uint32_t *);
void start_vm_batch(int, short, void*);
+static inline void vm_terminate(struct vmd_vm *, const char *);
+
struct vmd *env;
static struct privsep_proc procs[] = {
@@ -395,14 +397,14 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
errno = vmr.vmr_result;
log_warn("%s: failed to forward vm result",
vcp->vcp_name);
- vm_remove(vm, __func__);
+ vm_terminate(vm, __func__);
return (-1);
}
}
if (vmr.vmr_result) {
log_warnx("%s: failed to start vm", vcp->vcp_name);
- vm_remove(vm, __func__);
+ vm_terminate(vm, __func__);
errno = vmr.vmr_result;
break;
}
@@ -410,7 +412,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
/* Now configure all the interfaces */
if (vm_priv_ifconfig(ps, vm) == -1) {
log_warn("%s: failed to configure vm", vcp->vcp_name);
- vm_remove(vm, __func__);
+ vm_terminate(vm, __func__);
break;
}
@@ -441,10 +443,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
log_info("%s: sent vm %d successfully.",
vm->vm_params.vmc_params.vcp_name,
vm->vm_vmid);
- if (vm->vm_from_config)
- vm_stop(vm, 0, __func__);
- else
- vm_remove(vm, __func__);
+ vm_terminate(vm, __func__);
}
/* Send a response if a control client is waiting for it */
@@ -470,10 +469,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
}
if (vmr.vmr_result != EAGAIN ||
vm->vm_params.vmc_bootdevice) {
- if (vm->vm_from_config)
- vm_stop(vm, 0, __func__);
- else
- vm_remove(vm, __func__);
+ vm_terminate(vm, __func__);
} else {
/* Stop VM instance but keep the tty open */
vm_stop(vm, 1, __func__);
@@ -509,7 +505,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
imsg->hdr.peerid, -1, &vir, sizeof(vir)) == -1) {
log_debug("%s: GET_INFO_VM failed for vm %d, removing",
__func__, vm->vm_vmid);
- vm_remove(vm, __func__);
+ vm_terminate(vm, __func__);
return (-1);
}
break;
@@ -545,7 +541,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
sizeof(vir)) == -1) {
log_debug("%s: GET_INFO_VM_END failed",
__func__);
- vm_remove(vm, __func__);
+ vm_terminate(vm, __func__);
return (-1);
}
}
@@ -1947,3 +1943,15 @@ getmonotime(struct timeval *tv)
TIMESPEC_TO_TIMEVAL(tv, &ts);
}
+
+static inline void
+vm_terminate(struct vmd_vm *vm, const char *caller)
+{
+ if (vm->vm_from_config)
+ vm_stop(vm, 0, caller);
+ else {
+ /* vm_remove calls vm_stop */
+ vm_remove(vm, caller);
+ }
+}
+