Skip to content

mount.erofs: /sys/block/nbdX/pid exposes a root-namespace PID on WSL, causing false -EBUSY in the NBD backend #46

@SToPire

Description

@SToPire

Note: This issue was investigated and narrowed down with the help of GPT-5.4.

Summary

On WSL2, mount.erofs -t erofs.nbd ... can fail with -EBUSY even though the NBD device was connected successfully.

The current code assumes that /sys/block/nbdX/pid must be equal to the PID of the child process created by fork(). On WSL2, this assumption does not hold.

What we found

  • The failure happens on both the netlink path and the ioctl fallback path.
  • In both cases, /sys/block/nbdX/size becomes nonzero, which shows that the NBD device is already in service.
  • However, /sys/block/nbdX/pid does not match the userspace child PID.
  • The PID read from sysfs is also not visible as a live process or thread from normal userspace tools inside the distro.

Why this happens

In the NBD driver, /sys/block/nbdX/pid comes from:

nbd->pid = task_pid_nr(current);

Both netlink and ioctl paths eventually reach this same assignment.

On WSL2, kernel-side PID values and userspace-visible PID values differ for WSL uses different PID namespaces for each distros [1, 2]. For mount.erofs, /sys/block/nbdX/pid matches the kernel-side PID, not the userspace-visible PID.

Actions?

I am wondering if we could just remove the strict check that requires /sys/block/nbdX/pid to equal the forked child PID?

As long as we ensure that the NBD device is ready (via /sys/block/nbdX/size) and that our NBD daemon process is still alive, I do not think there is any risk of PID reuse.

[1] microsoft/WSL#12115
[2] microsoft/WSL#12408

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions