Skip to content

Emulated Netlink sockets cause infinite busy loops under event-loop pollers (e.g., avahi-daemon) #105

@doanbaotrung

Description

@doanbaotrung

Problem Description

On macOS hosts, elfuse emulates Linux netlink route sockets (AF_NETLINK, NETLINK_ROUTE) using a host pipe.

Currently, the write end of this pipe (pipefd[1]) is closed immediately at socket creation in netlink_socket(). This makes the read end of the pipe (pipefd[0]) permanently readable, returning EOF (0 bytes) when read.

When guest applications (such as avahi-daemon) run event loops that wait for netlink messages using ppoll() or select(), the emulated descriptor immediately returns POLLIN because the write end is closed. The application's subsequent recvmsg or read call returns 0 bytes. Because no sender credentials can be resolved from a 0-byte read, the application ignores the read and immediately queries ppoll() again. This causes the guest application to spin in an infinite busy-loop consuming 100% CPU.

Proposed Fix

Implement a non-blocking self-pipe signaling mechanism inside src/syscall/netlink.c:

  1. Retain the write descriptor: Keep the write descriptor of the pipe (pipe_wr) open in the netlink socket state (netlink_state_t) instead of closing it at socket creation. Ensure it is closed during netlink_close() to prevent file descriptor leaks.
  2. Signal readability: Write a dummy byte to pipe_wr when populating synthetic responses in the netlink buffer.
  3. Clear readability: Read the dummy byte back from the host descriptor once the guest has fully drained the buffer.
  4. Return -EAGAIN: Change netlink_recvmsg and netlink_read to return -EAGAIN (instead of 0) when the buffer is empty, indicating standard non-blocking socket behavior.

Location: src/syscall/netlink.c.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions