During h2k22 there was some discussion around how vmd(8) manages vms and
the vmm(4) device's role. While looking into something related, I found
vmd opens /dev/vmm in each subprocess during the initial fork+execve
dance.

The only vmd process that needs /dev/vmm is the vmm process.

The diff below changes it so that *only* the parent process opens
/dev/vmm and then uses fd passing to send it to the vmm process once
fork+exec'd. This adds a new imsg type specific to this handoff.

The other processes don't end up with the vmm pledge, so there's no
reason they need open file descriptors to the vmm device.

OK?


diff refs/heads/master refs/heads/vmd-vmm-open
commit - adc9c11636d08981539860c611938338c714d31e
commit + 1bb17c1c2d6cd28c231fa2eb6f8494e5498bb1a3
blob - bd0d8580ffc25d905e5f20c1de5044397ddf313d
blob + 41e4b7b5852c7523a7b1c0e3a73591638a9c9e56
--- usr.sbin/vmd/vmd.c
+++ usr.sbin/vmd/vmd.c
@@ -847,8 +847,8 @@ main(int argc, char **argv)
        proc_priv->p_pw = &proc_privpw; /* initialized to all 0 */
        proc_priv->p_chroot = ps->ps_pw->pw_dir; /* from VMD_USER */

-       /* Open /dev/vmm */
-       if (env->vmd_noaction == 0) {
+       /* Open /dev/vmm early. */
+       if (env->vmd_noaction == 0 && proc_id == PROC_PARENT) {
                env->vmd_fd = open(VMM_NODE, O_RDWR);
                if (env->vmd_fd == -1)
                        fatal("%s", VMM_NODE);
@@ -971,6 +971,10 @@ vmd_configure(void)
                exit(0);
        }

+       /* Send VMM device fd to vmm proc. */
+       proc_compose_imsg(&env->vmd_ps, PROC_VMM, -1,
+           IMSG_VMDOP_RECEIVE_VMM_FD, -1, env->vmd_fd, NULL, 0);
+
        /* Send shared global configuration to all children */
        if (config_setconfig(env) == -1)
                return (-1);
blob - c27d03df7336a2c8ede22ec0d83b74d327fb3244
blob + 2ca4aa336bf68b0d8bf8183e92c9d0ef99d5411e
--- usr.sbin/vmd/vmd.h
+++ usr.sbin/vmd/vmd.h
@@ -108,6 +108,7 @@ enum imsg_type {
        IMSG_VMDOP_GET_INFO_VM_DATA,
        IMSG_VMDOP_GET_INFO_VM_END_DATA,
        IMSG_VMDOP_LOAD,
+       IMSG_VMDOP_RECEIVE_VMM_FD,
        IMSG_VMDOP_RELOAD,
        IMSG_VMDOP_PRIV_IFDESCR,
        IMSG_VMDOP_PRIV_IFADD,
blob - 6c2bdbd12a3ee11aa88055200e11e0f2a0ff667f
blob + 2f82a241c1c1672770529ef98f9b748714512704
--- usr.sbin/vmd/vmm.c
+++ usr.sbin/vmd/vmm.c
@@ -94,9 +94,6 @@ vmm_run(struct privsep *ps, struct privsep_proc *p, vo
         */
        if (pledge("stdio vmm sendfd recvfd proc", NULL) == -1)
                fatal("pledge");
-
-       /* Get and terminate all running VMs */
-       get_info_vm(ps, NULL, 1);
 }

 int
@@ -315,6 +312,14 @@ vmm_dispatch_parent(int fd, struct privsep_proc *p, st
                    imsg->hdr.type, imsg->hdr.peerid, imsg->hdr.pid,
                    imsg->fd, &var, sizeof(var));
                break;
+       case IMSG_VMDOP_RECEIVE_VMM_FD:
+               if (env->vmd_fd > -1)
+                       fatalx("already received vmm fd");
+               env->vmd_fd = imsg->fd;
+
+               /* Get and terminate all running VMs */
+               get_info_vm(ps, NULL, 1);
+               break;
        default:
                return (-1);
        }

Reply via email to