Skip to content

Close the tap device fd explicitly instead of relying on O_CLOEXEC #830

Description

@Anamika1608

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

  1. Modify urunc to spawn the monitor as a child process instead of exec-ing into it, keeping the urunc process alive.
  2. Run a Firecracker container with a network interface, letting the monitor attach to the tap device urunc created.
  3. The attach fails with "Resource busy" (EBUSY), because urunc still holds the fd from netlink.LinkAdd.

Metadata

Metadata

Assignees

Labels

CoreRelated to urunc's internalsNetworkenhancementNew feature or request

Type

Fields

No fields configured for Task.

Projects

Status
No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions