Project

General

Profile

Actions

Bug #14633

closed

lib9p: unlinkat() does not work on 9p share

Added by Andy Fiddaman 6 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
bhyve
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Bite-size
Tags:
Gerrit CR:
External Bug:

Description

A user reported that trying to do a recursive `rm -rf` on a directory tree on a 9p mount in a Linux guest is failing.

A simple reproducer which fails under Fedora 35 and Ubuntu 21.10:

# mkdir -p aaaa/bbbb
# touch aaaa/bbbb/cccc
# rm -rf aaa
rm: cannot remove 'aaaa': File exists

It turns out that rm in these modern Linux distributions is using unlinkat(), and this is failing on the
file:

# strace rm -rf /a/aaaa 2>&1 | grep unlinkat
unlinkat(5, "cccc", 0)                  = -1 EINVAL (Invalid argument)
unlinkat(4, "bbbb", AT_REMOVEDIR)       = -1 EINVAL (Invalid argument)
unlinkat(AT_FDCWD, "/a/aaaa", AT_REMOVEDIR) = -1 EEXIST (File exists)

and the debug output from lib9p

[DEBUG]  l9p_dispatch_request: Treaddir tag=0 fid=5 offset=0 count=8168
...
DEBUG]  l9p_dispatch_request: Twalk tag=0 fid=5 newfid=6 wname="cccc" 
[DEBUG]  open_fid: authinfo 1290a50 now used by 6
...
[DEBUG]  l9p_dispatch_request: Tunlinkat tag=0 dirfd=5 name="cccc" flags=0x0
[DEBUG]  l9p_respond: Rlerror tag=0 errnum=22 (Invalid argument)

Tracing through, the EINVAL from the attempt to remove the file is because the code asserts
that the directory fid is not open, which it often is for the unlinkat() call.

Actions

Also available in: Atom PDF