Bug 895905
| Summary: | guestmount: link() incorrectly returns ENOENT, when it should be EXDEV | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | [Community] Virtualization Tools | Reporter: | Richard W.M. Jones <rjones> | ||||||
| Component: | libguestfs | Assignee: | Richard W.M. Jones <rjones> | ||||||
| Status: | CLOSED UPSTREAM | QA Contact: | |||||||
| Severity: | unspecified | Docs Contact: | |||||||
| Priority: | unspecified | ||||||||
| Version: | unspecified | CC: | bfan, dyasny, leiwang, mbooth, moli, qguan, walters, wshi | ||||||
| Target Milestone: | --- | ||||||||
| Target Release: | --- | ||||||||
| Hardware: | Unspecified | ||||||||
| OS: | Unspecified | ||||||||
| Whiteboard: | |||||||||
| Fixed In Version: | Doc Type: | Bug Fix | |||||||
| Doc Text: | Story Points: | --- | |||||||
| Clone Of: | 892291 | Environment: | |||||||
| Last Closed: | 2013-01-21 14:46:13 UTC | Type: | Bug | ||||||
| Regression: | --- | Mount Type: | --- | ||||||
| Documentation: | --- | CRM: | |||||||
| Verified Versions: | Category: | --- | |||||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||||
| Embargoed: | |||||||||
| Bug Depends On: | |||||||||
| Bug Blocks: | 892291 | ||||||||
| Attachments: |
|
||||||||
|
Description
Richard W.M. Jones
2013-01-16 09:06:17 UTC
Cloning this bug to check whether it happens upstream too. Created attachment 684279 [details]
test script
Simple self-contained test script demonstrating the problem.
The output is:
[...]
+ mkdir -p /tmp/mnt
+ guestmount -a test1.img -m /dev/sda1:/ -m /dev/sda2:/boot /tmp/mnt
+ touch /tmp/mnt/foo
+ cd /tmp/mnt
+ ln foo boot/foo
ln: failed to create hard link ‘boot/foo’ => ‘foo’: No such file or directory
(The error message should be "Invalid cross-device link")
Created attachment 684284 [details]
API-level link test
This is a test script to see what the guestfs_ln API
returns.
Note that the current implementation of guestfs_ln runs
the external 'ln' binary. This has two obvious problems:
(a) it's slow
(b) it doesn't capture errno
There's no obvious reason why we could not replace this
impl with a direct call to link(2).
Two commits are needed to fix this fully: https://github.com/libguestfs/libguestfs/commit/533082e28240522df51e6615d99794d726c8e1f0 https://github.com/libguestfs/libguestfs/commit/28e34290ff0dc11e9c5d8b8a1e5992cd0cc941fb The first commit changes guestfs_ln to use link(2) directly instead of the external 'ln' program, ensuring that we can capture the errno. That commit on its own does fix the whole bug (including guestmount), but ... When I looked closely at the code to guestmount to try to work out why ENOENT was being returned (ENOENT appears nowhere along any relevant codepaths), I realized there is a second bug in guestmount which affects lots of things. The current guestmount code returns errnos to FUSE by just doing: return -guestfs_last_errno(g); That works, in the cases where the previous guestfs_* API call captured the errno. In other cases, guestfs_last_errno returns 0, and thus 0 (no error) is passed back to FUSE. Ooops. What was in fact happening in the ln-over-guestmount case was that the link call was *succeeding*, but a subsequent open was failing with ENOENT. The second commit fixes this. |