RHEL Intermediate #3: Advanced Storage — Stratis, NFS, Samba
In #2 we organized single-machine disk operations with LVM. This post covers Stratis on top of it, NFS, the standard for sharing between Linux machines, and Samba, which is compatible with Windows. We also cover how multiple machines can share the same data.
The position of this post in the RHEL Intermediate series:
- #1 Intro to SELinux — Enforcing/Permissive, labels, troubleshooting
- #2 LVM — PV/VG/LV, snapshots, expansion
- #3 Advanced storage — Stratis, NFS, Samba ← this post
- #4 Networking — NetworkManager (nmcli), bonding, teaming
- #5 Log management — journald, rsyslog, log rotation
- #6 Job scheduling — cron, systemd timer, at
- #7 Intro to containers — Podman/Buildah/Skopeo (differences from Docker)
Stratis — LVM’s next role #
As pointed out in Basics #6, starting with RHEL 8, Stratis entered as a new option for storage management. Stratis is not a new filesystem but a manager layered on top of LVM and XFS. Instead of handling the two tools directly, it bundles them into one command group (stratis) so you use thin provisioning and snapshots routinely.
user command: stratis pool create / fs create / snapshot
│
▼
┌───────────────┐
│ stratisd │ ← daemon
└───────┬───────┘
│
┌─────────┴─────────┐
│ │
▼ ▼
[device-mapper] [thin pool / XFS]
│ │
▼ ▼
physical disk filesystemThe goal of Stratis is to let operators handle thin provisioning and snapshots routinely. Working with LVM directly requires keeping track of the three layers PV/VG/LV, but Stratis only needs two concepts: pool and filesystem.
Install and activate #
$ sudo dnf install -y stratisd stratis-cli
$ sudo systemctl enable --now stratisd
$ sudo stratis daemon version
3.x.xstratisd is the background daemon, stratis is the CLI we type.
Creating a pool #
$ sudo stratis pool create data_pool /dev/vdb /dev/vdc
$ sudo stratis pool list
Name Total / Used / Free Properties
data_pool 30 GiB / 564 MiB / 29.4 GiB Cr,~Ca
$ sudo stratis blockdev list data_pool
Pool Name Device Node Physical Size Tier
data_pool /dev/vdb 20 GiB Data
data_pool /dev/vdc 10 GiB DataThis is the role corresponding to PV/VG of LVM. One pool can contain multiple disks, and you can add more later (stratis pool add-data).
Creating a filesystem #
$ sudo stratis filesystem create data_pool myfs
$ sudo stratis filesystem list
Pool Filesystem Total / Used / Free Created Device
data_pool myfs 1 TiB / 546 MiB / 1023 GiB Apr 18 ... /dev/stratis/data_pool/myfsNotice something interesting — the fs size shows as 1 TiB. The actual pool is only 30 GiB. This is thin provisioning at work. Stratis allocates a large virtual size when creating an fs and draws from the pool only as data is actually written. It can grow until the pool itself fills up.
Mounting #
$ sudo mkdir -p /myfs
$ sudo mount /dev/stratis/data_pool/myfs /myfs
# In the actual /etc/fstab, use the pool UUID helper.
$ sudo stratis pool list
Name Total / Used / Free Properties
data_pool 30 GiB / 564 MiB / 29.4 GiB Cr,~Ca/dev/stratis/data_pool/myfs /myfs xfs defaults,x-systemd.requires=stratis-fstab-setup@<pool-uuid>.service,x-systemd.after=stratis-fstab-setup@<pool-uuid>.service 0 0Stratis requires a systemd helper keyed to the pool UUID for boot-time mounting. You must include both x-systemd.requires=stratis-fstab-setup@<pool-uuid>.service and x-systemd.after=stratis-fstab-setup@<pool-uuid>.service; only with that configuration does the mount come up reliably at boot.
Snapshots #
$ sudo stratis filesystem snapshot data_pool myfs myfs_snap
$ sudo stratis filesystem list
Pool Filesystem ... Device
data_pool myfs ... /dev/stratis/data_pool/myfs
data_pool myfs_snap ... /dev/stratis/data_pool/myfs_snapThe snapshot is created as a new fs and immediately mountable. Much more intuitive than LVM’s lvcreate -s.
Pool expansion #
$ sudo stratis pool add-data data_pool /dev/vdd
$ sudo stratis pool list
Name Total / Used / Free ...
data_pool 40 GiB / 1.2 GiB / 38.8 GiBEquivalent to LVM’s vgextend. Since the fs is already thin, it automatically utilizes the expanded pool. No need to run xfs_growfs separately.
Stratis vs LVM — which one? #
| Role | LVM directly | Stratis |
|---|---|---|
| Single fs / stability priority | ✅ operational standard | possible but new tool |
| Routine thin provisioning | possible but complex | ✅ default |
| Frequent snapshot-taking | possible but many steps | ✅ one line |
| Complex RAID configuration | ✅ raid5/6 etc. | not supported |
| RHEL 9 default | ✅ | separate install |
| Automation / Ansible integration | ✅ mature | adoption ongoing |
The default choice for operations is still LVM. Stratis has greater value in roles where thin / snapshots are routine (container hosts, virtual machine disk pools, storage workstations).
As of 2026 — Stratis 3.x has entered a stable stage and is supported on both RHEL 9 / 10. However, the majority of operations still stay on LVM directly. If designing a new system, choose based on workload patterns.
NFS — the standard file sharing between Linux machines #
The most frequently used tool when you want multiple servers to see the same directory. One machine exports a directory, and another machine mounts it and uses it like its own filesystem.
┌────────────────┐ ┌────────────────┐
│ NFS server │ │ NFS client │
│ (exports) │ │ (mount) │
├────────────────┤ ├────────────────┤
│ /var/nfs/share │ ─── network ─→ │ /mnt/share │
└────────────────┘ └────────────────┘Server setup #
$ sudo dnf install -y nfs-utils
$ sudo systemctl enable --now nfs-server
$ systemctl status nfs-serverCreate the directory to share and loosen permissions.
$ sudo mkdir -p /var/nfs/share
$ sudo chown nobody:nobody /var/nfs/share
$ sudo chmod 775 /var/nfs/shareWrite the share definition in /etc/exports.
# directory client(options)
/var/nfs/share 192.168.64.0/24(rw,sync,no_subtree_check)
/var/nfs/ro *(ro,sync,no_subtree_check)Frequently used options:
| Option | Meaning |
|---|---|
rw / ro | read-write / read-only |
sync | synchronous write (safe, default) — compare: async is fast but risky |
no_root_squash | maps client root to server root (security risk, rarely used) |
root_squash | maps client root to nobody (default) |
no_subtree_check | skips directory tree verification — recommended |
Apply after change:
$ sudo exportfs -rav
exporting 192.168.64.0/24:/var/nfs/share
exporting *:/var/nfs/ro
$ sudo exportfs -v # current export listFirewall / SELinux #
$ sudo firewall-cmd --permanent --add-service=nfs
$ sudo firewall-cmd --permanent --add-service=mountd
$ sudo firewall-cmd --permanent --add-service=rpc-bind
$ sudo firewall-cmd --reload$ sudo setsebool -P nfs_export_all_rw onNFS configuration centers on directory permissions and /etc/exports, though SELinux may need additional tuning depending on share patterns. Exporting specific directories with the basic configuration generally works without extra steps.
Mounting from the client #
$ sudo dnf install -y nfs-utils
$ sudo mkdir -p /mnt/share
$ sudo mount -t nfs 192.168.64.10:/var/nfs/share /mnt/share
$ df -hT /mnt/share
Filesystem Type Size Used Avail Use% Mounted on
192.168.64.10:/var/nfs/share nfs4 20G 175M 20G 1% /mnt/share-t nfs can be omitted with auto-detection. For permanent mount use /etc/fstab:
192.168.64.10:/var/nfs/share /mnt/share nfs defaults,_netdev,nofail 0 0The _netdev option is key. It tells systemd to wait until the network is up before attempting mount. Without it, the system tries to mount before the network during boot and fails.
autofs — mount only when needed #
Always mounting multiple NFS shares is a burden. autofs mounts a share automatically the moment someone accesses its path, then unmounts it automatically after it has been idle for a set period.
$ sudo dnf install -y autofs
# /etc/auto.master.d/share.autofs
/mnt/auto /etc/auto.share
# /etc/auto.share
share -fstype=nfs,rw 192.168.64.10:/var/nfs/share
$ sudo systemctl enable --now autofsWith this, the moment you access /mnt/auto/share an NFS mount happens automatically. Frequently used in desktop / multi-server environments.
NFS versions #
| Version | Characteristics |
|---|---|
| NFSv3 | UDP-capable, stateless, compatible with old systems |
| NFSv4 | TCP only, stateful, security / performance improvements (RHEL 9 default) |
| NFSv4.2 | latest, server-side copy (copy_file_range), sparse file support |
The default is v4, but accepts v3 clients for compatibility. To force explicitly: mount -o vers=4.2 ....
Samba — file sharing compatible with Windows #
NFS works well between Linux machines, but Windows clients cannot use it reliably. The Windows file-sharing standard is SMB / CIFS, and Samba is its Linux implementation.
$ sudo dnf install -y samba samba-client
$ sudo systemctl enable --now smb nmbShare definition — /etc/samba/smb.conf
#
[global]
workgroup = WORKGROUP
server string = RHEL 9 Samba
security = user
map to guest = bad user
netbios name = RHEL9LAB
[share]
comment = Shared folder
path = /var/samba/share
browseable = yes
read only = no
guest ok = no
valid users = curtis, aliceFrequently used options:
| Option | Meaning |
|---|---|
path | directory to share |
read only | writable if no |
guest ok | allows unauthenticated access if yes |
valid users | list of users allowed access |
browseable | whether visible in network exploration |
Creating Samba users #
Linux user accounts and Samba accounts are separate. You must set a Samba password for each Linux user individually.
$ sudo useradd -s /sbin/nologin curtis # skip if already exists
$ sudo smbpasswd -a curtis
New SMB password: ...
Retype new SMB password: ...
$ sudo pdbedit -L # list of registered Samba users
curtis:1000:Curtis KimDirectory / SELinux / firewall #
$ sudo mkdir -p /var/samba/share
$ sudo chown -R curtis:curtis /var/samba/share
$ sudo chmod 770 /var/samba/share$ sudo semanage fcontext -a -t samba_share_t "/var/samba/share(/.*)?"
$ sudo restorecon -Rv /var/samba/share
$ sudo setsebool -P samba_export_all_rw on$ sudo firewall-cmd --permanent --add-service=samba
$ sudo firewall-cmd --reloadConnecting from clients #
On Windows: enter \\<server-ip>\share in the Explorer address bar → enter username / password.
On Linux client: mount with cifs-utils.
$ sudo dnf install -y cifs-utils
$ sudo mkdir -p /mnt/smbshare
$ sudo mount -t cifs //192.168.64.10/share /mnt/smbshare \
-o username=curtis,uid=$(id -u),gid=$(id -g)Permanent registration in /etc/fstab:
//192.168.64.10/share /mnt/smbshare cifs credentials=/root/.smbcreds,_netdev,nofail 0 0Store credentials separately in /root/.smbcreds (username=curtis / password=...), mode 600.
Validate configuration with testparm #
$ sudo testparm
Load smb config files from /etc/samba/smb.conf
Loaded services file OK.
Server role: ROLE_STANDALONE
...
[global]
...
[share]
...It immediately catches syntax errors or conflicts. After config changes, always run testparm once before applying.
NFS vs Samba — which one? #
| Role | NFS | Samba |
|---|---|---|
| Linux to Linux | ✅ standard | possible |
| Windows clients | limited | ✅ standard |
| Configuration simplicity | ✅ | requires separate user management |
| Active Directory integration | limited | ✅ powerful |
| Performance (large files) | ✅ | slightly slower |
| Permissions / ACL compatibility | UNIX-based | Windows ACL friendly |
The operational rule is straightforward. Use NFS between Linux machines, and Samba when Windows clients are in the mix. Running both on the same server to serve both sides is also common.
AlmaLinux / Rocky differences #
All commands in this post work as is. Stratis is available via stratisd and stratis-cli packages, and NFS and Samba via RHEL default packages.
Frequently encountered traps #
“Permission denied on NFS client” #
The server directory’s permissions are too restrictive, or the exports options are the culprit (ro / root_squash). On the server, check both ls -ld <dir> and cat /etc/exports together.
“stratisd is not running and boot is stuck” #
The pool UUID helper option was not added to /etc/fstab. Without it, systemd tries to mount the filesystem before Stratis is ready.
“Password is wrong when connecting to Samba” #
Make sure you set a Samba password separately with smbpasswd -a. The Samba password is independent of the Linux login password.
“Firewall is open but NFS mount is denied” #
You also need to open mountd / rpc-bind together. firewall-cmd --add-service=nfs alone is insufficient.
“Trying to access Samba share from Windows with empty username, denied” #
Both map to guest = bad user in smb.conf and guest ok = yes in the share definition are needed for guest access to be allowed.
Frequently used commands at a glance #
| Tool | Command |
|---|---|
| Stratis | stratis pool create / list / add-data |
| Stratis | stratis filesystem create / snapshot / list |
| NFS server | systemctl enable --now nfs-server |
| NFS server | exportfs -rav (apply exports) |
| NFS server | exportfs -v (current export list) |
| NFS client | mount -t nfs <server>:<path> <mount> |
| NFS client | showmount -e <server> (server’s export list) |
| Samba | systemctl enable --now smb nmb |
| Samba | testparm (config validation) |
| Samba | smbpasswd -a <user> (add Samba user) |
| Samba | pdbedit -L (Samba user list) |
| CIFS client | mount -t cifs //<server>/<share> <mount> |
Wrapping up #
The flows covered in this post:
- Stratis is a manager layered on LVM + XFS. With the two concepts of pool / filesystem, you can handle thin provisioning and snapshots simply. Particularly useful in new workstations or container hosts.
- NFS is the standard between Linux. Server
/etc/exports+exportfs -rav, clientmount -t nfs. Don’t forget the_netdevoption. - autofs mounts only when needed, reducing the burden of multiple shares.
- Samba is Windows-compatible. A Samba user (
smbpasswd -a) separate from the Linux user is needed, and always validate withtestparm. - Operational guide — NFS between Linux, Samba when Windows is mixed in.
Next — networking #
With storage organized, it’s time to look at the network layer on top of it. The networking standard for RHEL 9 is NetworkManager.
In #4 Networking — NetworkManager (nmcli), bonding, teaming we’ll organize NetworkManager’s operating model, the flow of setting static IP / DNS / gateway with nmcli, bonding that bundles two NICs to prepare for failures, and bridge the foundation of virtual machine and container networks.