diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2016-12-14 06:59:13 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2016-12-14 06:59:13 +0000 |
commit | f36838ee92524efe7682361388be3d6802392210 (patch) | |
tree | 37ece3aec692312b8e1f576ee5a15f7d8feb4d68 /usr.sbin/vmd/vmd.c | |
parent | 289324f1e12ade78d6ad882848c687c91268a838 (diff) |
If a VM terminates with the result EAGAIN, close all fds except the
pty and re-send it to the vmm monitor process. With additional
changes in vmm.c, this will allow perform a cold reboot of VM.
With testing and feedback from Jon Bernard
OK mlarkin@
Diffstat (limited to 'usr.sbin/vmd/vmd.c')
-rw-r--r-- | usr.sbin/vmd/vmd.c | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c index 44fe0ddae37..d572784bb05 100644 --- a/usr.sbin/vmd/vmd.c +++ b/usr.sbin/vmd/vmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.c,v 1.45 2016/11/26 20:03:42 reyk Exp $ */ +/* $OpenBSD: vmd.c,v 1.46 2016/12/14 06:59:12 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> @@ -203,17 +203,29 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg) vcp->vcp_name, vcp->vcp_id, vm->vm_ttyname); break; case IMSG_VMDOP_TERMINATE_VM_RESPONSE: - case IMSG_VMDOP_TERMINATE_VM_EVENT: IMSG_SIZE_CHECK(imsg, &vmr); memcpy(&vmr, imsg->data, sizeof(vmr)); - if (imsg->hdr.type == IMSG_VMDOP_TERMINATE_VM_RESPONSE) - proc_forward_imsg(ps, imsg, PROC_CONTROL, -1); + proc_forward_imsg(ps, imsg, PROC_CONTROL, -1); if (vmr.vmr_result == 0) { /* Remove local reference */ vm = vm_getbyid(vmr.vmr_id); vm_remove(vm); } break; + case IMSG_VMDOP_TERMINATE_VM_EVENT: + IMSG_SIZE_CHECK(imsg, &vmr); + memcpy(&vmr, imsg->data, sizeof(vmr)); + if ((vm = vm_getbyid(vmr.vmr_id)) == NULL) + break; + if (vmr.vmr_result == 0) { + /* Remove local reference */ + vm_remove(vm); + } else if (vmr.vmr_result == EAGAIN) { + /* Stop VM instance but keep the tty open */ + vm_stop(vm, 1); + config_setvm(ps, vm, (uint32_t)-1); + } + break; case IMSG_VMDOP_GET_INFO_VM_DATA: IMSG_SIZE_CHECK(imsg, &vir); memcpy(&vir, imsg->data, sizeof(vir)); @@ -615,32 +627,57 @@ vm_getbypid(pid_t pid) } void -vm_remove(struct vmd_vm *vm) +vm_stop(struct vmd_vm *vm, int keeptty) { unsigned int i; if (vm == NULL) return; - TAILQ_REMOVE(env->vmd_vms, vm, vm_entry); + vm->vm_running = 0; for (i = 0; i < VMM_MAX_DISKS_PER_VM; i++) { - if (vm->vm_disks[i] != -1) + if (vm->vm_disks[i] != -1) { close(vm->vm_disks[i]); + vm->vm_disks[i] = -1; + } } for (i = 0; i < VMM_MAX_NICS_PER_VM; i++) { - if (vm->vm_ifs[i].vif_fd != -1) + if (vm->vm_ifs[i].vif_fd != -1) { close(vm->vm_ifs[i].vif_fd); + vm->vm_ifs[i].vif_fd = -1; + } free(vm->vm_ifs[i].vif_name); free(vm->vm_ifs[i].vif_switch); free(vm->vm_ifs[i].vif_group); + vm->vm_ifs[i].vif_name = NULL; + vm->vm_ifs[i].vif_switch = NULL; + vm->vm_ifs[i].vif_group = NULL; } - if (vm->vm_kernel != -1) + if (vm->vm_kernel != -1) { close(vm->vm_kernel); - if (vm->vm_tty != -1) - close(vm->vm_tty); + vm->vm_kernel = -1; + } + + if (keeptty) + return; + if (vm->vm_tty != -1) { + close(vm->vm_tty); + vm->vm_tty = -1; + } free(vm->vm_ttyname); + vm->vm_ttyname = NULL; +} + +void +vm_remove(struct vmd_vm *vm) +{ + if (vm == NULL) + return; + + TAILQ_REMOVE(env->vmd_vms, vm, vm_entry); + vm_stop(vm, 0); free(vm); } |