On Fri, Feb 09, 2024 at 10:02:29AM -0500, Dave Voutila wrote:
> Try this diff. There was an issue in the order of closing disk fds. I
> also noticed we're not closing the sockets when closing the data fds, so
> that's added into virtio_dev_closefds().
> 
> With this i can boot a guest that uses a network interface and a qcow2
> disk image with a base image.

This fixes my reproducer and real vm.conf with a derived .qcow2 image.
Good catch, I forgot to mention that.

> diff refs/heads/master refs/heads/vmd-fd-fix
> commit - 06bc238730aac28903aeab0d96b2427760b0110a
> commit + 8e46c12aa617cf136fdb3557f0177d41adb4d9d9
> blob - afe3dd8f7a48cde226a4438567a8a3eb9dac2dce
> blob + ce052097a463bed0e75775d7acb2f036ca111572
> --- usr.sbin/vmd/virtio.c
> +++ usr.sbin/vmd/virtio.c
> @@ -1301,8 +1301,8 @@ virtio_dev_launch(struct vmd_vm *vm, struct virtio_dev
>  {
>       char *nargv[12], num[32], vmm_fd[32], vm_name[VM_NAME_MAX], t[2];
>       pid_t dev_pid;
> -     int data_fds[VM_MAX_BASE_PER_DISK], sync_fds[2], async_fds[2], ret = 0;
> -     size_t i, data_fds_sz, sz = 0;
> +     int sync_fds[2], async_fds[2], ret = 0;
> +     size_t sz = 0;
>       struct viodev_msg msg;
>       struct virtio_dev *dev_entry;
>       struct imsg imsg;
> @@ -1310,14 +1310,10 @@ virtio_dev_launch(struct vmd_vm *vm, struct virtio_dev
> 
>       switch (dev->dev_type) {
>       case VMD_DEVTYPE_NET:
> -             data_fds[0] = dev->vionet.data_fd;
> -             data_fds_sz = 1;
>               log_debug("%s: launching vionet%d",
>                   vm->vm_params.vmc_params.vcp_name, dev->vionet.idx);
>               break;
>       case VMD_DEVTYPE_DISK:
> -             memcpy(&data_fds, dev->vioblk.disk_fd, sizeof(data_fds));
> -             data_fds_sz = dev->vioblk.ndisk_fd;
>               log_debug("%s: launching vioblk%d",
>                   vm->vm_params.vmc_params.vcp_name, dev->vioblk.idx);
>               break;
> @@ -1359,10 +1355,6 @@ virtio_dev_launch(struct vmd_vm *vm, struct virtio_dev
>               dev->sync_fd = sync_fds[1];
>               dev->async_fd = async_fds[1];
> 
> -             /* Close data fds. Only the child device needs them now. */
> -             for (i = 0; i < data_fds_sz; i++)
> -                     close_fd(data_fds[i]);
> -
>               /* 1. Send over our configured device. */
>               log_debug("%s: sending '%c' type device struct", __func__,
>                       dev->dev_type);
> @@ -1373,6 +1365,13 @@ virtio_dev_launch(struct vmd_vm *vm, struct virtio_dev
>                       goto err;
>               }
> 
> +             /* Close data fds. Only the child device needs them now. */
> +             if (virtio_dev_closefds(dev) == -1) {
> +                     log_warnx("%s: failed to close device data fds",
> +                         __func__);
> +                     goto err;
> +             }
> +
>               /* 2. Send over details on the VM (including memory fds). */
>               log_debug("%s: sending vm message for '%s'", __func__,
>                       vm->vm_params.vmc_params.vcp_name);
> @@ -1775,5 +1774,10 @@ virtio_dev_closefds(struct virtio_dev *dev)
>               return (-1);
>       }
> 
> +     close_fd(dev->async_fd);
> +     dev->async_fd = -1;
> +     close_fd(dev->sync_fd);
> +     dev->sync_fd = -1;
> +
>       return (0);
>  }

Reply via email to