diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2017-03-15 19:54:53 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2017-03-15 19:54:53 +0000 |
commit | 5a86bb8ee1f8f27891c208b9e5b561e0c4ebe1de (patch) | |
tree | acb9e32906a808fa75a60ddea0cb7e1e9434afe8 /usr.sbin/vmd/vmd.c | |
parent | 974f439890b16f213d8a0db6ceaa4ddee96110f0 (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.c | 25 |
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); |