Skip to content

Name the entry that blocks a full copy - #2

Merged
RhysSullivan merged 4 commits into
upstream-0.0.13from
fix/copy-all-unsearchable-dirs
Oct 7, 2026
Merged

RhysSullivan merged 4 commits into
upstream-0.0.13from
fix/copy-all-unsearchable-dirs

Conversation

@RhysSullivan

@RhysSullivan RhysSullivan commented Oct 7, 2026 •

Copy link
Copy Markdown

Problem

rift create --copy-all failed with copy-on-write cloning unavailable: failed to clone <root>: Permission denied (os error 13) for any tree that contains a directory without the search bit, for example an empty drw-r--r-- directory. Filtered creates from the same tree succeeded. The message named the root and blamed copy-on-write support, so the real cause was hard to find. In our executor-next checkout, every --copy-all create failed this way for a while.

Cause

CopyMode::All makes one clonefile call on the root. The kernel refuses that whole call with EACCES when any file inside is unreadable or any directory inside lacks read or search permission, even when the caller owns it. The refused call leaves nothing behind. Rift also reported every clonefile error as missing copy-on-write support.

Solution

This PR diagnoses the problem. It does not work around it.

  • When the whole-tree clone fails with EACCES/EPERM, rift keeps the kernel's error and message and may add a likely cause: the first source entry the caller is denied, with a fix. That is an unreadable file, or a directory without read or search permission. node_modules directories are scanned only after the rest of the tree comes up clean. Example:

    clone failed for /tmp/x/app: Permission denied (os error 13). Found /tmp/x/app/lib, a directory without search permission, which blocks whole-tree cloning. Run `chmod u+x /tmp/x/app/lib`, or remove it if it is empty and untracked
    
  • The source is blamed only when the destination parent is writable and has no immutable or append-only flag. Otherwise the kernel's error is returned as is.

  • Only EACCES/EPERM on an entry count as a cause. Any other scan failure, such as EMFILE, EIO or ENOENT from a race, makes the scan inconclusive, and the original error is returned.

  • The path in the suggested command is shell-quoted, for example chmod u+x '/tmp/it'\''s a $dir/lib dir;x'.

  • Rift never changes the source and never falls back to a partial copy. A failed create leaves no destination and no registry row.

  • If the scan finds nothing, the original error is returned with the root path.

  • copy-on-write cloning unavailable is now used only for ENOTSUP/EOPNOTSUPP/EXDEV. Other errors, such as ENOSPC or EIO, read clone failed for <path>: ….

  • The new error has the RPC code blocked_entry and carries the entry's path.

An earlier version of this PR fell back to cloning per child. Review found that it could leave a half-copied destination, rejected FIFOs and changed some metadata. That fallback was dropped.

Tests are in the PR stacked on top.

@RhysSullivan
RhysSullivan force-pushed the fix/copy-all-unsearchable-dirs branch from bb94532 to be766cb Compare October 7, 2026 17:27
@RhysSullivan RhysSullivan changed the title Copy trees with unsearchable directories in full copies Name the entry that blocks a full copy Oct 7, 2026
@RhysSullivan
RhysSullivan marked this pull request as ready for review October 7, 2026 19:04
* Test the error for blocked full copies

* Test quoting, destination refusals, inconclusive scans and append-only parents
@RhysSullivan
RhysSullivan merged commit f32d648 into upstream-0.0.13 Oct 7, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant