← Back to issue list

Handle ELOOP while copying symlink metadata on virtiofs

View original Github issue

Metadata

Project
craft-parts
Number
#1703
Type
issue
State
open
Author
gcomneno
Labels
Type: Bug
Created
Updated
Closed

Current evaluation

Bug report to handle ELOOP errors when copying symlink metadata on virtiofs. Fresh issue with root cause analysis and proposed fix; no maintainer response yet.

Suggested action: needs triage

Reason: The issue is fresh (5 days old) with a clear bug report, root cause analysis, and proposed solution, but has no maintainer response or assignee. It has a 'Type: Bug' label but no maintainer acknowledgment. The issue references canonical/charmcraft#2661 and #2864 which confirm the problem, but craft-parts maintainers have not yet weighed in on the proposed fix approach.

Impact: 60 Quick Win: 33.0 Staleness: 5 Complexity: 45 Confidence: 85 Support Request: 10

Issue body

## Summary Copying a symlink with `craft_parts.utils.file_utils.copy()` can fail with: OSError: [Errno 40] Too many levels of symbolic links on virtiofs-backed filesystems. This has been observed through Charmcraft when a project contains symlinks inside directories such as `.venv` or `.tox`: - canonical/charmcraft#2661 - canonical/charmcraft#2864 The Charmcraft-side proposal avoids pulling those directories, but the underlying failure appears to be in the generic craft-parts file-copy path. ## Root cause For a symlink copied with `follow_symlinks=False`, `file_utils.copy()` eventually calls: shutil.copy2(...) -> shutil.copyfile(...) -> shutil.copystat(...) -> shutil._copyxattr(...) -> os.listxattr(..., follow_symlinks=False) -> llistxattr() On the affected virtiofs setup, `llistxattr()` returns `ELOOP` for the symlink. Python's `shutil._copyxattr()` suppresses several unsupported-xattr errors, including `ENOTSUP`, `ENODATA`, and `EINVAL`, but not `ELOOP`, so the exception propagates even though the symlink itself can be copied successfully. ## Scope This is not specific to `.venv` or `.tox`. Any symlink copied through this path on a filesystem exhibiting the same `llistxattr()` behavior may trigger the failure. ## Possible narrow handling A possible approach would be to distinguish the symlink-copy operation from the metadata-copy operation when: - `follow_symlinks=False`; and - the source is a symlink. This would allow an `ELOOP` raised specifically while copying symlink metadata to be treated as an unsupported metadata operation, without suppressing an `ELOOP` raised while actually copying the entry. A local proof-of-concept verified these boundaries: - symlink + `copystat()` raising `ELOOP`: symlink remains correctly copied; - symlink + `copyfile()` raising `ELOOP`: `ELOOP` still propagates; - regular file + `copy2()` raising `ELOOP`: `ELOOP` still propagates. ## Test coverage A regression test could simulate the filesystem behavior without requiring virtiofs by mocking the relevant `shutil` operation. Suggested cases: 1. tolerate `ELOOP` from metadata copying for a symlink copied without following it; 2. propagate `ELOOP` from the actual symlink copy; 3. continue propagating `ELOOP` for regular files. This would keep the exception handling limited to the known metadata boundary rather than suppressing `ELOOP` generically.

Evaluation history

Date Model Scores Action Summary
qwen3.6-35b-a3b-mtp-q6
Impact: 60
Quick Win: 33.0
Staleness: 5
Complexity: 45
Confidence: 85
Support Request: 10
needs triage Bug report to handle ELOOP errors when copying symlink metadata on virtiofs. Fresh issue with root cause analysis and proposed fix; no maintainer response yet.

Update history

Date Change
updated
created

Related work

  • Related To: canonical/charmcraft#2661 (confidence 95%)

    Same ELOOP issue reported from Charmcraft perspective; open issue confirming the problem on virtiofs.

  • Related To: canonical/charmcraft#2864 (confidence 95%)

    Open PR with Charmcraft-side workaround (excluding .venv/.tox); explicitly references craft-parts#1703 as the underlying issue.

Related issues

No related issues found above the similarity threshold.