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);
 }
-

Reply via email to