vmd: fix rebooting a received vm
authordv <dv@openbsd.org>
Sun, 8 May 2022 14:44:54 +0000 (14:44 +0000)
committerdv <dv@openbsd.org>
Sun, 8 May 2022 14:44:54 +0000 (14:44 +0000)
Rebooting a received vm resulted in vmd(8) exiting as a result of
flawed state tracking in the parent process.

When stopping a vm, clear the VM_RECEIVE_STATE flag. When starting
a vm, make sure the parent process collapses any existing memory
ranges after the vm is sent to the vmm process (responsible for
launching the vm).

ok mlarkin@

usr.sbin/vmd/config.c
usr.sbin/vmd/vmd.c

index 2750be4..374d7de 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: config.c,v 1.64 2021/11/10 20:49:04 sthen Exp $       */
+/*     $OpenBSD: config.c,v 1.65 2022/05/08 14:44:54 dv Exp $  */
 
 /*
  * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -231,6 +231,7 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid)
        unsigned int             unit;
        struct timeval           tv, rate, since_last;
        struct vmop_addr_req     var;
+       size_t                   bytes = 0;
 
        if (vm->vm_state & VM_STATE_RUNNING) {
                log_warnx("%s: vm is already running", __func__);
@@ -518,6 +519,14 @@ config_setvm(struct privsep *ps, struct vmd_vm *vm, uint32_t peerid, uid_t uid)
 
        free(tapfds);
 
+       /* Collapse any memranges after the vm was sent to PROC_VMM */
+       if (vcp->vcp_nmemranges > 0) {
+               for (i = 0; i < vcp->vcp_nmemranges; i++)
+                       bytes += vcp->vcp_memranges[i].vmr_size;
+               memset(&vcp->vcp_memranges, 0, sizeof(vcp->vcp_memranges));
+               vcp->vcp_nmemranges = 0;
+               vcp->vcp_memranges[0].vmr_size = bytes;
+       }
        vm->vm_state |= VM_STATE_RUNNING;
        return (0);
 
index 4d7e7b5..74b4a3f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vmd.c,v 1.130 2022/03/01 21:46:19 dv Exp $    */
+/*     $OpenBSD: vmd.c,v 1.131 2022/05/08 14:44:54 dv Exp $    */
 
 /*
  * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -1162,7 +1162,8 @@ vm_stop(struct vmd_vm *vm, int keeptty, const char *caller)
            __func__, ps->ps_title[privsep_process], caller,
            vm->vm_vmid, keeptty ? ", keeping tty open" : "");
 
-       vm->vm_state &= ~(VM_STATE_RUNNING | VM_STATE_SHUTDOWN);
+       vm->vm_state &= ~(VM_STATE_RECEIVED | VM_STATE_RUNNING
+           | VM_STATE_SHUTDOWN);
 
        user_inc(&vm->vm_params.vmc_params, vm->vm_user, 0);
        user_put(vm->vm_user);