* Fix logic handling stopping a VM. Prevents VMD from crashing. * Add additional error code to notify the user that a vm cannot be stopped when not running. * Add additional log_debug statements.
diff --git usr.sbin/vmctl/vmctl.c usr.sbin/vmctl/vmctl.c index 64d82ca847d..5fb7fbfd74c 100644 --- usr.sbin/vmctl/vmctl.c +++ usr.sbin/vmctl/vmctl.c @@ -439,12 +439,19 @@ terminate_vm_complete(struct imsg *imsg, int *ret) vmr = (struct vmop_result *)imsg->data; res = vmr->vmr_result; if (res) { - errno = res; - if (res == ENOENT) - warnx("vm not found"); - else - warn("terminate vm command failed"); - *ret = EIO; + switch (res) { + case VMD_VM_STOP_INVALID: + warnx("cannot stop vm that is not running"); + *ret = EINVAL; + break; + case ENOENT: + warnx("vm not found"); + *ret = EIO; + break; + default: + warn("terminate vm command failed"); + *ret = EIO; + } } else { warnx("sent request to terminate vm %d", vmr->vmr_id); *ret = 0; @@ -453,6 +460,7 @@ terminate_vm_complete(struct imsg *imsg, int *ret) warnx("unexpected response received from vmd"); *ret = EINVAL; } + errno = *ret; return (1); } diff --git usr.sbin/vmd/vmd.h usr.sbin/vmd/vmd.h index 22da6d58a7b..1240339db52 100644 --- usr.sbin/vmd/vmd.h +++ usr.sbin/vmd/vmd.h @@ -54,6 +54,7 @@ #define VMD_BIOS_MISSING 1001 #define VMD_DISK_MISSING 1002 #define VMD_DISK_INVALID 1003 +#define VMD_VM_STOP_INVALID 1004 /* 100.64.0.0/10 from rfc6598 (IPv4 Prefix for Shared Address Space) */ #define VMD_DHCP_PREFIX "100.64.0.0/10" diff --git usr.sbin/vmd/vmm.c usr.sbin/vmd/vmm.c index d3233147cff..66083a5f959 100644 --- usr.sbin/vmd/vmm.c +++ usr.sbin/vmd/vmm.c @@ -169,10 +169,9 @@ vmm_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) else res = 0; } else { - /* Terminate VMs that are unknown or shutting down */ - vtp.vtp_vm_id = vm_vmid2id(vm->vm_vmid, vm); - res = terminate_vm(&vtp); - vm_remove(vm); + log_debug("%s: cannot stop vm that is not running", + __func__); + res = VMD_VM_STOP_INVALID; } cmd = IMSG_VMDOP_TERMINATE_VM_RESPONSE; break; @@ -346,6 +345,8 @@ vmm_sighdlr(int sig, short event, void *arg) vmid = vm->vm_params.vmc_params.vcp_id; vtp.vtp_vm_id = vmid; + log_debug("%s: attempting to terminate vm %d", + __func__, vm->vm_vmid); if (terminate_vm(&vtp) == 0) { memset(&vmr, 0, sizeof(vmr)); vmr.vmr_result = ret; @@ -505,7 +506,7 @@ vmm_dispatch_vm(int fd, short event, void *arg) * supplied vm_terminate_params structure (vtp->vtp_vm_id) * * Parameters - * vtp: vm_create_params struct containing the ID of the VM to terminate + * vtp: vm_terminate_params struct containing the ID of the VM to terminate * * Return values: * 0: success @@ -515,6 +516,7 @@ vmm_dispatch_vm(int fd, short event, void *arg) int terminate_vm(struct vm_terminate_params *vtp) { + log_debug("%s: terminating vmid %d", __func__, vtp->vtp_vm_id); if (ioctl(env->vmd_fd, VMM_IOC_TERM, vtp) < 0) return (errno); -- 2.14.1