mount

Chris Lu
2026-04-13 18:40:28 -07:00
parent 4bc2d85a52
commit 4214f059f5
3 changed files with 173 additions and 0 deletions
+96
@@ -16,6 +16,102 @@ With "weed mount", the files can be operated as a local file. The following oper
* advisory file locking (`flock(2)` and POSIX `fcntl(2)` byte-range locks)
* extended attributes (xattr)
### Distributed Lock (cross-mount write coordination)
`weed mount` can coordinate writers across different mount instances using
the filer's distributed lock manager (DLM). When enabled, opening a file
for writing acquires a cluster-wide lock on the file's filer path, so only
one mount can write a given file at a time. Other mounts that open the same
file for writing block until the holder releases it.
#### Enabling
Pass `-dlm` when starting `weed mount`:
```bash
weed mount -filer=localhost:8888 -dir=/mnt/seaweedfs -dlm
```
DLM is off by default. It is automatically disabled if `-writebackCache` is
also set, since writeback implies single-writer semantics and the extra
coordination would only add latency. When DLM is disabled, writers across
mounts are unordered — last writer wins on flush.
#### Flow
```mermaid
sequenceDiagram
participant A as App on Mount A
participant MA as weed mount A<br/>(owner mount-1)
participant F as Filer DLM
participant MB as weed mount B<br/>(owner mount-2)
participant B as App on Mount B
A->>MA: open("/data/file", O_WRONLY)
MA->>F: Lock("/data/file", owner=mount-1, ttl=7s)
F-->>MA: granted
Note over MA,F: Heartbeat renews lock every ~7s
MA-->>A: fd
B->>MB: open("/data/file", O_WRONLY)
MB->>F: Lock("/data/file", owner=mount-2, ttl=7s)
F-->>MB: blocked (held by mount-1)
A->>MA: write / close
MA->>F: flush to filer, then Unlock
F-->>MB: granted (mount-1 released)
MB-->>B: fd
B->>MB: write / close
MB->>F: flush to filer, then Unlock
```
If mount A crashes without closing, the filer drops the lock after the
7-second TTL and mount B's pending acquire unblocks automatically.
#### Semantics
* **Scope.** The lock key is the file's filer path (not the local inode,
which is per-mount). Two mounts opening the same path for writing contend
on the same key.
* **Acquisition.** The lock is taken when a handle is opened with any write
flag (`O_WRONLY`, `O_RDWR`, `O_APPEND`, `O_CREAT`, `O_TRUNC`). Read-only
opens are not locked. Acquisition is blocking: a second mount's
`open(2)`-for-write blocks until the first mount closes the file or the
lock TTL expires.
* **Release.** The lock is held for the full lifetime of the file handle
and released on close. For handles running the writeback async flush
path, the lock is released after the background flush completes — so a
reader on another mount after a successful close always sees the flushed
data.
* **Auto-renewal.** The lock is renewed on a 7-second TTL heartbeat while
the handle is open. If a mount crashes, the lock frees on TTL expiry.
* **Rename and unlink.** `rename(2)` acquires DLM locks on both the source
and destination paths (sorted to avoid A→B / B→A deadlocks) so no other
mount can open either path for writing during the rename. `unlink(2)` of
a file that is currently open on this mount coordinates with the held
handle's lock.
* **Owner identifier.** Each mount is tagged with `mount-<signature>`,
which appears in filer lock logs and in `weed shell`'s lock commands for
debugging.
#### Requirements and constraints
* At least one filer address (`-filer=`) must be configured; DLM is a
filer-hosted service.
* DLM is disabled when `-writebackCache` is set (single-writer mode).
* DLM coordinates writes only. Concurrent readers on different mounts are
never blocked, and they still see flushed data via the filer's metadata.
* DLM does not replace POSIX `fcntl`/`flock` advisory locks; those remain
available and are orthogonal (see the next section).
#### When to use it
Enable `-dlm` when multiple `weed mount` instances may write to the same
files — e.g. a shared build cache mounted on several CI workers, or an
application that runs on multiple nodes and writes to the same path. Leave
it off for single-mount deployments or when each mount writes into its own
subtree, since the extra round-trips add latency on every open-for-write.
### Advisory File Locking
SeaweedFS supports advisory file locking over FUSE:
+76
@@ -0,0 +1,76 @@
# POSIX Compliance for `weed mount`
SeaweedFS runs the [pjdfstest](https://github.com/pjd/pjdfstest) POSIX
compliance suite against `weed mount` on every change to `weed/mount/**`,
`weed/filer/**`, or the test harness itself. The job is defined in
[`.github/workflows/pjdfstest.yml`](https://github.com/seaweedfs/seaweedfs/blob/master/.github/workflows/pjdfstest.yml)
and the harness lives under [`test/pjdfstest/`](https://github.com/seaweedfs/seaweedfs/tree/master/test/pjdfstest).
## How it runs
1. A SeaweedFS e2e image (master + volume + filer + mount) is built and
started via `test/pjdfstest/docker-compose.yml`.
2. `test/pjdfstest/run.sh` mounts the filesystem with `weed mount
-allowOthers=true` and clones pjdfstest pinned to an immutable upstream
commit for reproducibility.
3. `prove -rv` runs every `tests/**/*.t` except the entries listed in
[`known_failures.txt`](https://github.com/seaweedfs/seaweedfs/blob/master/test/pjdfstest/known_failures.txt).
Any failure outside that allow-list fails CI.
## Tests passing
All pjdfstest syscall groups pass on `weed mount`, except for the three
test files called out below. The groups exercised by the suite are:
| Group | Coverage |
|-------|----------|
| `tests/chflags/` | BSD file flags (skipped on Linux by the suite itself) |
| `tests/chmod/` | `chmod(2)` permission, errno, and setuid/setgid behavior |
| `tests/chown/` | `chown(2)` ownership, errno, and clearing of set\*id bits |
| `tests/link/` | `link(2)` creation, permission, and errno cases (except `00.t`) |
| `tests/mkdir/` | `mkdir(2)` creation and errno paths |
| `tests/mkfifo/` | `mkfifo(2)` FIFO creation |
| `tests/mknod/` | `mknod(2)` regular/FIFO node creation |
| `tests/open/` | `open(2)` flags, permissions, `O_CREAT`, `O_TRUNC`, errno |
| `tests/rename/` | `rename(2)` same/cross-directory, errno cases (except `21.t`) |
| `tests/rmdir/` | `rmdir(2)` empty-directory and errno cases |
| `tests/symlink/` | `symlink(2)` creation, traversal, errno cases |
| `tests/truncate/` | `truncate(2)` resize, permission, and errno cases |
| `tests/unlink/` | `unlink(2)` removal and errno cases (except `00.t`) |
| `tests/utimensat/` | `utimensat(2)` atime/mtime/ctime semantics, errno paths |
| `tests/granular/` | Granular timestamp update checks |
## Tests not passing
The following tests are listed in
[`test/pjdfstest/known_failures.txt`](https://github.com/seaweedfs/seaweedfs/blob/master/test/pjdfstest/known_failures.txt)
and are skipped in CI. They are deterministic and tracked as known issues:
| Test | Category | Reason |
|------|----------|--------|
| `tests/rename/21.t` | rename | Cross-directory rename of a subdirectory with restricted permissions triggers cascading failures in the rest of the test file. |
| `tests/link/00.t` | link | `nlink` assertion mismatch (e.g. expected `nlink=2`, got `nlink=3`) after hard link creation. Filer-side hard-link counter issue. |
| `tests/unlink/00.t` | unlink | Same filer-side hard-link counter issue surfaced on the removal path. |
The two `nlink` failures are filer-side hard-link counter bugs rather than
FUSE mount bugs, and are deterministic under the current meta-cache load
ordering. The rename failure is a permission edge case on cross-directory
rename. Contributions that fix any of these are welcome — once a test is
green, remove it from `known_failures.txt` so CI enforces it going forward.
## Running locally
```sh
# Full suite against a local weed binary (requires sudo, fusermount3,
# autoconf, make, perl TAP::Harness::Archive).
test/pjdfstest/run.sh
# Subset, e.g. only chmod tests
PJDFSTEST_TESTS=tests/chmod test/pjdfstest/run.sh
# Containerized (matches CI exactly)
docker compose -f test/pjdfstest/docker-compose.yml up --wait
docker compose -f test/pjdfstest/docker-compose.yml exec mount /run.sh
```
See also: [FUSE Mount](FUSE-Mount).
+1
@@ -58,6 +58,7 @@
### [[FUSE Mount]]
* [[FIO benchmark]]
* [[fstab and systemd mount]]
* [[POSIX Compliance]]
### [[WebDAV]]