Kernel Mount (seaweed-vfs) — Deploy, Build & Upgrade

Operational reference for Kernel Mount: how to install, configure, run, build from source, and upgrade seaweed-vfs on a single host or a fleet. For the quickstart see Kernel Mount; for how it works under the hood see Kernel Mount internals.

Components

A working mount has two halves, shipped as separate packages:

  • seaweedvfs kernel module (GPL-2.0) — owns the VFS (inodes, dentries, page cache) and does zero networking. It builds for your exact running kernel. Source: seaweedfs/seaweedvfs-kmod.
  • sw-kd daemon — the userspace process that does all SeaweedFS networking (filer gRPC for metadata, volume HTTP for data) over the /dev/seaweedvfs character device. Ships as a prebuilt binary; architecture-specific but kernel-independent.

The module alone does not give you a mount — you always install both.

Packages

Each release on seaweedfs/artifactory publishes three packages, as both .deb and .rpm. Pick one module package plus the daemon:

Package Contents Use when
seaweedfs-vfs-dkms (noarch) module source + DKMS config; rebuilds per kernel default — hosts with a toolchain and changing kernels
seaweedfs-vfs-kmod-<kver> (per arch) precompiled .ko for one exact kernel pinned-kernel fleets / hardened hosts with no compiler
seaweedfs-vfs (per arch) the sw-kd daemon, mount.seaweedvfs helper, systemd units, modprobe config always

Requirements

  • Linux, kernel 6.1 or newer, x86_64 or arm64 (CI validates 6.1 LTS → 7.0).
  • A reachable filer gRPC address — the filer’s HTTP port + 10000 (default 18888).
  • One of apt, dnf, yum, zypper for the installer and packages.
  • For DKMS or source builds only: make, gcc, and kernel headers (linux-headers-$(uname -r) on Debian/Ubuntu, kernel-devel on RHEL/SUSE).

Install

Detects your package manager, architecture, and kernel; installs the module (via DKMS) and the daemon. The filer is named at mount time, so nothing else is required — passing FILER is optional and just mounts that filer at /mnt/seaweed once installed:

curl -fsSL https://raw.githubusercontent.com/seaweedfs/artifactory/main/seaweed-vfs/install.sh \
  | sudo FILER=filer.example.com:18888 bash

It resolves the newest vfs-* release automatically. Re-run the same command any time to upgrade in place.

Installer environment variables

Variable Default Effect
FILER (unset) Optional. After install, mounts this filer at $MNT. Omit it to mount yourself — the filer is always a mount-time choice.
MNT /mnt/seaweed Mountpoint used when FILER is set.
SEAWEEDFS_VFS_RELEASE newest vfs-* Pin a release tag, e.g. vfs-0.0.9.
SEAWEEDFS_VFS_BASE_URL GitHub releases Mirror or alternate download point.
SEAWEEDFS_VFS_KMOD (unset) 1 installs a precompiled .ko for this exact kernel instead of DKMS (no toolchain).
SEAWEEDFS_VFS_UPGRADE auto 1 forces an in-place upgrade; 0 treats the run as a fresh install.
SEAWEEDFS_VFS_RPM_REL 1 RPM release number, if the packaging ever changes it.

Precompiled module (fleets / hardened hosts)

Pinned-kernel boxes that can’t compile install the precompiled .ko instead — no compiler or kernel headers needed:

curl -fsSL https://raw.githubusercontent.com/seaweedfs/artifactory/main/seaweed-vfs/install.sh \
  | sudo SEAWEEDFS_VFS_KMOD=1 FILER=filer.example.com:18888 bash

A precompiled package must exist for your exact kernel version. On signed-module hosts see Secure Boot.

Manual package install

To fetch the packages yourself from the releases page:

# Debian / Ubuntu — DKMS module + daemon
sudo apt install ./seaweedfs-vfs-dkms_<ver>_all.deb ./seaweedfs-vfs_<ver>_amd64.deb
# ...or a precompiled module instead of DKMS (no compiler/headers on the box):
sudo apt install --no-install-recommends \
  ./seaweedfs-vfs-kmod-$(uname -r)_<ver>_amd64.deb ./seaweedfs-vfs_<ver>_amd64.deb

# RHEL / Fedora  (on SUSE: zypper install)
sudo dnf install ./seaweedfs-vfs-dkms-<ver>-1.noarch.rpm ./seaweedfs-vfs-<ver>-1.x86_64.rpm

Deploy

The filer is selected at mount time — the mount helper starts a per-filer sw-kd daemon on demand, so there is no global default to configure first.

Mount

sudo mkdir -p /mnt/seaweed
sudo mount -t seaweedvfs filer.example.com:18888 /mnt/seaweed

/sbin/mount.seaweedvfs loads the module, starts seaweed-vfs@filer.example.com:18888.service (sw-kd --filer …), waits for it to attach to /dev/seaweedvfs, then mounts. At boot via /etc/fstab:

filer.example.com:18888  /mnt/seaweed  seaweedvfs  _netdev  0 0

Each distinct filer gets its own daemon instance, so multiple filers / fstab entries coexist. Read and write /mnt/seaweed like any local directory; sudo umount /mnt/seaweed to unmount. The daemon is stateless (path-based protocol), so it restarts on failure and re-attaches to live mounts transparently. See Kernel Mount for more on the mount step.

