Description
createTapDevice in pkg/network/network.go does not close the file descriptor that netlink.LinkAdd opens for the tap device. The fd is opened with O_CLOEXEC, so it is eventually closed as a side effect of urunc exec-ing into the monitor (syscall.Exec) — nothing closes it explicitly.
This works in the current flow, but it ties the fd's lifetime to the exec: in any flow where the urunc process keeps running instead of exec-ing away (for example spawning the monitor as a child process, as discussed for the API-based boot in #756), the fd stays open for as long as urunc runs. Since the tap device is single-queue, the open fd blocks the monitor's own attempt to attach to the device, and Firecracker fails with:
Network config error: Could not create the network device: Open tap device failed: Error while creating ifreq structure: Resource busy (os error 16)
Closing the fd right after the owner/group ioctls is safe: the device is created with TUNSETPERSIST (the vendored vishvananda/netlink sets it whenever NonPersist is unset, which is the case here), so the interface survives independently of the fd.
Environment
- urunc main (609e07e), Ubuntu 24.04 aarch64 with KVM
- Firecracker v1.7.0
Steps to reproduce
- Modify urunc to spawn the monitor as a child process instead of exec-ing into it, keeping the urunc process alive.
- Run a Firecracker container with a network interface, letting the monitor attach to the tap device urunc created.
- The attach fails with "Resource busy" (EBUSY), because urunc still holds the fd from
netlink.LinkAdd.
Description
createTapDeviceinpkg/network/network.godoes not close the file descriptor thatnetlink.LinkAddopens for the tap device. The fd is opened withO_CLOEXEC, so it is eventually closed as a side effect of urunc exec-ing into the monitor (syscall.Exec) — nothing closes it explicitly.This works in the current flow, but it ties the fd's lifetime to the exec: in any flow where the urunc process keeps running instead of exec-ing away (for example spawning the monitor as a child process, as discussed for the API-based boot in #756), the fd stays open for as long as urunc runs. Since the tap device is single-queue, the open fd blocks the monitor's own attempt to attach to the device, and Firecracker fails with:
Closing the fd right after the owner/group ioctls is safe: the device is created with
TUNSETPERSIST(the vendoredvishvananda/netlinksets it wheneverNonPersistis unset, which is the case here), so the interface survives independently of the fd.Environment
Steps to reproduce
netlink.LinkAdd.