summaryrefslogtreecommitdiff
path: root/usr.sbin/vmd/vmd.c
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2017-03-15 19:54:53 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2017-03-15 19:54:53 +0000
commit5a86bb8ee1f8f27891c208b9e5b561e0c4ebe1de (patch)
treeacb9e32906a808fa75a60ddea0cb7e1e9434afe8 /usr.sbin/vmd/vmd.c
parent974f439890b16f213d8a0db6ceaa4ddee96110f0 (diff)
More fixes for starting and stopping VMs, fixing fallout from vm_running.
- Don't start a VM that is already running - Keep the VM as running until it is powered off (and not stopping) - Don't fatal in the parent if the vmm process referenced an unknown VM - Don't stop a VM that is already stopping - Indicate that a VM is stopping in "vmctl status" The previous "vmctl stop; vmctl stop" to force-shutdown is not supported anymore - the shutdown timeout should make sure that the VM is really terminated. To force-shutdown, reference the VM by ID. We might add a flag to vmctl stop to just turn the VM off.
Diffstat (limited to 'usr.sbin/vmd/vmd.c')
-rw-r--r--usr.sbin/vmd/vmd.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index c3e1ade2bed..77731c2462f 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.c,v 1.54 2017/03/15 17:53:10 reyk Exp $ */
+/* $OpenBSD: vmd.c,v 1.55 2017/03/15 19:54:52 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -86,7 +86,8 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
ret = vm_register(ps, &vmc, &vm, 0, vmc.vmc_uid);
if (vmc.vmc_flags == 0) {
/* start an existing VM with pre-configured options */
- if (!(ret == -1 && errno == EALREADY)) {
+ if (!(ret == -1 && errno == EALREADY &&
+ vm->vm_running == 0)) {
res = errno;
cmd = IMSG_VMDOP_START_VM_RESPONSE;
}
@@ -109,6 +110,10 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
res = ENOENT;
cmd = IMSG_VMDOP_TERMINATE_VM_RESPONSE;
break;
+ } else if (vm->vm_shutdown) {
+ res = EALREADY;
+ cmd = IMSG_VMDOP_TERMINATE_VM_RESPONSE;
+ break;
}
id = vm->vm_params.vmc_params.vcp_id;
} else
@@ -189,7 +194,7 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
IMSG_SIZE_CHECK(imsg, &vmr);
memcpy(&vmr, imsg->data, sizeof(vmr));
if ((vm = vm_getbyvmid(imsg->hdr.peerid)) == NULL)
- fatalx("%s: invalid vm response", __func__);
+ break;
vm->vm_pid = vmr.vmr_pid;
vcp = &vm->vm_params.vmc_params;
vcp->vcp_id = vmr.vmr_id;
@@ -200,7 +205,6 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
* from the parent, not the control socket.
*/
if (vm->vm_peerid != (uint32_t)-1) {
- vmr.vmr_result = res;
(void)strlcpy(vmr.vmr_ttyname, vm->vm_ttyname,
sizeof(vmr.vmr_ttyname));
if (proc_compose_imsg(ps, PROC_CONTROL, -1,
@@ -238,10 +242,8 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
if ((vm = vm_getbyid(vmr.vmr_id)) == NULL)
break;
if (vmr.vmr_result == 0) {
- if (vm->vm_from_config)
- vm_stop(vm, 0);
- else
- vm_remove(vm);
+ /* Mark VM as shutting down */
+ vm->vm_shutdown = 1;
}
break;
case IMSG_VMDOP_TERMINATE_VM_EVENT:
@@ -268,6 +270,12 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
if (vm->vm_ttyname != NULL)
strlcpy(vir.vir_ttyname, vm->vm_ttyname,
sizeof(vir.vir_ttyname));
+ if (vm->vm_shutdown) {
+ /* XXX there might be a nicer way */
+ (void)strlcat(vir.vir_info.vir_name,
+ " - stopping",
+ sizeof(vir.vir_info.vir_name));
+ }
/* get the user id who started the vm */
vir.vir_uid = vm->vm_uid;
vir.vir_gid = vm->vm_params.vmc_gid;
@@ -706,6 +714,7 @@ vm_stop(struct vmd_vm *vm, int keeptty)
return;
vm->vm_running = 0;
+ vm->vm_shutdown = 0;
if (vm->vm_iev.ibuf.fd != -1) {
event_del(&vm->vm_iev.ev);