The conclusion of my previous fixes to vmd(8) [1] changes the event handling in vmctl(8) to support receiving IMSG_VMDOP_TERMINATE_VM_EVENTs from the control process. (This removes a XXX comment from vmd.)
For clarity, the messaging logic was changed previously: - ...TERMINATE_VM_RESPONSE conveying success/failure of the request to terminate a guest regardless of waiting for termination - ...TERMINATE_VM_EVENT conveying the actual termination of a guest This diff finishes bringing that logic from vmd(8) to vmctl(8). OK? -dv Index: usr.sbin/vmd/control.c =================================================================== RCS file: /cvs/src/usr.sbin/vmd/control.c,v retrieving revision 1.35 diff -u -p -r1.35 control.c --- usr.sbin/vmd/control.c 26 Apr 2021 22:58:27 -0000 1.35 +++ usr.sbin/vmd/control.c 30 Apr 2021 12:31:22 -0000 @@ -154,9 +154,8 @@ control_dispatch_vmd(int fd, struct priv if (notify->ctl_vmid != vmr.vmr_id) continue; if ((c = control_connbyfd(notify->ctl_fd)) != NULL) { - /* XXX vmctl expects *_RESPONSE, not *_EVENT */ - imsg_compose_event(&c->iev, - IMSG_VMDOP_TERMINATE_VM_RESPONSE, + /* Forward to the vmctl(8) client */ + imsg_compose_event(&c->iev, imsg->hdr.type, 0, 0, -1, imsg->data, IMSG_DATA_SIZE(imsg)); TAILQ_REMOVE(&ctl_notify_q, notify, entry); free(notify); Index: usr.sbin/vmctl/vmctl.c =================================================================== RCS file: /cvs/src/usr.sbin/vmctl/vmctl.c,v retrieving revision 1.77 diff -u -p -r1.77 vmctl.c --- usr.sbin/vmctl/vmctl.c 22 Mar 2021 18:50:11 -0000 1.77 +++ usr.sbin/vmctl/vmctl.c 30 Apr 2021 12:31:22 -0000 @@ -461,7 +461,7 @@ terminate_vm(uint32_t terminate_id, cons * terminate_vm_complete * * Callback function invoked when we are expecting an - * IMSG_VMDOP_TERMINATE_VM_RESPONSE message indicating the completion of + * IMSG_VMDOP_TERMINATE_VM_EVENT message indicating the completion of * a terminate vm operation. * * Parameters: @@ -484,41 +484,50 @@ terminate_vm_complete(struct imsg *imsg, struct vmop_result *vmr; int res; - if (imsg->hdr.type == IMSG_VMDOP_TERMINATE_VM_RESPONSE) { + switch (imsg->hdr.type) { + case IMSG_VMDOP_TERMINATE_VM_RESPONSE: + IMSG_SIZE_CHECK(imsg, &vmr); vmr = (struct vmop_result *)imsg->data; res = vmr->vmr_result; - if (res) { - switch (res) { - case VMD_VM_STOP_INVALID: - fprintf(stderr, - "cannot stop vm that is not running\n"); - *ret = EINVAL; - break; - case ENOENT: - fprintf(stderr, "vm not found\n"); - *ret = EIO; - break; - case EINTR: - fprintf(stderr, "interrupted call\n"); - *ret = EIO; - break; - default: - errno = res; - fprintf(stderr, "failed: %s\n", - strerror(res)); - *ret = EIO; - } - } else if (flags & VMOP_WAIT) { + + switch (res) { + case 0: + fprintf(stderr, "requested to shutdown vm %d\n", + vmr->vmr_id); + *ret = 0; + break; + case VMD_VM_STOP_INVALID: + fprintf(stderr, + "cannot stop vm that is not running\n"); + *ret = EINVAL; + break; + case ENOENT: + fprintf(stderr, "vm not found\n"); + *ret = EIO; + break; + case EINTR: + fprintf(stderr, "interrupted call\n"); + *ret = EIO; + break; + default: + errno = res; + fprintf(stderr, "failed: %s\n", + strerror(res)); + *ret = EIO; + } + break; + case IMSG_VMDOP_TERMINATE_VM_EVENT: + IMSG_SIZE_CHECK(imsg, &vmr); + vmr = (struct vmop_result *)imsg->data; + if (flags & VMOP_WAIT) { fprintf(stderr, "terminated vm %d\n", vmr->vmr_id); } else if (flags & VMOP_FORCE) { fprintf(stderr, "forced to terminate vm %d\n", vmr->vmr_id); - } else { - fprintf(stderr, "requested to shutdown vm %d\n", - vmr->vmr_id); - *ret = 0; } - } else { + *ret = 0; + break; + default: fprintf(stderr, "unexpected response received from vmd\n"); *ret = EINVAL; } @@ -951,4 +960,3 @@ create_imagefile(int type, const char *i return (ret); } -