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