Solène Rapenne <[email protected]> writes:
> On Fri, 2023-06-09 at 11:25 -0400, Dave Voutila wrote:
>>
>> Thanks. This feels like bad fd accounting during the fork/exec dance.
>>
>> Sounds like the switch definition and usage isn't required for
>> reproducing?
>
> indeed, you don't need it, a local interface is enough
Can you try this diff? I think I found the issue. In short, a file
descriptor for one of the devices was being closed, that descriptor was
recycled when creating a socketpair, and then being closed again because
of the loop over ther other device fds.
Nice part about this possible fix is it's a net-negative diff.
Sorry it took a month+ to find time to look a this.
diff refs/heads/master refs/heads/vmd-qcow
commit - 4d951e9375c9e68d1aed559bb61502fa0cca5b7a
commit + 72c6b89f61e48347d7c68dfa0cfa2d2b621ecb68
blob - 6167a7764cb2d6e05233260679f3146b095bc768
blob + e8f5a1b162a41dc9d40cd665e0cc5ea22bc44e61
--- usr.sbin/vmd/virtio.c
+++ usr.sbin/vmd/virtio.c
@@ -1349,17 +1349,6 @@ virtio_dev_launch(struct vmd_vm *vm, struct virtio_dev
goto err;
}
- /* Keep data file descriptors open after exec. */
- for (i = 0; i < data_fds_sz; i++) {
- log_debug("%s: marking fd %d !close-on-exec", __func__,
- data_fds[i]);
- if (fcntl(data_fds[i], F_SETFD, 0)) {
- ret = errno;
- log_warn("%s: fcntl", __func__);
- goto err;
- }
- }
-
/* Fork... */
dev_pid = fork();
if (dev_pid == -1) {
@@ -1459,26 +1448,14 @@ virtio_dev_launch(struct vmd_vm *vm, struct virtio_dev
close_fd(async_fds[0]);
close_fd(sync_fds[0]);
- /*
- * Close any other device fd's we know aren't
- * ours. This releases any exclusive locks held on
- * things like disk images.
- */
- SLIST_FOREACH(d, &virtio_devs, dev_next) {
- if (d == dev)
- continue;
-
- switch (d->dev_type) {
- case VMD_DEVTYPE_DISK:
- for (j = 0; j < d->vioblk.ndisk_fd; j++)
- close_fd(d->vioblk.disk_fd[j]);
- break;
- case VMD_DEVTYPE_NET:
- close_fd(d->vionet.data_fd);
- break;
- default:
- fatalx("%s: invalid device type '%c'",
- __func__, d->dev_type);
+ /* Keep data file descriptors open after exec. */
+ for (i = 0; i < data_fds_sz; i++) {
+ log_debug("%s: marking fd %d !close-on-exec", __func__,
+ data_fds[i]);
+ if (fcntl(data_fds[i], F_SETFD, 0)) {
+ ret = errno;
+ log_warn("%s: fcntl", __func__);
+ goto err;
}
}