diff options
Diffstat (limited to 'usr.sbin/vmd')
-rw-r--r-- | usr.sbin/vmd/config.c | 3 | ||||
-rw-r--r-- | usr.sbin/vmd/control.c | 4 | ||||
-rw-r--r-- | usr.sbin/vmd/vmd.c | 29 | ||||
-rw-r--r-- | usr.sbin/vmd/vmd.h | 6 | ||||
-rw-r--r-- | usr.sbin/vmd/vmm.c | 28 |
5 files changed, 45 insertions, 25 deletions
diff --git a/usr.sbin/vmd/config.c b/usr.sbin/vmd/config.c index fab9af708d4..fc8114a9e5e 100644 --- a/usr.sbin/vmd/config.c +++ b/usr.sbin/vmd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.45 2018/07/10 16:15:51 reyk Exp $ */ +/* $OpenBSD: config.c,v 1.46 2018/07/11 13:19:47 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> @@ -451,6 +451,7 @@ config_getvm(struct privsep *ps, struct imsg *imsg) /* If the fd is -1, the kernel will be searched on the disk */ vm->vm_kernel = imsg->fd; vm->vm_running = 1; + vm->vm_peerid = (uint32_t)-1; return (0); diff --git a/usr.sbin/vmd/control.c b/usr.sbin/vmd/control.c index 37cc538ccb3..1162c0c207d 100644 --- a/usr.sbin/vmd/control.c +++ b/usr.sbin/vmd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.26 2018/07/11 09:35:44 reyk Exp $ */ +/* $OpenBSD: control.c,v 1.27 2018/07/11 13:19:47 reyk Exp $ */ /* * Copyright (c) 2010-2015 Reyk Floeter <reyk@openbsd.org> @@ -352,7 +352,6 @@ control_dispatch_imsg(int fd, short event, void *arg) switch (imsg.hdr.type) { case IMSG_VMDOP_GET_INFO_VM_REQUEST: case IMSG_VMDOP_TERMINATE_VM_REQUEST: - case IMSG_VMDOP_KILL_VM_REQUEST: case IMSG_VMDOP_START_VM_REQUEST: case IMSG_VMDOP_PAUSE_VM: case IMSG_VMDOP_UNPAUSE_VM: @@ -411,7 +410,6 @@ control_dispatch_imsg(int fd, short event, void *arg) } break; case IMSG_VMDOP_TERMINATE_VM_REQUEST: - case IMSG_VMDOP_KILL_VM_REQUEST: if (IMSG_DATA_SIZE(&imsg) < sizeof(vid)) goto fail; memcpy(&vid, imsg.data, sizeof(vid)); diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c index d4f4e2e71f3..ac67bfd1169 100644 --- a/usr.sbin/vmd/vmd.c +++ b/usr.sbin/vmd/vmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.c,v 1.92 2018/07/11 10:31:45 reyk Exp $ */ +/* $OpenBSD: vmd.c,v 1.93 2018/07/11 13:19:47 reyk Exp $ */ /* * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org> @@ -76,10 +76,9 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) { struct privsep *ps = p->p_ps; int res = 0, ret = 0, cmd = 0, verbose; - unsigned int v = 0; + unsigned int v = 0, flags; struct vmop_create_params vmc; struct vmop_id vid; - struct vm_terminate_params vtp; struct vmop_result vmr; struct vm_dump_header vmh; struct vmd_vm *vm = NULL; @@ -111,9 +110,10 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) } break; case IMSG_VMDOP_TERMINATE_VM_REQUEST: - case IMSG_VMDOP_KILL_VM_REQUEST: IMSG_SIZE_CHECK(imsg, &vid); memcpy(&vid, imsg->data, sizeof(vid)); + flags = vid.vid_flags; + if ((id = vid.vid_id) == 0) { /* Lookup vm (id) by name */ if ((vm = vm_getbyname(vid.vid_name)) == NULL) { @@ -121,7 +121,7 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) cmd = IMSG_VMDOP_TERMINATE_VM_RESPONSE; break; } else if (vm->vm_shutdown && - imsg->hdr.type != IMSG_VMDOP_KILL_VM_REQUEST) { + (flags & VMOP_FORCE) == 0) { res = EALREADY; cmd = IMSG_VMDOP_TERMINATE_VM_RESPONSE; break; @@ -141,10 +141,12 @@ vmd_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) cmd = IMSG_VMDOP_TERMINATE_VM_RESPONSE; break; } - memset(&vtp, 0, sizeof(vtp)); - vtp.vtp_vm_id = id; + + memset(&vid, 0, sizeof(vid)); + vid.vid_id = id; + vid.vid_flags = flags; if (proc_compose_imsg(ps, PROC_VMM, -1, imsg->hdr.type, - imsg->hdr.peerid, -1, &vtp, sizeof(vtp)) == -1) + imsg->hdr.peerid, -1, &vid, sizeof(vid)) == -1) return (-1); break; case IMSG_VMDOP_GET_INFO_VM_REQUEST: @@ -432,6 +434,17 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg) vm_stop(vm, 1, __func__); config_setvm(ps, vm, (uint32_t)-1, vm->vm_uid); } + + /* Send a response if a control client is waiting for it */ + if (imsg->hdr.peerid != (uint32_t)-1) { + /* the error is meaningless for deferred responses */ + vmr.vmr_result = 0; + + if (proc_compose_imsg(ps, PROC_CONTROL, -1, + IMSG_VMDOP_TERMINATE_VM_RESPONSE, + imsg->hdr.peerid, -1, &vmr, sizeof(vmr)) == -1) + return (-1); + } break; case IMSG_VMDOP_GET_INFO_VM_DATA: IMSG_SIZE_CHECK(imsg, &vir); diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h index 8b1b7a5f058..c25f9642147 100644 --- a/usr.sbin/vmd/vmd.h +++ b/usr.sbin/vmd/vmd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.h,v 1.73 2018/07/11 09:35:44 reyk Exp $ */ +/* $OpenBSD: vmd.h,v 1.74 2018/07/11 13:19:47 reyk Exp $ */ /* * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org> @@ -82,7 +82,6 @@ enum imsg_type { IMSG_VMDOP_RECEIVE_VM_RESPONSE, IMSG_VMDOP_RECEIVE_VM_END, IMSG_VMDOP_TERMINATE_VM_REQUEST, - IMSG_VMDOP_KILL_VM_REQUEST, IMSG_VMDOP_TERMINATE_VM_RESPONSE, IMSG_VMDOP_TERMINATE_VM_EVENT, IMSG_VMDOP_GET_INFO_VM_REQUEST, @@ -122,6 +121,9 @@ struct vmop_id { uint32_t vid_id; char vid_name[VMM_MAX_NAME_LEN]; uid_t vid_uid; + unsigned int vid_flags; +#define VMOP_FORCE 0x01 +#define VMOP_WAIT 0x02 }; struct vmop_ifreq { diff --git a/usr.sbin/vmd/vmm.c b/usr.sbin/vmd/vmm.c index cd721de8989..9beed72df96 100644 --- a/usr.sbin/vmd/vmm.c +++ b/usr.sbin/vmd/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.85 2018/07/11 09:35:44 reyk Exp $ */ +/* $OpenBSD: vmm.c,v 1.86 2018/07/11 13:19:47 reyk Exp $ */ /* * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org> @@ -111,7 +111,7 @@ vmm_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) struct vmop_create_params vmc; uint32_t id = 0; pid_t pid = 0; - unsigned int mode; + unsigned int mode, flags; switch (imsg->hdr.type) { case IMSG_VMDOP_START_VM_REQUEST: @@ -150,17 +150,19 @@ vmm_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) cmd = IMSG_VMDOP_START_VM_RESPONSE; break; case IMSG_VMDOP_TERMINATE_VM_REQUEST: - case IMSG_VMDOP_KILL_VM_REQUEST: - IMSG_SIZE_CHECK(imsg, &vtp); - memcpy(&vtp, imsg->data, sizeof(vtp)); - id = vtp.vtp_vm_id; + IMSG_SIZE_CHECK(imsg, &vid); + memcpy(&vid, imsg->data, sizeof(vid)); + id = vid.vid_id; + flags = vid.vid_flags; DPRINTF("%s: recv'ed TERMINATE_VM for %d", __func__, id); + cmd = IMSG_VMDOP_TERMINATE_VM_RESPONSE; + if (id == 0) { res = ENOENT; } else if ((vm = vm_getbyvmid(id)) != NULL) { - if (imsg->hdr.type == IMSG_VMDOP_KILL_VM_REQUEST) { + if (flags & VMOP_FORCE) { vtp.vtp_vm_id = vm_vmid2id(vm->vm_vmid, vm); vm->vm_shutdown = 1; (void)terminate_vm(&vtp); @@ -189,20 +191,23 @@ vmm_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) * Check to see if the VM process is still * active. If not, return VMD_VM_STOP_INVALID. */ - vtp.vtp_vm_id = vm_vmid2id(vm->vm_vmid, vm); - if (vtp.vtp_vm_id == 0) { + if (vm_vmid2id(vm->vm_vmid, vm) == 0) { log_debug("%s: no vm running anymore", __func__); res = VMD_VM_STOP_INVALID; } } + if ((flags & VMOP_WAIT) && + res == 0 && vm->vm_shutdown == 1) { + vm->vm_peerid = imsg->hdr.peerid; + cmd = 0; + } } else { /* vm doesn't exist, cannot stop vm */ log_debug("%s: cannot stop vm that is not running", __func__); res = VMD_VM_STOP_INVALID; } - cmd = IMSG_VMDOP_TERMINATE_VM_RESPONSE; break; case IMSG_VMDOP_GET_INFO_VM_REQUEST: res = get_info_vm(ps, imsg, 0); @@ -387,7 +392,8 @@ vmm_sighdlr(int sig, short event, void *arg) vmr.vmr_id = vm_id2vmid(vmid, vm); if (proc_compose_imsg(ps, PROC_PARENT, -1, IMSG_VMDOP_TERMINATE_VM_EVENT, - 0, -1, &vmr, sizeof(vmr)) == -1) + vm->vm_peerid, -1, + &vmr, sizeof(vmr)) == -1) log_warnx("could not signal " "termination of VM %u to " "parent", vm->vm_vmid); |