Bug 15805 - samba not triggering systemd-automounts
Summary: samba not triggering systemd-automounts
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: File services (show other bugs)
Version: unspecified
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Samba QA Contact
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-02-12 11:36 UTC by Samuel Cabrero
Modified: 2025-02-18 11:18 UTC (History)
0 users

See Also:


Attachments
Test program (3.23 KB, text/x-csrc)
2025-02-13 15:45 UTC, Samuel Cabrero
no flags Details
Patch for master (14.57 KB, patch)
2025-02-18 11:18 UTC, Samuel Cabrero
scabrero: review?
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Samuel Cabrero 2025-02-12 11:36:37 UTC
It turns out that systemd-automount behaves differently from autofs daemon and it does not return ENOENT when calling openat(pathref_dir_fd, "automount directory not yet mounted", ..), it returns a real fd without triggering the mount so the workaround implemented in ac7a16f9cc4bd97ef546d1b7b02605991000d0f9 does not work.

To make it work we would need to check fstatfs() .f_type on each directory open if the fd is a pathref, but this approach seems sub-optimal (test patch https://gitlab.com/samba-team/devel/samba/-/commit/32f2f3c020060e48a53aa7d2ea7051e267e504d4).

A possible mitigation could be to add a new per-share option to perform fstatfs() .f_type check only if enabled.

Or discuss with systemd developers the possibility to return ENOENT as autofs does...

Other ideas?
Comment 1 Samuel Cabrero 2025-02-13 12:47:05 UTC
After further analysis this is not a systemd vs autofs behavior but direct automounts problem, either with autofs or systemd.

Autofs indirect:

# grep -v '^#' /etc/auto.master
+auto.master
/indirect/data  /etc/auto.indirect

# grep -v '^#' /etc/auto.indirect
d1  localhost:/export/data/d1
d2  localhost:/export/data/d2

With browse_mode = no:

# ls /indirect/
data

# ls /indirect/data
(empty)

# ./test /indirect
Target is /indirect
chddir(/indirect) -> 0
openat(AT_FDCWD, data, O_RDONLY | O_NOFOLLOW | O_PATH) -> 3
openat(3, d1, O_RDONLY | O_NOFOLLOW | O_PATH) -> 4                <- [1]
openat(AT_FDCWD, /proc/self/fd/4, O_RDONLY | O_DIRECTORY) -> 5

[1] This call triggers the mount as 'd1' does not exist

With browse_mode = yes:

# ls /indirect
data

# ls /indirect/data
d1  d2

# ./test /indirect
Target is /indirect
chddir(/indirect) -> 0
openat(AT_FDCWD, data, O_RDONLY | O_NOFOLLOW | O_PATH) -> 3
openat(3, d1, O_RDONLY | O_NOFOLLOW | O_PATH) -> 4
openat(AT_FDCWD, /proc/self/fd/4, O_RDONLY | O_DIRECTORY) -> -1
Press key to continue (pid=19202)...

While pid 19202 waits...

# ls -l /proc/19202/fd/4/
ls: cannot open directory '/proc/19202/fd/4/': No such file or directory <- [2]
# ls -l /proc/19202/fd/4
l--------- 1 root root 64 feb 13 12:29 /proc/19202/fd/4 -> /indirect/data/d1

[2] Why????

Now, autofs direct automounts:

# grep -v "^#" /etc/auto.master
+auto.master
/-              /etc/auto.direct
# grep -v "^#" /etc/auto.direct
/direct/data/d1  localhost:/export/data/d1
/direct/data/d2  localhost:/export/data/d2

# ls /direct/
data
# ls /direct/data/
d1  d2

# ./test /direct
Target is /direct
chddir(/direct) -> 0
openat(AT_FDCWD, data, O_RDONLY | O_NOFOLLOW | O_PATH) -> 3
openat(3, d1, O_RDONLY | O_NOFOLLOW | O_PATH) -> 4
openat(AT_FDCWD, /proc/self/fd/4, O_RDONLY | O_DIRECTORY) -> 5  <- [3]
Press key to continue (pid=19272)...

[3] Gets a fd referring to the mountpoint without triggering the mount.

While pid 19272 waits...

# ls -l /proc/19272/fd/4
l--------- 1 root root 64 feb 13 12:34 /proc/19272/fd/4 -> /direct/data/d1
# ls -l /proc/19272/fd/4/
total 0

# ls -l /proc/19272/fd/5
lr-x------ 1 root root 64 feb 13 12:35 /proc/19272/fd/5 -> /direct/data/d1
# ls -l /proc/19272/fd/5/
total 0
Comment 2 Samuel Cabrero 2025-02-13 15:45:02 UTC
Created attachment 18556 [details]
Test program

One possibility would switching from openat to openat2 and pass RESOLVE_NO_XDEV in the how structore. Then we will get EXDEV when crossing any mountpoint, then calling fstatfs() and fallback to name based for automounts or retying without RESOLVE_NO_XDEV for other types. 

# ./test2 /direct
Target is /direct
chddir(/direct) -> 0
openat(AT_FDCWD, data, O_RDONLY | O_NOFOLLOW | O_PATH) -> 3
openat(3, d1, O_RDONLY | O_NOFOLLOW | O_PATH) -> 4
openat2(AT_FDCWD, /proc/self/fd/4, ... how.resolve.RESOLVE_NO_XDEV) -> -1 Invalid cross-device link
sbuf.f_type=0x187
It is autofs, fallback to name-based
openat(3, d1, O_RDONLY | O_NOFOLLOW) -> 5
getdents(5) -> 1048576
.
..
f1
Comment 3 Samuel Cabrero 2025-02-18 11:18:02 UTC
Created attachment 18573 [details]
Patch for master

A possible fix.

Pipeline: https://gitlab.com/samba-team/devel/samba/-/pipelines/1676040908