Per-filer tuning (optional)

To pass extra sw-kd flags to a mounted filer, create /etc/seaweedfs-vfs/<filer>.conf, named for the filer (e.g. /etc/seaweedfs-vfs/filer.example.com:18888.conf):

# Extra sw-kd arguments, space-separated:
#   --io-uring          drive the kernel<->daemon channel with an io_uring ring
#   --distributed-locks honour flock/POSIX locks across clients via the filer
#   --chunk-cache-mb N  cap the whole-chunk read cache (MiB; default 256, 0 disables)
EXTRA_ARGS=--chunk-cache-mb 64

# The unit reads this file as a systemd EnvironmentFile, so plain KEY=value lines
# also become the daemon's environment — e.g. cap glibc's retained memory:
MALLOC_ARENA_MAX=2

The templated seaweed-vfs@<filer>.service reads this file if present and appends EXTRA_ARGS to the daemon command. For --distributed-locks, also load the module with distributed_locks=1 (see Module parameters).

To bound the daemon’s memory, lower --chunk-cache-mb (the read cache is the largest part of a streaming mount’s RSS) and/or set MALLOC_ARENA_MAX=2. Because the file is an EnvironmentFile, the MALLOC_ARENA_MAX line takes effect on the next daemon start (systemctl restart seaweed-vfs@<filer>.service); confirm it landed with cat /proc/$(pgrep -x sw-kd)/environ | tr '\0' '\n' | grep MALLOC. See why the daemon’s RSS is cache, not a leak.

Standalone daemon (optional)

If you want a boot-time daemon bound to one filer with no mount of its own — rare, since _netdev already starts the per-filer daemon at mount — use the config-file unit instead:

printf 'FILER=filer.example.com:18888\nEXTRA_ARGS=\n' | sudo tee /etc/seaweedfs-vfs/config
sudo systemctl enable --now seaweed-vfs.service
sudo mount -t seaweedvfs none /mnt/seaweed     # no filer — uses the standalone daemon

Only one daemon can own /dev/seaweedvfs, so don’t pair the standalone seaweed-vfs.service with a per-filer seaweed-vfs@… instance for the same device — pick one path. The one-line installer never enables this; set it up by hand as above.

Module parameters

  • distributed_locks=1 — route advisory (flock/POSIX) locks through the filer’s lock service so they are honoured across mounts and clients (off by default). Set it in /etc/modprobe.d/seaweedvfs.conf and pair it with the daemon’s --distributed-locks (in the filer’s <filer>.conf, or the standalone config’s EXTRA_ARGS).

Build from source

The kernel module is GPL-2.0 and builds out-of-tree against your running kernel’s headers; source is at seaweedfs/seaweedvfs-kmod. (The sw-kd daemon ships as a prebuilt binary in the seaweedfs-vfs package — you don’t build it.)

make                                  # builds seaweedvfs.ko
sudo insmod seaweedvfs.ko             # udev then creates /dev/seaweedvfs
# ...run the daemon (or the systemd unit), then mount as above
sudo rmmod seaweedvfs                 # to unload

This needs make, gcc, and the kernel headers/build tree for your running kernel.

Register with DKMS

To have the module rebuild automatically across kernel upgrades:

sudo cp -r . /usr/src/seaweedfs-vfs-<version>/
sudo dkms add     -m seaweedfs-vfs -v <version>
sudo dkms build   -m seaweedfs-vfs -v <version>
sudo dkms install -m seaweedfs-vfs -v <version>

Upgrade

Re-run the installer — it detects an existing install and reloads only what changed:

curl -fsSL https://raw.githubusercontent.com/seaweedfs/artifactory/main/seaweed-vfs/install.sh | sudo bash

It stages the new packages first, then compares the loaded module’s srcversion to the new one to choose the least disruptive path:

  • Only the daemon changed → restart sw-kd under the live mounts. In-flight requests get -ENOTCONN and the daemon re-attaches — a brief I/O pause, no unmount.
  • The kernel module changed → a full reload is unavoidable (a loaded module can’t be swapped with users on it): unmount → rmmodmodprobe → remount, restarting the daemon around it.

Force the choice with SEAWEEDFS_VFS_UPGRADE=1 (always upgrade) or SEAWEEDFS_VFS_UPGRADE=0 (treat as a fresh install).

Kernel upgrades

  • DKMS rebuilds the module automatically for the new kernel — nothing to do.
  • Precompiled (SEAWEEDFS_VFS_KMOD=1) modules are tied to one exact kernel; install the matching seaweedfs-vfs-kmod-<new-kver> package (or re-run the installer with SEAWEEDFS_VFS_KMOD=1) for the new kernel before you boot into it.

Secure Boot

When Secure Boot is on, the kernel loads only signed modules, so modprobe fails with “Key was rejected by service” until the module’s signing key is enrolled:

  • DKMS signs the module with a per-host MOK key and prompts you to enroll it (mokutil --import …, then reboot). The installer detects Secure Boot and reminds you.
  • Precompiled / bare .ko — sign with the kernel’s sign-file (/lib/modules/$(uname -r)/build/scripts/sign-file) using a key you mokutil --import once across the fleet.

For Kubernetes and immutable hosts (Talos / Flatcar / Fedora CoreOS), see the module’s install notes.