Table of Contents

About

When setting up resources for a lab it might be useful to have a data pool from which storage can be shared to connecting machines. Given an environment where the network filesystem is based on Samba, it would be beneficial if machines could just map a share, a share that would then be interpreted on the server as a subset of some storage pool and the access would be granted automatically without even having to supply a password. The following guide should point out some configuration options and a setup based on Samba, leveraging a ZFS pool with quotas as well as the relevant configuration that would allow transparently mapping a share on a shared filesystem server with zero knowledge required from the mapping client.

Diagram

Assumptions

Creating ZFS Tank and Filesystems

Since every connecting machine to the network will conditionally benefit from a slice of the overall storage pool, a ZFS tank has to be created and then partitioned into sub-filesystems.

First a tank has to be created with "some options" and by using various "storage" components such as hard-drives.

zpool create [ some options ] tank [ storage ]

where:

Once the tank is created, ZFS filesystems can be created on top of that tank. For instance, assume that a filesystem with a given quota is to be created for a connecting client that will have the fully-qualified domain name media.lan.

First the filesystem is created:

zpool create tank/media.lan

where:

Next, quotas can be enforced on the ZFS filesystem if so desired. For example, the next command:

zfs set quota=1TB tank/media.lan

will set a 1TB quota for the tank/media.lan filesystem.

Next, a mount point can be set for the entire ZFS tank:

zfs set mountpoint=/mnt/share tank

where /mnt/share is the mount point where all filesystems can be accessed.

For all machines that will benefit from the shared storage, the filesystems have to be set up using ZFS. Conversely, any machine that will not have a ZFS filesystem created will be denied access to the pool. Effectively, creating the setup this way delegates access to ZFS which is the last component in the setup and makes Samba oblivious to the underlying filesystem properties. One advantage therefore is that ZFS features can be leveraged without even having to modify the Samba configuration that acts as a passthrough.

Setting up Samba

There will be a single Samba share configured that will expand into a subdirectory named after the FQDN of the connecting clients. The configuration for the share would match the following:

[share]
    comment = Scratch
    path = /mnt/share/%M
    force user = system
    force group = system
    read only = No
    create mask = 0664
    force create mode = 0664
    force directory mode = 0755
    inherit acls = Yes
    guest ok = Yes

where:

Since %M has been used, Samba will have to look up the DNS name of the connecting clients. This can has to be enabled in the global Samba configuration:

[global]
   ...
   hostname lookups = yes
   ...

Now since clients such as media.lan will be accessing the Samba share, it is important to grant the necessary permission to the system user to the ZFS filesystem. First, make sure that POSIX ACLs are enabled on the tank, and then grant permission to the system user to read and write to the share on the server.

setfacl -R -d -m u:system:rwx,g:system:rwx /mnt/share/
setfacl -R -m u:system:rwx,g:system:rwx /mnt/share/

this will ensure that when a Samba client such as media.lan accesses the share and reads or writes files, Samba will use the force user = system and force group = system settings in order to map any read and writes to the system user such that ZFS will grant the permission to write to /mnt/share/ and all its subdirectories.

Mounting the Share on the Client

To mount the Samba share using a Unix client, issue:

mount -t cifs -o rw,guest //server.lan/share /mnt/share

where:

Windows clients act identically by either browsing the server shares or by mapping the share //server.lan/share as a drive.

Note that the share is //server.lan/share and not //server.lan/share/media.lan where media.lan is the DNS client name and this is because Samba will expand //server.lan/share using the DNS client name automatically and make it such that the Samba client will have access only to their own directory under /mnt/share.

Conversely, on the server, the folder /mnt/share contains the ZFS tank mount point and will contain directories for each DNS client that has attempted to mount the share Samba share and has had a ZFS filesystem defined.

Scaling

The setup scales beautifully because Samba just acts as a passthrough and only presents the share Samba share to clients that are oblivious to where their files are being written. That being said, to make some space available to a client on the network, simply create a ZFS filesystem matching the DNS of the client.

For instance, to grant the machine hostname1.lan access to some space, just issue:

zfs create tank/hostname1.lan

and that would automatically create the folder /mnt/share/hostname1.lan on the server such that Samba will allow mapping to the directory in case the hostname1.lan client connects.

Conversely, to remove the space for some machine hostname1.lan, issue:

zfs destroy tank/hostname1.lan

and then Samba will just refuse to map the share Samba share on the client because the /mnt/share/hostname1.lan folder would not exist on the server.

Similarly, quotas can be changed for the ZFS filesystems or other options leveraged such as ZFS snapshots to make backups that will all work transparently to Samba.